|
19 | 19 | import static org.mockito.ArgumentMatchers.anyLong; |
20 | 20 | import static org.mockito.Mockito.mock; |
21 | 21 |
|
| 22 | +import java.lang.reflect.Field; |
22 | 23 | import java.util.Collections; |
23 | 24 | import java.util.List; |
| 25 | +import java.util.Map; |
24 | 26 | import java.util.Objects; |
25 | 27 | import java.util.Optional; |
26 | 28 |
|
| 29 | +import org.apache.cloudstack.framework.config.ConfigKey; |
27 | 30 | import org.junit.Assert; |
28 | 31 | import org.junit.Test; |
29 | 32 | import org.junit.runner.RunWith; |
| 33 | +import org.mockito.ArgumentCaptor; |
30 | 34 | import org.mockito.InjectMocks; |
31 | 35 | import org.mockito.Mock; |
32 | 36 | import org.mockito.Mockito; |
|
47 | 51 | import com.cloud.storage.VolumeVO; |
48 | 52 | import com.cloud.storage.dao.VolumeDao; |
49 | 53 | import com.cloud.utils.Pair; |
| 54 | +import com.cloud.utils.exception.CloudRuntimeException; |
50 | 55 | import com.cloud.vm.VMInstanceVO; |
51 | 56 | import com.cloud.vm.dao.VMInstanceDao; |
52 | 57 |
|
@@ -349,4 +354,203 @@ public void testGetVMHypervisorHostFallbackToZoneWideKVMHost() { |
349 | 354 | Mockito.verify(hostDao).findHypervisorHostInCluster(clusterId); |
350 | 355 | Mockito.verify(resourceManager).findOneRandomRunningHostByHypervisor(Hypervisor.HypervisorType.KVM, zoneId); |
351 | 356 | } |
| 357 | + |
| 358 | + private void overrideConfigValue(final ConfigKey configKey, final Object value) { |
| 359 | + try { |
| 360 | + Field f = ConfigKey.class.getDeclaredField("_value"); |
| 361 | + f.setAccessible(true); |
| 362 | + f.set(configKey, value); |
| 363 | + } catch (IllegalAccessException | NoSuchFieldException e) { |
| 364 | + Assert.fail(e.getMessage()); |
| 365 | + } |
| 366 | + } |
| 367 | + |
| 368 | + private VMInstanceVO setupVmForTakeBackup(Long vmId, Long hostId, Long backupOfferingId, |
| 369 | + Long accountId, Long domainId, Long zoneId) { |
| 370 | + VMInstanceVO vm = mock(VMInstanceVO.class); |
| 371 | + Mockito.when(vm.getId()).thenReturn(vmId); |
| 372 | + Mockito.when(vm.getHostId()).thenReturn(hostId); |
| 373 | + Mockito.when(vm.getInstanceName()).thenReturn("test-vm"); |
| 374 | + Mockito.when(vm.getBackupOfferingId()).thenReturn(backupOfferingId); |
| 375 | + Mockito.when(vm.getAccountId()).thenReturn(accountId); |
| 376 | + Mockito.when(vm.getDomainId()).thenReturn(domainId); |
| 377 | + Mockito.when(vm.getDataCenterId()).thenReturn(zoneId); |
| 378 | + Mockito.when(vm.getState()).thenReturn(VMInstanceVO.State.Running); |
| 379 | + return vm; |
| 380 | + } |
| 381 | + |
| 382 | + private void setupHostAndRepo(Long hostId, Long backupOfferingId) { |
| 383 | + BackupRepository backupRepository = mock(BackupRepository.class); |
| 384 | + Mockito.when(backupRepository.getType()).thenReturn("nfs"); |
| 385 | + Mockito.when(backupRepository.getAddress()).thenReturn("address"); |
| 386 | + Mockito.when(backupRepository.getMountOptions()).thenReturn("sync"); |
| 387 | + Mockito.when(backupRepositoryDao.findByBackupOfferingId(backupOfferingId)).thenReturn(backupRepository); |
| 388 | + |
| 389 | + HostVO host = mock(HostVO.class); |
| 390 | + Mockito.when(host.getId()).thenReturn(hostId); |
| 391 | + Mockito.when(host.getStatus()).thenReturn(Status.Up); |
| 392 | + Mockito.when(host.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM); |
| 393 | + Mockito.when(hostDao.findById(hostId)).thenReturn(host); |
| 394 | + } |
| 395 | + |
| 396 | + @Test |
| 397 | + public void testTakeBackupDetailsCompressionEnabled() throws AgentUnavailableException, OperationTimedoutException { |
| 398 | + Long vmId = 1L; Long hostId = 2L; Long backupOfferingId = 3L; |
| 399 | + Long accountId = 4L; Long domainId = 5L; Long zoneId = 6L; |
| 400 | + |
| 401 | + VMInstanceVO vm = setupVmForTakeBackup(vmId, hostId, backupOfferingId, accountId, domainId, zoneId); |
| 402 | + setupHostAndRepo(hostId, backupOfferingId); |
| 403 | + |
| 404 | + VolumeVO volume = mock(VolumeVO.class); |
| 405 | + Mockito.when(volume.getState()).thenReturn(Volume.State.Ready); |
| 406 | + Mockito.when(volume.getSize()).thenReturn(100L); |
| 407 | + Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(List.of(volume)); |
| 408 | + |
| 409 | + overrideConfigValue(nasBackupProvider.NASBackupCompressionEnabled, "true"); |
| 410 | + |
| 411 | + BackupAnswer answer = mock(BackupAnswer.class); |
| 412 | + Mockito.when(answer.getResult()).thenReturn(true); |
| 413 | + Mockito.when(answer.getSize()).thenReturn(100L); |
| 414 | + |
| 415 | + ArgumentCaptor<TakeBackupCommand> cmdCaptor = ArgumentCaptor.forClass(TakeBackupCommand.class); |
| 416 | + Mockito.when(agentManager.send(anyLong(), cmdCaptor.capture())).thenReturn(answer); |
| 417 | + Mockito.when(backupDao.persist(Mockito.any(BackupVO.class))).thenAnswer(invocation -> invocation.getArgument(0)); |
| 418 | + Mockito.when(backupDao.update(Mockito.anyLong(), Mockito.any(BackupVO.class))).thenReturn(true); |
| 419 | + |
| 420 | + nasBackupProvider.takeBackup(vm, false); |
| 421 | + |
| 422 | + TakeBackupCommand capturedCmd = cmdCaptor.getValue(); |
| 423 | + Map<String, String> details = capturedCmd.getDetails(); |
| 424 | + Assert.assertEquals("true", details.get("compression")); |
| 425 | + |
| 426 | + // Reset config |
| 427 | + overrideConfigValue(nasBackupProvider.NASBackupCompressionEnabled, "false"); |
| 428 | + } |
| 429 | + |
| 430 | + @Test |
| 431 | + public void testTakeBackupDetailsBandwidthLimit() throws AgentUnavailableException, OperationTimedoutException { |
| 432 | + Long vmId = 1L; Long hostId = 2L; Long backupOfferingId = 3L; |
| 433 | + Long accountId = 4L; Long domainId = 5L; Long zoneId = 6L; |
| 434 | + |
| 435 | + VMInstanceVO vm = setupVmForTakeBackup(vmId, hostId, backupOfferingId, accountId, domainId, zoneId); |
| 436 | + setupHostAndRepo(hostId, backupOfferingId); |
| 437 | + |
| 438 | + VolumeVO volume = mock(VolumeVO.class); |
| 439 | + Mockito.when(volume.getState()).thenReturn(Volume.State.Ready); |
| 440 | + Mockito.when(volume.getSize()).thenReturn(100L); |
| 441 | + Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(List.of(volume)); |
| 442 | + |
| 443 | + overrideConfigValue(nasBackupProvider.NASBackupBandwidthLimitMbps, "50"); |
| 444 | + |
| 445 | + BackupAnswer answer = mock(BackupAnswer.class); |
| 446 | + Mockito.when(answer.getResult()).thenReturn(true); |
| 447 | + Mockito.when(answer.getSize()).thenReturn(100L); |
| 448 | + |
| 449 | + ArgumentCaptor<TakeBackupCommand> cmdCaptor = ArgumentCaptor.forClass(TakeBackupCommand.class); |
| 450 | + Mockito.when(agentManager.send(anyLong(), cmdCaptor.capture())).thenReturn(answer); |
| 451 | + Mockito.when(backupDao.persist(Mockito.any(BackupVO.class))).thenAnswer(invocation -> invocation.getArgument(0)); |
| 452 | + Mockito.when(backupDao.update(Mockito.anyLong(), Mockito.any(BackupVO.class))).thenReturn(true); |
| 453 | + |
| 454 | + nasBackupProvider.takeBackup(vm, false); |
| 455 | + |
| 456 | + TakeBackupCommand capturedCmd = cmdCaptor.getValue(); |
| 457 | + Map<String, String> details = capturedCmd.getDetails(); |
| 458 | + Assert.assertEquals("50", details.get("bandwidth_limit")); |
| 459 | + |
| 460 | + overrideConfigValue(nasBackupProvider.NASBackupBandwidthLimitMbps, "0"); |
| 461 | + } |
| 462 | + |
| 463 | + @Test |
| 464 | + public void testTakeBackupDetailsIntegrityCheck() throws AgentUnavailableException, OperationTimedoutException { |
| 465 | + Long vmId = 1L; Long hostId = 2L; Long backupOfferingId = 3L; |
| 466 | + Long accountId = 4L; Long domainId = 5L; Long zoneId = 6L; |
| 467 | + |
| 468 | + VMInstanceVO vm = setupVmForTakeBackup(vmId, hostId, backupOfferingId, accountId, domainId, zoneId); |
| 469 | + setupHostAndRepo(hostId, backupOfferingId); |
| 470 | + |
| 471 | + VolumeVO volume = mock(VolumeVO.class); |
| 472 | + Mockito.when(volume.getState()).thenReturn(Volume.State.Ready); |
| 473 | + Mockito.when(volume.getSize()).thenReturn(100L); |
| 474 | + Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(List.of(volume)); |
| 475 | + |
| 476 | + overrideConfigValue(nasBackupProvider.NASBackupIntegrityCheckEnabled, "true"); |
| 477 | + |
| 478 | + BackupAnswer answer = mock(BackupAnswer.class); |
| 479 | + Mockito.when(answer.getResult()).thenReturn(true); |
| 480 | + Mockito.when(answer.getSize()).thenReturn(100L); |
| 481 | + |
| 482 | + ArgumentCaptor<TakeBackupCommand> cmdCaptor = ArgumentCaptor.forClass(TakeBackupCommand.class); |
| 483 | + Mockito.when(agentManager.send(anyLong(), cmdCaptor.capture())).thenReturn(answer); |
| 484 | + Mockito.when(backupDao.persist(Mockito.any(BackupVO.class))).thenAnswer(invocation -> invocation.getArgument(0)); |
| 485 | + Mockito.when(backupDao.update(Mockito.anyLong(), Mockito.any(BackupVO.class))).thenReturn(true); |
| 486 | + |
| 487 | + nasBackupProvider.takeBackup(vm, false); |
| 488 | + |
| 489 | + TakeBackupCommand capturedCmd = cmdCaptor.getValue(); |
| 490 | + Map<String, String> details = capturedCmd.getDetails(); |
| 491 | + Assert.assertEquals("true", details.get("integrity_check")); |
| 492 | + |
| 493 | + overrideConfigValue(nasBackupProvider.NASBackupIntegrityCheckEnabled, "false"); |
| 494 | + } |
| 495 | + |
| 496 | + @Test |
| 497 | + public void testTakeBackupDetailsEncryptionWithPassphrase() throws AgentUnavailableException, OperationTimedoutException { |
| 498 | + Long vmId = 1L; Long hostId = 2L; Long backupOfferingId = 3L; |
| 499 | + Long accountId = 4L; Long domainId = 5L; Long zoneId = 6L; |
| 500 | + |
| 501 | + VMInstanceVO vm = setupVmForTakeBackup(vmId, hostId, backupOfferingId, accountId, domainId, zoneId); |
| 502 | + setupHostAndRepo(hostId, backupOfferingId); |
| 503 | + |
| 504 | + VolumeVO volume = mock(VolumeVO.class); |
| 505 | + Mockito.when(volume.getState()).thenReturn(Volume.State.Ready); |
| 506 | + Mockito.when(volume.getSize()).thenReturn(100L); |
| 507 | + Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(List.of(volume)); |
| 508 | + |
| 509 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionEnabled, "true"); |
| 510 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionPassphrase, "my-secret-passphrase"); |
| 511 | + |
| 512 | + BackupAnswer answer = mock(BackupAnswer.class); |
| 513 | + Mockito.when(answer.getResult()).thenReturn(true); |
| 514 | + Mockito.when(answer.getSize()).thenReturn(100L); |
| 515 | + |
| 516 | + ArgumentCaptor<TakeBackupCommand> cmdCaptor = ArgumentCaptor.forClass(TakeBackupCommand.class); |
| 517 | + Mockito.when(agentManager.send(anyLong(), cmdCaptor.capture())).thenReturn(answer); |
| 518 | + Mockito.when(backupDao.persist(Mockito.any(BackupVO.class))).thenAnswer(invocation -> invocation.getArgument(0)); |
| 519 | + Mockito.when(backupDao.update(Mockito.anyLong(), Mockito.any(BackupVO.class))).thenReturn(true); |
| 520 | + |
| 521 | + nasBackupProvider.takeBackup(vm, false); |
| 522 | + |
| 523 | + TakeBackupCommand capturedCmd = cmdCaptor.getValue(); |
| 524 | + Map<String, String> details = capturedCmd.getDetails(); |
| 525 | + Assert.assertEquals("true", details.get("encryption")); |
| 526 | + Assert.assertEquals("my-secret-passphrase", details.get("encryption_passphrase")); |
| 527 | + |
| 528 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionEnabled, "false"); |
| 529 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionPassphrase, ""); |
| 530 | + } |
| 531 | + |
| 532 | + @Test(expected = CloudRuntimeException.class) |
| 533 | + public void testTakeBackupEncryptionWithoutPassphraseThrows() throws AgentUnavailableException, OperationTimedoutException { |
| 534 | + Long vmId = 1L; Long hostId = 2L; Long backupOfferingId = 3L; |
| 535 | + Long accountId = 4L; Long domainId = 5L; Long zoneId = 6L; |
| 536 | + |
| 537 | + VMInstanceVO vm = setupVmForTakeBackup(vmId, hostId, backupOfferingId, accountId, domainId, zoneId); |
| 538 | + setupHostAndRepo(hostId, backupOfferingId); |
| 539 | + |
| 540 | + VolumeVO volume = mock(VolumeVO.class); |
| 541 | + Mockito.when(volume.getState()).thenReturn(Volume.State.Ready); |
| 542 | + Mockito.when(volume.getSize()).thenReturn(100L); |
| 543 | + Mockito.when(volumeDao.findByInstance(vmId)).thenReturn(List.of(volume)); |
| 544 | + |
| 545 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionEnabled, "true"); |
| 546 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionPassphrase, ""); |
| 547 | + |
| 548 | + Mockito.when(backupDao.persist(Mockito.any(BackupVO.class))).thenAnswer(invocation -> invocation.getArgument(0)); |
| 549 | + |
| 550 | + try { |
| 551 | + nasBackupProvider.takeBackup(vm, false); |
| 552 | + } finally { |
| 553 | + overrideConfigValue(nasBackupProvider.NASBackupEncryptionEnabled, "false"); |
| 554 | + } |
| 555 | + } |
352 | 556 | } |
0 commit comments