From 1c3d0e9a14e49307d80bb884081184845a8a1620 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Thu, 16 Jul 2026 13:32:08 +0200 Subject: [PATCH 1/6] test: fix smoke test failures on xen/vmware --- .../integration/smoke/test_events_resource.py | 19 ++++++++++++++----- test/integration/smoke/test_kms_lifecycle.py | 5 +++++ .../smoke/test_network_extension_namespace.py | 4 +++- .../smoke/test_nonstrict_affinity_group.py | 7 ++++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/test/integration/smoke/test_events_resource.py b/test/integration/smoke/test_events_resource.py index dac95f8c090a..1f5fd3a60c1b 100644 --- a/test/integration/smoke/test_events_resource.py +++ b/test/integration/smoke/test_events_resource.py @@ -147,16 +147,25 @@ def test_01_events_resource(self): diskofferingid=self.disk_offering.id ) self.cleanup.append(volume) - virtual_machine.attach_volume( - self.apiclient, - volume - ) + try: + virtual_machine.attach_volume( + self.apiclient, + volume + ) + except Exception as e: + print("Failed to attach volume to VM: %s" % e) + pass + virtual_machine.stop(self.apiclient) account_network.restart(self.apiclient, cleanup=False) time.sleep(self.services["sleep"]) virtual_machine.restore(self.apiclient) time.sleep(self.services["sleep"]) - virtual_machine.detach_volume(self.apiclient, volume) + try: + virtual_machine.detach_volume(self.apiclient, volume) + except Exception as e: + print("Failed to detach volume from VM: %s" % e) + pass volume.delete(self.apiclient) self.cleanup.remove(volume) ts = str(time.time()) diff --git a/test/integration/smoke/test_kms_lifecycle.py b/test/integration/smoke/test_kms_lifecycle.py index 79deb5bdf0e2..783a2af72e54 100644 --- a/test/integration/smoke/test_kms_lifecycle.py +++ b/test/integration/smoke/test_kms_lifecycle.py @@ -65,6 +65,7 @@ def setUpClass(cls): cls.apiclient = cls.test_client.getApiClient() cls.zone = get_zone(cls.apiclient, cls.test_client.getZoneForTests()) cls.domain = get_domain(cls.apiclient) + cls.hypervisor = cls.test_client.getHypervisorInfo() cls._cleanup = [] @@ -424,6 +425,10 @@ def test_12_deploy_vm_with_root_disk_encryption(self): Test: deploy a VM with its root disk encrypted using a KMS key. Verify that the VM starts and the root volume has the KMS key ID. """ + + if self.hypervisor.lower() != 'kvm': + raise self.skipTest("Skipping test case for non-kvm hypervisor") + # 1. Create a KMS key for the user key = self._create_kms_key(name=_random_name("vm-root-key"), profile_id=self.default_profile.id, apiclient=self.user_apiclient) diff --git a/test/integration/smoke/test_network_extension_namespace.py b/test/integration/smoke/test_network_extension_namespace.py index 5452cd4ac9d0..f2484d73d8c1 100644 --- a/test/integration/smoke/test_network_extension_namespace.py +++ b/test/integration/smoke/test_network_extension_namespace.py @@ -859,6 +859,8 @@ def _check_kvm_host_prerequisites(self, tools=None): excluded from the check — the connectivity failure will surface naturally when the test later tries to deploy scripts. """ + if self.hv.lower() != 'kvm': + raise self.skipTest("Skipping test case for non-kvm hypervisor") if tools is None: tools = ['arping', 'dnsmasq', 'haproxy'] if not self.kvm_host_configs: @@ -2387,7 +2389,7 @@ def _mk_action(name, parameters = []): @attr(tags=["advanced", "smoke"], required_hardware="true") def test_09_vpc_source_nat_ip_update(self): """Update VPC source NAT IP and verify old/new source NAT flags flip correctly.""" - self._check_kvm_host_prerequisites(['arping']) + self._check_kvm_host_prerequisites(['ip', 'arping', 'dnsmasq', 'haproxy']) svc = VPC_NETWORK_SERVICES _nw_offering, ext_name = self._setup_extension_nsp_offering( diff --git a/test/integration/smoke/test_nonstrict_affinity_group.py b/test/integration/smoke/test_nonstrict_affinity_group.py index 1b9b0c02c709..3e9890daf6b7 100644 --- a/test/integration/smoke/test_nonstrict_affinity_group.py +++ b/test/integration/smoke/test_nonstrict_affinity_group.py @@ -20,6 +20,7 @@ """ import logging +import time from marvin.codes import FAILED from nose.plugins.attrib import attr @@ -38,7 +39,6 @@ from marvin.lib.common import (get_domain, get_zone, - get_template, get_test_template) @@ -209,6 +209,9 @@ def test_01_non_strict_host_anti_affinity(self): vm_2_host_id, msg="Both VMs of affinity group %s are on the same host" % self.affinity_group.name) + + time.sleep(10) + # 4. Migrate vm-2 to same host as vm-1 self.virtual_machine_2.migrate( self.apiclient, @@ -362,6 +365,8 @@ def test_02_non_strict_host_affinity(self): vm_12_host_id, msg="Both VMs of affinity group %s are on the different host" % self.affinity_group.name) + time.sleep(10) + # 4. Migrate vm-12 to different host as vm-11 self.virtual_machine_12.migrate( self.apiclient From 748e2cee69d124a857e3c47b2586dfc1d451ca47 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Fri, 17 Jul 2026 11:41:28 +0200 Subject: [PATCH 2/6] test: sleep 10 seconds before attaching volume in test_events_resource.py --- .../integration/smoke/test_events_resource.py | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/test/integration/smoke/test_events_resource.py b/test/integration/smoke/test_events_resource.py index 1f5fd3a60c1b..fce0e6d7370f 100644 --- a/test/integration/smoke/test_events_resource.py +++ b/test/integration/smoke/test_events_resource.py @@ -147,25 +147,17 @@ def test_01_events_resource(self): diskofferingid=self.disk_offering.id ) self.cleanup.append(volume) - try: - virtual_machine.attach_volume( - self.apiclient, - volume - ) - except Exception as e: - print("Failed to attach volume to VM: %s" % e) - pass - + time.sleep(10) + virtual_machine.attach_volume( + self.apiclient, + volume + ) virtual_machine.stop(self.apiclient) account_network.restart(self.apiclient, cleanup=False) time.sleep(self.services["sleep"]) virtual_machine.restore(self.apiclient) time.sleep(self.services["sleep"]) - try: - virtual_machine.detach_volume(self.apiclient, volume) - except Exception as e: - print("Failed to detach volume from VM: %s" % e) - pass + virtual_machine.detach_volume(self.apiclient, volume) volume.delete(self.apiclient) self.cleanup.remove(volume) ts = str(time.time()) From af1499ba6cd9d6df6c9547ecb62424a7fa0683fd Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Mon, 27 Jul 2026 16:27:48 +0200 Subject: [PATCH 3/6] test: add more time.sleep(10) --- test/integration/smoke/test_host_maintenance.py | 4 ++++ test/integration/smoke/test_usage.py | 2 ++ test/integration/smoke/test_vm_life_cycle.py | 1 + 3 files changed, 7 insertions(+) diff --git a/test/integration/smoke/test_host_maintenance.py b/test/integration/smoke/test_host_maintenance.py index 9a84f325ede7..93419951ff67 100644 --- a/test/integration/smoke/test_host_maintenance.py +++ b/test/integration/smoke/test_host_maintenance.py @@ -27,6 +27,8 @@ from distutils.util import strtobool from marvin.sshClient import SshClient +import time + _multiprocess_shared_ = False MIN_VMS_FOR_TEST = 3 @@ -349,6 +351,7 @@ def test_02_cancel_host_maintenace_with_migration_jobs(self): if (no_vm_req > 0): self.logger.debug("Creating vms = {}".format(no_vm_req)) self.vmlist = self.createVMs(listHost[0].id, no_vm_req) + time.sleep(10) try: migrations_finished = self.hostPrepareAndCancelMaintenance(listHost[0].id, listHost[1].id) @@ -413,6 +416,7 @@ def test_03_cancel_host_maintenace_with_migration_jobs_failure(self): if (no_vm_req > 0): self.logger.debug("Creating vms = {}".format(no_vm_req)) self.vmlist = self.createVMs(listHost[0].id, no_vm_req, "taggedsmall") + time.sleep(10) # Attempt putting host in maintenance and check if ErrorInMaintenance state is reached self.prepare_host_for_maintenance(target_host_id) diff --git a/test/integration/smoke/test_usage.py b/test/integration/smoke/test_usage.py index fef0d8fe3c1e..f4bb14ba8417 100644 --- a/test/integration/smoke/test_usage.py +++ b/test/integration/smoke/test_usage.py @@ -43,6 +43,7 @@ list_storage_pools, find_storage_pool_type) +import time class Services: @@ -782,6 +783,7 @@ def test_01_volume_usage(self): ) rool_volume_pool = rool_volume_pool_response[0] try: + time.sleep(10) self.virtual_machine.attach_volume(self.apiclient,volume_uploaded) except Exception as e: self.debug("Exception %s: " % e) diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index 8df0b994a555..2bb4effb704d 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -858,6 +858,7 @@ def test_11_destroy_vm_and_volumes(self): zoneid=self.zone.id ) + time.sleep(10) small_virtual_machine.attach_volume(self.apiclient, vol1) self.debug("Destroy VM - ID: %s" % small_virtual_machine.id) From 0ffe696301e3b5c8e5488492bc5e55a013647f51 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 28 Jul 2026 14:50:48 +0200 Subject: [PATCH 4/6] test: add more time.sleep(10) in test_vm_strict_host_tags.py --- test/integration/smoke/test_vm_strict_host_tags.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/smoke/test_vm_strict_host_tags.py b/test/integration/smoke/test_vm_strict_host_tags.py index aac3e1ea65f2..26d36d7b5c36 100644 --- a/test/integration/smoke/test_vm_strict_host_tags.py +++ b/test/integration/smoke/test_vm_strict_host_tags.py @@ -22,6 +22,7 @@ from marvin.lib.common import (get_domain, get_zone) from nose.plugins.attrib import attr +import time class TestVMDeploymentPlannerStrictTags(cloudstackTestCase): @@ -529,6 +530,8 @@ def test_01_migrate_vm_strict_tags_success(self): self.cleanup.append(vm) self.assertEqual(self.host_h1.id, vm.hostid, "VM instance was not deployed on target host ID") Host.update(self.apiclient, id=self.host_h2.id, hosttags="h1,t1,v1") + + time.sleep(10) # Wait for VM to boot into OS before migrating the VM vm.migrate(self.apiclient, self.host_h2.id) migrated_vm = VirtualMachine.list(self.apiclient, id=vm.id, listall=True)[0] self.assertEqual(migrated_vm.hostid, self.host_h2.id, "VM was not migratd") @@ -545,6 +548,7 @@ def test_02_migrate_vm_strict_tags_failure(self): self.assertEqual(self.host_h1.id, vm.hostid, "VM instance was not deployed on target host ID") Host.update(self.apiclient, id=self.host_h2.id, hosttags="h2,t2,v2") try: + time.sleep(10) # Wait for VM to boot into OS before migrating the VM vm.migrate(self.apiclient, self.host_h2.id) VirtualMachine.list(self.apiclient, id=vm.id, listall=True)[0] self.fail("VM should not be migrated") From be38fcc5aa8f90bb9c9e7a1be9ae99204e976b72 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 28 Jul 2026 15:12:10 +0200 Subject: [PATCH 5/6] test: fix test_usage.py --- test/integration/smoke/test_usage.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/test/integration/smoke/test_usage.py b/test/integration/smoke/test_usage.py index f4bb14ba8417..501070980652 100644 --- a/test/integration/smoke/test_usage.py +++ b/test/integration/smoke/test_usage.py @@ -1746,16 +1746,9 @@ def setUpClass(cls): domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id ) - cls.public_ip = PublicIPAddress.create( - cls.api_client, - accountid=cls.virtual_machine.account, - zoneid=cls.virtual_machine.zoneid, - domainid=cls.virtual_machine.domainid, - services=cls.services["server"] - ) src_nat_list = PublicIPAddress.list( cls.api_client, - accountid=cls.virtual_machine.account, + account=cls.virtual_machine.account, zoneid=cls.virtual_machine.zoneid, domainid=cls.virtual_machine.domainid, issourcenat=True From a6abccea38952676c20c46c3aaa3a5bcff27c377 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 28 Jul 2026 15:55:41 +0200 Subject: [PATCH 6/6] xenserver/xcpng: do not bypass secondary storage when copy volumes between pools --- .../storage/motion/AncientDataMotionStrategy.java | 8 ++++++++ .../motion/AncientDataMotionStrategyTest.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index bbf775de27ad..78d720737b3e 100644 --- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -556,7 +556,15 @@ private boolean canBypassSecondaryStorage(DataObject srcData, DataObject destDat return true; } + if (Hypervisor.HypervisorType.XenServer.equals(((VolumeInfo) srcData).getHypervisorType())) { + return false; + } + if (destData instanceof VolumeInfo) { + if (Hypervisor.HypervisorType.XenServer.equals(((VolumeInfo) destData).getHypervisorType())) { + return false; + } + Scope srcDataStoreScope = srcData.getDataStore().getScope(); Scope destDataStoreScope = destData.getDataStore().getScope(); logger.info("srcDataStoreScope: {}, srcData pool type: {}; destDataStoreScope: {}, destData pool type: {}", diff --git a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java index 86af81899e8f..56b689f89cf9 100755 --- a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java +++ b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategyTest.java @@ -143,6 +143,7 @@ public void testCanBypassSecondaryStorageForDirectDownload() throws NoSuchMethod @Test public void testCanBypassSecondaryStorageForUnsupportedDataObject() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); TemplateObject destTemplateInfo = Mockito.spy(new TemplateObject()); @@ -156,12 +157,14 @@ public void testCanBypassSecondaryStorageForUnsupportedDataObject() throws NoSuc @Test public void testCanBypassSecondaryStorageForUnsupportedSrcPoolType() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.PowerFlex).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -177,12 +180,14 @@ public void testCanBypassSecondaryStorageForUnsupportedSrcPoolType() throws NoSu @Test public void testCanBypassSecondaryStorageForUnsupportedDestPoolType() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -198,12 +203,14 @@ public void testCanBypassSecondaryStorageForUnsupportedDestPoolType() throws NoS @Test public void testCanBypassSecondaryStorageWithZoneWideNFSPoolsInSameZone() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -219,12 +226,14 @@ public void testCanBypassSecondaryStorageWithZoneWideNFSPoolsInSameZone() throws @Test public void testCanBypassSecondaryStorageWithClusterWideNFSPoolsInSameCluster() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(5L, 2L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(5L, 2L, 1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -240,12 +249,14 @@ public void testCanBypassSecondaryStorageWithClusterWideNFSPoolsInSameCluster() @Test public void testCanBypassSecondaryStorageWithLocalAndClusterWideNFSPoolsInSameCluster() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new HostScope(1L, 1L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.Filesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(1L, 1L, 1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -264,12 +275,14 @@ public void testCanBypassSecondaryStorageWithLocalAndClusterWideNFSPoolsInSameCl @Test public void testCanBypassSecondaryStorageWithLocalAndZoneWideNFSPoolsInSameZone() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new HostScope(1L, 1L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.Filesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore(); @@ -288,12 +301,14 @@ public void testCanBypassSecondaryStorageWithLocalAndZoneWideNFSPoolsInSameZone( @Test public void testCanBypassSecondaryStorageWithClusterWideNFSAndZoneWideNFSPoolsInSameZone() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { VolumeObject srcVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(srcVolumeInfo).getHypervisorType(); DataStore srcDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ClusterScope(5L, 2L, 1L)).when(srcDataStore).getScope(); Mockito.doReturn(srcDataStore).when(srcVolumeInfo).getDataStore(); Mockito.doReturn(Storage.StoragePoolType.NetworkFilesystem).when(srcVolumeInfo).getStoragePoolType(); VolumeObject destVolumeInfo = Mockito.spy(new VolumeObject()); + Mockito.doReturn(HypervisorType.KVM).when(destVolumeInfo).getHypervisorType(); DataStore destDataStore = Mockito.mock(DataStore.class); Mockito.doReturn(new ZoneScope(1L)).when(destDataStore).getScope(); Mockito.doReturn(destDataStore).when(destVolumeInfo).getDataStore();