From 26c91401ee8f203d74261a6b0c67196173ef57d6 Mon Sep 17 00:00:00 2001 From: Claudiu Belu Date: Tue, 30 Jan 2018 03:48:37 -0800 Subject: [PATCH] tests: autospecs mock.patch and classes usages By default, mock.patch's autospec argument is None, meaning that there's no signature checking for the patched methods and funtions. oslotest.mock_fixture.patch_mock_module fixes a few issues within mock.patch functions, as well as setting autospec=True by default, unless otherwise specified or new_callable, create, spec arguments are passed in. Updates HyperVBaseTestCase to autospec the classes used by different *Ops classes. Change-Id: Ifbdc185d0b50e29c5d5f3ff036141253d2323076 Partial-Bug: #1735588 --- compute_hyperv/tests/test.py | 8 ++ .../tests/unit/cluster/test_clusterops.py | 13 ++-- .../tests/unit/cluster/test_driver.py | 12 +-- .../unit/cluster/test_livemigrationops.py | 5 +- compute_hyperv/tests/unit/test_base.py | 14 +++- .../tests/unit/test_block_device_manager.py | 7 +- compute_hyperv/tests/unit/test_driver.py | 25 +++--- .../tests/unit/test_eventhandler.py | 10 ++- compute_hyperv/tests/unit/test_hostops.py | 10 ++- compute_hyperv/tests/unit/test_imagecache.py | 5 +- .../tests/unit/test_livemigrationops.py | 57 +++++++------- .../tests/unit/test_migrationops.py | 14 ++-- .../tests/unit/test_rdpconsoleops.py | 6 +- .../tests/unit/test_serialconsolehandler.py | 12 ++- .../tests/unit/test_serialconsoleops.py | 6 +- compute_hyperv/tests/unit/test_snapshotops.py | 5 +- compute_hyperv/tests/unit/test_vmops.py | 78 ++++++++----------- compute_hyperv/tests/unit/test_volumeops.py | 10 ++- 18 files changed, 176 insertions(+), 121 deletions(-) diff --git a/compute_hyperv/tests/test.py b/compute_hyperv/tests/test.py index 8a8d7742..1fac60f9 100644 --- a/compute_hyperv/tests/test.py +++ b/compute_hyperv/tests/test.py @@ -34,6 +34,7 @@ from nova.tests.unit import conf_fixture from nova.tests.unit import policy_fixture from oslo_log.fixture import logging_error as log_fixture from oslo_log import log as logging +from oslotest import mock_fixture from oslotest import moxstubout import six import testtools @@ -70,6 +71,12 @@ def _patch_mock_to_raise_for_invalid_assert_calls(): # to patch the mock lib _patch_mock_to_raise_for_invalid_assert_calls() +# NOTE(claudiub): this needs to be called before any mock.patch calls are +# being done, and especially before any other test classes load. This fixes +# the mock.patch autospec issue: +# https://github.com/testing-cabal/mock/issues/396 +mock_fixture.patch_mock_module() + class NoDBTestCase(testtools.TestCase): """Test case base class for all unit tests. @@ -83,6 +90,7 @@ class NoDBTestCase(testtools.TestCase): def setUp(self): """Run before each test method to initialize test environment.""" super(NoDBTestCase, self).setUp() + self.useFixture(mock_fixture.MockAutospecFixture()) self.useFixture(nova_fixtures.Timeout( os.environ.get('OS_TEST_TIMEOUT', 0), self.TIMEOUT_SCALING_FACTOR)) diff --git a/compute_hyperv/tests/unit/cluster/test_clusterops.py b/compute_hyperv/tests/unit/cluster/test_clusterops.py index 6e7a411e..3ab6fc04 100644 --- a/compute_hyperv/tests/unit/cluster/test_clusterops.py +++ b/compute_hyperv/tests/unit/cluster/test_clusterops.py @@ -33,10 +33,16 @@ CONF = compute_hyperv.nova.conf.CONF class ClusterOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V ClusterOps class.""" + _autospec_classes = [ + clusterops.hostops.HostOps, + clusterops.network.API, + clusterops.vmops.VMOps, + clusterops.serialconsoleops.SerialConsoleOps, + ] + _FAKE_INSTANCE_NAME = 'fake_instance_name' - @mock.patch('nova.network.API') - def setUp(self, mock_network_api): + def setUp(self): super(ClusterOpsTestCase, self).setUp() self.context = 'fake_context' @@ -44,9 +50,6 @@ class ClusterOpsTestCase(test_base.HyperVBaseTestCase): self.clusterops._context = self.context self.clusterops._clustutils = mock.MagicMock() self.clusterops._vmutils = mock.MagicMock() - self.clusterops._network_api = mock.MagicMock() - self.clusterops._vmops = mock.MagicMock() - self.clusterops._serial_console_ops = mock.MagicMock() self._clustutils = self.clusterops._clustutils def test_get_instance_host(self): diff --git a/compute_hyperv/tests/unit/cluster/test_driver.py b/compute_hyperv/tests/unit/cluster/test_driver.py index 5b8dba95..aaa339ac 100644 --- a/compute_hyperv/tests/unit/cluster/test_driver.py +++ b/compute_hyperv/tests/unit/cluster/test_driver.py @@ -20,7 +20,6 @@ import mock from nova import safe_utils from nova.virt import driver as nova_base_driver -from compute_hyperv.nova.cluster import clusterops from compute_hyperv.nova.cluster import driver from compute_hyperv.nova import driver as base_driver from compute_hyperv.tests.unit import test_base @@ -28,16 +27,19 @@ from compute_hyperv.tests.unit import test_base class HyperVClusterTestCase(test_base.HyperVBaseTestCase): - @mock.patch.object(clusterops, 'ClusterOps') - @mock.patch.object(base_driver.hostops, 'api', mock.MagicMock()) + _autospec_classes = [ + driver.clusterops.ClusterOps, + base_driver.hostops.api.API, + driver.livemigrationops.ClusterLiveMigrationOps, + ] + @mock.patch.object(base_driver.HyperVDriver, '_check_minimum_windows_version') - def setUp(self, mock_check_minimum_windows_version, mock_clusterops_init): + def setUp(self, mock_check_minimum_windows_version): super(HyperVClusterTestCase, self).setUp() self.context = 'context' self.driver = driver.HyperVClusterDriver(mock.sentinel.virtapi) - self.driver._livemigrationops = mock.Mock() def test_public_api_signatures(self): driver_methods = dict(driver.HyperVClusterDriver.__dict__, diff --git a/compute_hyperv/tests/unit/cluster/test_livemigrationops.py b/compute_hyperv/tests/unit/cluster/test_livemigrationops.py index f5501bf5..5564686b 100644 --- a/compute_hyperv/tests/unit/cluster/test_livemigrationops.py +++ b/compute_hyperv/tests/unit/cluster/test_livemigrationops.py @@ -30,12 +30,15 @@ from compute_hyperv.tests.unit import test_base class ClusterLiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V Cluster LivemigrationOps class.""" + _autospec_classes = [ + base_livemigrationops.volumeops.VolumeOps, + ] + def setUp(self): super(ClusterLiveMigrationOpsTestCase, self).setUp() self._fake_context = 'fake_context' self.livemigrops = livemigrationops.ClusterLiveMigrationOps() self.livemigrops._clustutils = mock.MagicMock() - self.livemigrops._volumeops = mock.MagicMock() self._clustutils = self.livemigrops._clustutils diff --git a/compute_hyperv/tests/unit/test_base.py b/compute_hyperv/tests/unit/test_base.py index 0f85f256..d443709f 100644 --- a/compute_hyperv/tests/unit/test_base.py +++ b/compute_hyperv/tests/unit/test_base.py @@ -21,9 +21,21 @@ from compute_hyperv.tests import test class HyperVBaseTestCase(test.NoDBTestCase): + _autospec_classes = [] + def setUp(self): super(HyperVBaseTestCase, self).setUp() utilsfactory_patcher = mock.patch.object(utilsfactory, '_get_class') utilsfactory_patcher.start() - self.addCleanup(utilsfactory_patcher.stop) + + self._patch_autospec_classes() + self.addCleanup(mock.patch.stopall) + + def _patch_autospec_classes(self): + for class_type in self._autospec_classes: + mocked_class = mock.MagicMock(autospec=class_type) + patcher = mock.patch( + '.'.join([class_type.__module__, class_type.__name__]), + mocked_class) + patcher.start() diff --git a/compute_hyperv/tests/unit/test_block_device_manager.py b/compute_hyperv/tests/unit/test_block_device_manager.py index 3a118f23..6e9f93e2 100644 --- a/compute_hyperv/tests/unit/test_block_device_manager.py +++ b/compute_hyperv/tests/unit/test_block_device_manager.py @@ -33,6 +33,11 @@ from compute_hyperv.tests.unit import test_base class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V BlockDeviceInfoManager class.""" + _autospec_classes = [ + block_device_manager.volumeops.VolumeOps, + block_device_manager.pathutils.PathUtils, + ] + _FAKE_CONN_INFO = { 'serial': 'fake_volume_id' } @@ -46,9 +51,7 @@ class BlockDeviceManagerTestCase(test_base.HyperVBaseTestCase): def setUp(self): super(BlockDeviceManagerTestCase, self).setUp() self._bdman = block_device_manager.BlockDeviceInfoManager() - self._bdman._volops = mock.Mock() self._bdman._vmutils = mock.Mock() - self._bdman._pathutils = mock.Mock() self._volops = self._bdman._volops self._pathutils = self._bdman._pathutils diff --git a/compute_hyperv/tests/unit/test_driver.py b/compute_hyperv/tests/unit/test_driver.py index 0f2790d9..f71b9869 100644 --- a/compute_hyperv/tests/unit/test_driver.py +++ b/compute_hyperv/tests/unit/test_driver.py @@ -33,6 +33,20 @@ from compute_hyperv.tests.unit import test_base class HyperVDriverTestCase(test_base.HyperVBaseTestCase): + _autospec_classes = [ + driver.hostops.HostOps, + driver.volumeops.VolumeOps, + driver.vmops.VMOps, + driver.snapshotops.SnapshotOps, + driver.livemigrationops.LiveMigrationOps, + driver.migrationops.MigrationOps, + driver.rdpconsoleops.RDPConsoleOps, + driver.serialconsoleops.SerialConsoleOps, + driver.imagecache.ImageCache, + driver.image.API, + driver.pathutils.PathUtils, + ] + FAKE_WIN_2008R2_VERSION = '6.0.0' @mock.patch.object(driver.hostops, 'api', mock.MagicMock()) @@ -42,17 +56,6 @@ class HyperVDriverTestCase(test_base.HyperVBaseTestCase): self.context = 'context' self.driver = driver.HyperVDriver(mock.sentinel.virtapi) - self.driver._hostops = mock.MagicMock() - self.driver._volumeops = mock.MagicMock() - self.driver._vmops = mock.MagicMock() - self.driver._snapshotops = mock.MagicMock() - self.driver._livemigrationops = mock.MagicMock() - self.driver._migrationops = mock.MagicMock() - self.driver._rdpconsoleops = mock.MagicMock() - self.driver._serialconsoleops = mock.MagicMock() - self.driver._imagecache = mock.MagicMock() - self.driver._image_api = mock.MagicMock() - self.driver._pathutils = mock.MagicMock() @mock.patch.object(driver.LOG, 'warning') @mock.patch.object(driver.utilsfactory, 'get_hostutils') diff --git a/compute_hyperv/tests/unit/test_eventhandler.py b/compute_hyperv/tests/unit/test_eventhandler.py index cf75a26c..51fe6075 100644 --- a/compute_hyperv/tests/unit/test_eventhandler.py +++ b/compute_hyperv/tests/unit/test_eventhandler.py @@ -15,6 +15,7 @@ import mock from nova import utils +from nova.virt import driver from os_win import constants from os_win import utilsfactory @@ -24,6 +25,11 @@ from compute_hyperv.tests.unit import test_base class EventHandlerTestCase(test_base.HyperVBaseTestCase): + + _autospec_classes = [ + eventhandler.serialconsoleops.SerialConsoleOps, + ] + _FAKE_POLLING_INTERVAL = 3 _FAKE_EVENT_CHECK_TIMEFRAME = 15 @@ -31,7 +37,8 @@ class EventHandlerTestCase(test_base.HyperVBaseTestCase): def setUp(self, mock_get_vmutils): super(EventHandlerTestCase, self).setUp() - self._state_change_callback = mock.Mock() + self._state_change_callback = mock.Mock( + autospec=driver.ComputeDriver.emit_event) self.flags( power_state_check_timeframe=self._FAKE_EVENT_CHECK_TIMEFRAME, group='hyperv') @@ -41,7 +48,6 @@ class EventHandlerTestCase(test_base.HyperVBaseTestCase): self._event_handler = eventhandler.InstanceEventHandler( self._state_change_callback) - self._event_handler._serial_console_ops = mock.Mock() @mock.patch.object(vmops.VMOps, 'get_instance_uuid') @mock.patch.object(eventhandler.InstanceEventHandler, '_emit_event') diff --git a/compute_hyperv/tests/unit/test_hostops.py b/compute_hyperv/tests/unit/test_hostops.py index 95fafde0..ffd6b925 100644 --- a/compute_hyperv/tests/unit/test_hostops.py +++ b/compute_hyperv/tests/unit/test_hostops.py @@ -35,6 +35,12 @@ CONF = compute_hyperv.nova.conf.CONF class HostOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V HostOps class.""" + _autospec_classes = [ + hostops.pathutils.PathUtils, + hostops.vmops.VMOps, + hostops.api.API, + ] + FAKE_ARCHITECTURE = 0 FAKE_NAME = 'fake_name' FAKE_MANUFACTURER = 'FAKE_MANUFACTURER' @@ -43,14 +49,10 @@ class HostOpsTestCase(test_base.HyperVBaseTestCase): FAKE_LOCAL_IP = '10.11.12.13' FAKE_TICK_COUNT = 1000000 - @mock.patch.object(hostops, 'api', mock.MagicMock()) def setUp(self): super(HostOpsTestCase, self).setUp() self._hostops = hostops.HostOps() - self._hostops._api = mock.MagicMock() - self._hostops._vmops = mock.MagicMock() self._hostops._hostutils = mock.MagicMock() - self._hostops._pathutils = mock.MagicMock() self._hostops._diskutils = mock.MagicMock() def test_get_cpu_info(self): diff --git a/compute_hyperv/tests/unit/test_imagecache.py b/compute_hyperv/tests/unit/test_imagecache.py index 2ef3be5d..fb598124 100644 --- a/compute_hyperv/tests/unit/test_imagecache.py +++ b/compute_hyperv/tests/unit/test_imagecache.py @@ -35,6 +35,10 @@ CONF = compute_hyperv.nova.conf.CONF class ImageCacheTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V ImageCache class.""" + _autospec_classes = [ + imagecache.pathutils.PathUtils, + ] + FAKE_FORMAT = 'fake_format' FAKE_IMAGE_REF = 'fake_image_ref' FAKE_VHD_SIZE_GB = 1 @@ -46,7 +50,6 @@ class ImageCacheTestCase(test_base.HyperVBaseTestCase): self.instance = fake_instance.fake_instance_obj(self.context) self.imagecache = imagecache.ImageCache() - self.imagecache._pathutils = mock.MagicMock() self.imagecache._vhdutils = mock.MagicMock() self.tmpdir = self.useFixture(fixtures.TempDir()).path diff --git a/compute_hyperv/tests/unit/test_livemigrationops.py b/compute_hyperv/tests/unit/test_livemigrationops.py index 8f7349c4..9f724b6e 100644 --- a/compute_hyperv/tests/unit/test_livemigrationops.py +++ b/compute_hyperv/tests/unit/test_livemigrationops.py @@ -21,7 +21,6 @@ from os_win import exceptions as os_win_exc import compute_hyperv.nova.conf from compute_hyperv.nova import livemigrationops -from compute_hyperv.nova import serialconsoleops from compute_hyperv.tests import fake_instance from compute_hyperv.tests.unit import test_base @@ -32,27 +31,33 @@ CONF = compute_hyperv.nova.conf.CONF class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V LiveMigrationOps class.""" + _autospec_classes = [ + livemigrationops.pathutils.PathUtils, + livemigrationops.vmops.VMOps, + livemigrationops.volumeops.VolumeOps, + livemigrationops.serialconsoleops.SerialConsoleOps, + livemigrationops.imagecache.ImageCache, + livemigrationops.block_device_manager.BlockDeviceInfoManager, + ] + def setUp(self): super(LiveMigrationOpsTestCase, self).setUp() self.context = 'fake_context' self._livemigrops = livemigrationops.LiveMigrationOps() self._livemigrops._livemigrutils = mock.MagicMock() - self._livemigrops._pathutils = mock.MagicMock() - self._livemigrops._block_dev_man = mock.MagicMock() self._pathutils = self._livemigrops._pathutils - @mock.patch.object(serialconsoleops.SerialConsoleOps, - 'stop_console_handler') - @mock.patch('compute_hyperv.nova.vmops.VMOps.copy_vm_dvd_disks') - def _test_live_migration(self, mock_copy_dvd_disk, - mock_stop_console_handler, - side_effect=None, + def _test_live_migration(self, side_effect=None, shared_storage=False, migrate_data_received=True, migrate_data_version='1.1'): mock_instance = fake_instance.fake_instance_obj(self.context) mock_post = mock.MagicMock() mock_recover = mock.MagicMock() + + mock_copy_dvd_disks = self._livemigrops._vmops.copy_vm_dvd_disks + mock_stop_console_handler = ( + self._livemigrops._serial_console_ops.stop_console_handler) mock_copy_logs = self._livemigrops._pathutils.copy_vm_console_logs fake_dest = mock.sentinel.DESTINATION mock_check_shared_inst_dir = ( @@ -113,11 +118,11 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): if not shared_storage: mock_copy_logs.assert_called_once_with(mock_instance.name, fake_dest) - mock_copy_dvd_disk.assert_called_once_with(mock_instance.name, - fake_dest) + mock_copy_dvd_disks.assert_called_once_with(mock_instance.name, + fake_dest) else: self.assertFalse(mock_copy_logs.called) - self.assertFalse(mock_copy_dvd_disk.called) + self.assertFalse(mock_copy_dvd_disks.called) mock_live_migr = self._livemigrops._livemigrutils.live_migrate_vm mock_live_migr.assert_called_once_with( @@ -137,14 +142,11 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): def test_live_migration_shared_storage(self): self._test_live_migration(shared_storage=True) - @mock.patch('compute_hyperv.nova.volumeops.VolumeOps' - '.get_disk_path_mapping') - @mock.patch('compute_hyperv.nova.imagecache.ImageCache.get_cached_image') - @mock.patch('compute_hyperv.nova.volumeops.VolumeOps.connect_volumes') - def _test_pre_live_migration(self, mock_connect_volumes, - mock_get_cached_image, - mock_get_disk_path_mapping, - phys_disks_attached=True): + def _test_pre_live_migration(self, phys_disks_attached=True): + mock_get_disk_path_mapping = ( + self._livemigrops._volumeops.get_disk_path_mapping) + mock_get_cached_image = self._livemigrops._imagecache.get_cached_image + mock_instance = fake_instance.fake_instance_obj(self.context) mock_instance.image_ref = "fake_image_ref" mock_get_disk_path_mapping.return_value = ( @@ -166,7 +168,7 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): mock.sentinel.BLOCK_INFO) mock_get_cached_image.assert_called_once_with(self.context, mock_instance) - mock_connect_volumes.assert_called_once_with( + self._livemigrops._volumeops.connect_volumes.assert_called_once_with( mock.sentinel.BLOCK_INFO) mock_get_disk_path_mapping.assert_called_once_with( mock.sentinel.BLOCK_INFO, block_dev_only=True) @@ -183,9 +185,7 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): def test_pre_live_migration_invalid_disk_mapping(self): self._test_pre_live_migration(phys_disks_attached=False) - @mock.patch('compute_hyperv.nova.volumeops.VolumeOps.disconnect_volumes') - def _test_post_live_migration(self, mock_disconnect_volumes, - shared_storage=False): + def _test_post_live_migration(self, shared_storage=False): migrate_data = migrate_data_obj.HyperVLiveMigrateData( is_shared_instance_path=shared_storage) @@ -193,6 +193,8 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): self.context, mock.sentinel.instance, mock.sentinel.block_device_info, migrate_data) + mock_disconnect_volumes = ( + self._livemigrops._volumeops.disconnect_volumes) mock_disconnect_volumes.assert_called_once_with( mock.sentinel.block_device_info) mock_get_inst_dir = self._pathutils.get_instance_dir @@ -237,11 +239,10 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase): mock.sentinel.context, mock_instance, mock.sentinel.src_comp_info, mock.sentinel.dest_comp_info) - @mock.patch.object(livemigrationops.vmops.VMOps, 'plug_vifs') - def test_post_live_migration_at_destination(self, mock_plug_vifs): + def test_post_live_migration_at_destination(self): self._livemigrops.post_live_migration_at_destination( self.context, mock.sentinel.instance, network_info=mock.sentinel.NET_INFO, block_migration=mock.sentinel.BLOCK_INFO) - mock_plug_vifs.assert_called_once_with(mock.sentinel.instance, - mock.sentinel.NET_INFO) + self._livemigrops._vmops.plug_vifs.assert_called_once_with( + mock.sentinel.instance, mock.sentinel.NET_INFO) diff --git a/compute_hyperv/tests/unit/test_migrationops.py b/compute_hyperv/tests/unit/test_migrationops.py index f68e3a36..f9eba24a 100644 --- a/compute_hyperv/tests/unit/test_migrationops.py +++ b/compute_hyperv/tests/unit/test_migrationops.py @@ -32,6 +32,14 @@ from compute_hyperv.tests.unit import test_base class MigrationOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V MigrationOps class.""" + _autospec_classes = [ + migrationops.pathutils.PathUtils, + migrationops.volumeops.VolumeOps, + migrationops.vmops.VMOps, + migrationops.imagecache.ImageCache, + migrationops.block_device_manager.BlockDeviceInfoManager, + ] + _FAKE_DISK = 'fake_disk' _FAKE_TIMEOUT = 10 _FAKE_RETRY_INTERVAL = 5 @@ -42,14 +50,8 @@ class MigrationOpsTestCase(test_base.HyperVBaseTestCase): self._migrationops = migrationops.MigrationOps() self._migrationops._hostutils = mock.MagicMock() - self._migrationops._vmops = mock.MagicMock() self._migrationops._vmutils = mock.MagicMock() - self._migrationops._pathutils = mock.Mock() self._migrationops._vhdutils = mock.MagicMock() - self._migrationops._pathutils = mock.MagicMock() - self._migrationops._volumeops = mock.MagicMock() - self._migrationops._imagecache = mock.MagicMock() - self._migrationops._block_dev_man = mock.MagicMock() self._migrationops._migrationutils = mock.MagicMock() self._migrationops._metricsutils = mock.MagicMock() self._hostutils = self._migrationops._hostutils diff --git a/compute_hyperv/tests/unit/test_rdpconsoleops.py b/compute_hyperv/tests/unit/test_rdpconsoleops.py index d48c17f8..8024feb1 100644 --- a/compute_hyperv/tests/unit/test_rdpconsoleops.py +++ b/compute_hyperv/tests/unit/test_rdpconsoleops.py @@ -25,12 +25,14 @@ from compute_hyperv.tests.unit import test_base class RDPConsoleOpsTestCase(test_base.HyperVBaseTestCase): - @mock.patch.object(rdpconsoleops.hostops, 'api', mock.MagicMock()) + _autospec_classes = [ + rdpconsoleops.hostops.HostOps, + ] + def setUp(self): super(RDPConsoleOpsTestCase, self).setUp() self.rdpconsoleops = rdpconsoleops.RDPConsoleOps() - self.rdpconsoleops._hostops = mock.MagicMock() self.rdpconsoleops._vmutils = mock.MagicMock() self.rdpconsoleops._rdpconsoleutils = mock.MagicMock() diff --git a/compute_hyperv/tests/unit/test_serialconsolehandler.py b/compute_hyperv/tests/unit/test_serialconsolehandler.py index 3773af02..9c6d0309 100644 --- a/compute_hyperv/tests/unit/test_serialconsolehandler.py +++ b/compute_hyperv/tests/unit/test_serialconsolehandler.py @@ -24,17 +24,21 @@ from compute_hyperv.tests.unit import test_base class SerialConsoleHandlerTestCase(test_base.HyperVBaseTestCase): - @mock.patch.object(pathutils.PathUtils, 'get_vm_console_log_paths') - def setUp(self, mock_get_log_paths): + + _autospec_classes = [ + pathutils.PathUtils, + ] + + def setUp(self): super(SerialConsoleHandlerTestCase, self).setUp() - mock_get_log_paths.return_value = [mock.sentinel.log_path] + pathutils.PathUtils.return_value.mock_get_log_paths.return_value = [ + mock.sentinel.log_path] self._consolehandler = serialconsolehandler.SerialConsoleHandler( mock.sentinel.instance_name) self._consolehandler._log_path = mock.sentinel.log_path - self._consolehandler._pathutils = mock.Mock() self._consolehandler._vmutils = mock.Mock() @mock.patch.object(serialconsolehandler.SerialConsoleHandler, diff --git a/compute_hyperv/tests/unit/test_serialconsoleops.py b/compute_hyperv/tests/unit/test_serialconsoleops.py index 06ac80dc..c3900082 100644 --- a/compute_hyperv/tests/unit/test_serialconsoleops.py +++ b/compute_hyperv/tests/unit/test_serialconsoleops.py @@ -24,11 +24,15 @@ from compute_hyperv.tests.unit import test_base class SerialConsoleOpsTestCase(test_base.HyperVBaseTestCase): + + _autospec_classes = [ + serialconsoleops.pathutils.PathUtils, + ] + def setUp(self): super(SerialConsoleOpsTestCase, self).setUp() serialconsoleops._console_handlers = {} self._serialops = serialconsoleops.SerialConsoleOps() - self._serialops._pathutils = mock.MagicMock() self._serialops._vmutils = mock.MagicMock() self._vmutils = self._serialops._vmutils diff --git a/compute_hyperv/tests/unit/test_snapshotops.py b/compute_hyperv/tests/unit/test_snapshotops.py index 1a1af110..1146e602 100644 --- a/compute_hyperv/tests/unit/test_snapshotops.py +++ b/compute_hyperv/tests/unit/test_snapshotops.py @@ -26,12 +26,15 @@ from compute_hyperv.tests.unit import test_base class SnapshotOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V SnapshotOps class.""" + _autospec_classes = [ + snapshotops.pathutils.PathUtils, + ] + def setUp(self): super(SnapshotOpsTestCase, self).setUp() self.context = 'fake_context' self._snapshotops = snapshotops.SnapshotOps() - self._snapshotops._pathutils = mock.MagicMock() self._snapshotops._vmutils = mock.MagicMock() self._snapshotops._vhdutils = mock.MagicMock() diff --git a/compute_hyperv/tests/unit/test_vmops.py b/compute_hyperv/tests/unit/test_vmops.py index 3ab978d9..aa1b013b 100644 --- a/compute_hyperv/tests/unit/test_vmops.py +++ b/compute_hyperv/tests/unit/test_vmops.py @@ -29,12 +29,9 @@ from oslo_concurrency import processutils from oslo_utils import fileutils from oslo_utils import units -from compute_hyperv.nova import block_device_manager import compute_hyperv.nova.conf from compute_hyperv.nova import constants -from compute_hyperv.nova import pdk from compute_hyperv.nova import vmops -from compute_hyperv.nova import volumeops from compute_hyperv.tests import fake_instance from compute_hyperv.tests.unit import test_base @@ -45,6 +42,16 @@ CONF = compute_hyperv.nova.conf.CONF class VMOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V VMOps class.""" + _autospec_classes = [ + vmops.pathutils.PathUtils, + vmops.volumeops.VolumeOps, + vmops.imagecache.ImageCache, + vmops.serialconsoleops.SerialConsoleOps, + vmops.block_device_manager.BlockDeviceInfoManager, + vmops.vif_utils.HyperVVIFDriver, + vmops.pdk.PDK, + ] + _FAKE_TIMEOUT = 2 FAKE_SIZE = 10 FAKE_DIR = 'fake_dir' @@ -71,13 +78,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._vmutils = mock.MagicMock() self._vmops._metricsutils = mock.MagicMock() self._vmops._vhdutils = mock.MagicMock() - self._vmops._pathutils = mock.MagicMock() self._vmops._hostutils = mock.MagicMock() self._vmops._migrutils = mock.MagicMock() - self._vmops._pdk = mock.MagicMock() - self._vmops._serial_console_ops = mock.MagicMock() - self._vmops._block_dev_man = mock.MagicMock() - self._vmops._vif_driver = mock.MagicMock() self._pathutils = self._vmops._pathutils self._vmutils = self._vmops._vmutils @@ -168,13 +170,13 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_instance) @mock.patch('os.path.exists') - @mock.patch.object(vmops.imagecache.ImageCache, 'get_cached_image') - def _test_create_root_iso(self, mock_get_cached_image, - mock_os_path_exists, iso_already_exists=False): + def _test_create_root_iso(self, mock_os_path_exists, + iso_already_exists=False): mock_instance = fake_instance.fake_instance_obj(self.context) mock_get_root_vhd_path = self._vmops._pathutils.get_root_vhd_path mock_get_root_vhd_path.return_value = mock.sentinel.ROOT_ISO_PATH + mock_get_cached_image = self._vmops._imagecache.get_cached_image mock_get_cached_image.return_value = mock.sentinel.CACHED_ISO_PATH mock_os_path_exists.return_value = iso_already_exists @@ -212,14 +214,12 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): return mock_instance @mock.patch('os.path.exists') - @mock.patch('compute_hyperv.nova.imagecache.ImageCache.get_cached_image') - def _test_create_root_vhd_exception(self, mock_get_cached_image, - mock_os_path_exists, vhd_format): + def _test_create_root_vhd_exception(self, mock_os_path_exists, vhd_format): mock_instance = self._prepare_create_root_device_mocks( use_cow_images=False, vhd_format=vhd_format, vhd_size=(self.FAKE_SIZE + 1)) fake_vhd_path = self.FAKE_ROOT_PATH % vhd_format - mock_get_cached_image.return_value = fake_vhd_path + self._vmops._imagecache.get_cached_image.return_value = fake_vhd_path fake_root_path = self._vmops._pathutils.get_root_vhd_path.return_value mock_os_path_exists.return_value = False @@ -234,15 +234,13 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): fake_root_path) @mock.patch('os.path.exists') - @mock.patch('compute_hyperv.nova.imagecache.ImageCache.get_cached_image') - def _test_create_root_vhd_qcow(self, mock_get_cached_image, - mock_os_path_exists, vhd_format, + def _test_create_root_vhd_qcow(self, mock_os_path_exists, vhd_format, vhd_already_exists=False): mock_instance = self._prepare_create_root_device_mocks( use_cow_images=True, vhd_format=vhd_format, vhd_size=(self.FAKE_SIZE - 1)) fake_vhd_path = self.FAKE_ROOT_PATH % vhd_format - mock_get_cached_image.return_value = fake_vhd_path + self._vmops._imagecache.get_cached_image.return_value = fake_vhd_path mock_os_path_exists.return_value = vhd_already_exists fake_root_path = self._vmops._pathutils.get_root_vhd_path.return_value @@ -277,14 +275,14 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._vhdutils.resize_vhd.assert_not_called() @mock.patch('os.path.exists') - @mock.patch('compute_hyperv.nova.imagecache.ImageCache.get_cached_image') - def _test_create_root_vhd(self, mock_get_cached_image, mock_os_path_exists, + def _test_create_root_vhd(self, mock_os_path_exists, vhd_format, is_rescue_vhd=False, vhd_already_exists=False): mock_instance = self._prepare_create_root_device_mocks( use_cow_images=False, vhd_format=vhd_format, vhd_size=(self.FAKE_SIZE - 1)) fake_vhd_path = self.FAKE_ROOT_PATH % vhd_format + mock_get_cached_image = self._vmops._imagecache.get_cached_image mock_get_cached_image.return_value = fake_vhd_path rescue_image_id = ( mock.sentinel.rescue_image_id if is_rescue_vhd else None) @@ -494,10 +492,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): @mock.patch('compute_hyperv.nova.vmops.VMOps._delete_disk_files') @mock.patch('compute_hyperv.nova.vmops.VMOps._get_neutron_events', return_value=[]) - @mock.patch.object(block_device_manager.BlockDeviceInfoManager, - 'validate_and_update_bdi') - def _test_spawn(self, mock_validate_and_update_bdi, - mock_get_neutron_events, + def _test_spawn(self, mock_get_neutron_events, mock_delete_disk_files, mock_create_root_device, mock_create_ephemerals, mock_get_image_vm_gen, @@ -647,7 +642,6 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): @mock.patch.object(vmops.VMOps, '_requires_secure_boot') @mock.patch.object(vmops.VMOps, '_requires_certificate') @mock.patch.object(vmops.VMOps, '_get_instance_vnuma_config') - @mock.patch.object(vmops.volumeops.VolumeOps, 'attach_volumes') @mock.patch.object(vmops.VMOps, '_attach_root_device') @mock.patch.object(vmops.VMOps, 'configure_remotefx') @mock.patch.object(vmops.VMOps, '_get_image_serial_port_settings') @@ -658,7 +652,6 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_get_port_settings, mock_configure_remotefx, mock_attach_root_device, - mock_attach_volumes, mock_get_vnuma_config, mock_requires_certificate, mock_requires_secure_boot, @@ -700,7 +693,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self.context, mock_instance, root_device_info) mock_attach_ephemerals.assert_called_once_with(mock_instance.name, block_device_info['ephemerals']) - mock_attach_volumes.assert_called_once_with( + self._vmops._volumeops.attach_volumes.assert_called_once_with( self.context, block_device_info['block_device_mapping'], mock_instance) @@ -878,8 +871,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_instance, vnuma_enabled, nested_virt_enabled) self.assertEqual(expected_dyn_memory_ratio, response) - @mock.patch.object(vmops.volumeops.VolumeOps, 'attach_volume') - def test_attach_root_device_volume(self, mock_attach_volume): + def test_attach_root_device_volume(self): mock_instance = fake_instance.fake_instance_obj(self.context) root_device_info = {'type': constants.VOLUME, 'connection_info': mock.sentinel.CONN_INFO, @@ -888,7 +880,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): self._vmops._attach_root_device(self.context, mock_instance, root_device_info) - mock_attach_volume.assert_called_once_with( + self._vmops._volumeops.attach_volume.assert_called_once_with( self.context, root_device_info['connection_info'], mock_instance, disk_bus=root_device_info['disk_bus']) @@ -1185,7 +1177,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_get_configdrive_path.assert_has_calls( expected_get_configdrive_path_calls) mock_ConfigDriveBuilder.assert_called_with( - instance_md=mock_InstanceMetadata()) + instance_md=mock_InstanceMetadata.return_value) mock_make_drive = mock_ConfigDriveBuilder().__enter__().make_drive mock_make_drive.assert_called_once_with(path_iso) if not CONF.hyperv.config_drive_cdrom: @@ -1315,13 +1307,11 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): {'vm_exists': False, 'planned_vm_exists': False}, {'vm_exists': False, 'planned_vm_exists': True}) @ddt.unpack - @mock.patch('compute_hyperv.nova.volumeops.VolumeOps.disconnect_volumes') @mock.patch('compute_hyperv.nova.vmops.VMOps._delete_disk_files') @mock.patch('compute_hyperv.nova.vmops.VMOps.power_off') @mock.patch('compute_hyperv.nova.vmops.VMOps.unplug_vifs') def test_destroy(self, mock_unplug_vifs, mock_power_off, - mock_delete_disk_files, mock_disconnect_volumes, - vm_exists=True, + mock_delete_disk_files, vm_exists=True, planned_vm_exists=False): mock_instance = fake_instance.fake_instance_obj(self.context) self._vmops._vmutils.vm_exists.return_value = vm_exists @@ -1357,7 +1347,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_unplug_vifs.assert_called_once_with( mock_instance, mock.sentinel.fake_network_info) - mock_disconnect_volumes.assert_called_once_with( + self._vmops._volumeops.disconnect_volumes.assert_called_once_with( mock.sentinel.FAKE_BD_INFO) mock_delete_disk_files.assert_called_once_with( mock_instance, @@ -1547,15 +1537,14 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_set_vm_state.assert_called_once_with( mock_instance, os_win_const.HYPERV_VM_STATE_ENABLED) - @mock.patch('compute_hyperv.nova.volumeops.VolumeOps' - '.fix_instance_volume_disk_paths') @mock.patch('compute_hyperv.nova.vmops.VMOps._set_vm_state') - def test_power_on_having_block_devices(self, mock_set_vm_state, - mock_fix_instance_vol_paths): + def test_power_on_having_block_devices(self, mock_set_vm_state): mock_instance = fake_instance.fake_instance_obj(self.context) self._vmops.power_on(mock_instance, mock.sentinel.block_device_info) + mock_fix_instance_vol_paths = ( + self._vmops._volumeops.fix_instance_volume_disk_paths) mock_fix_instance_vol_paths.assert_called_once_with( mock_instance.name, mock.sentinel.block_device_info) mock_set_vm_state.assert_called_once_with( @@ -2042,13 +2031,11 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): (0, True), (0, False)) @ddt.unpack - @mock.patch.object(volumeops.VolumeOps, 'bytes_per_sec_to_iops') @mock.patch.object(vmops.VMOps, '_get_scoped_flavor_extra_specs') @mock.patch.object(vmops.VMOps, '_get_instance_local_disks') def test_set_instance_disk_qos_specs(self, total_iops_sec, is_resize, mock_get_local_disks, - mock_get_scoped_specs, - mock_bytes_per_sec_to_iops): + mock_get_scoped_specs): fake_total_bytes_sec = 8 mock_instance = fake_instance.fake_instance_obj(self.context) mock_local_disks = [mock.sentinel.root_vhd_path, @@ -2058,6 +2045,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): mock_set_qos_specs = self._vmops._vmutils.set_disk_qos_specs mock_get_scoped_specs.return_value = dict( disk_total_bytes_sec=fake_total_bytes_sec) + mock_bytes_per_sec_to_iops = ( + self._vmops._volumeops.bytes_per_sec_to_iops) mock_bytes_per_sec_to_iops.return_value = total_iops_sec self._vmops._set_instance_disk_qos_specs(mock_instance, is_resize) @@ -2155,8 +2144,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase): @mock.patch.object(vmops.VMOps, '_check_vtpm_requirements') @mock.patch.object(vmops.VMOps, '_feature_requested') @mock.patch.object(vmops.VMOps, '_create_fsk') - @mock.patch.object(pdk.PDK, 'create_pdk') - def _test_configure_secure_vm(self, mock_create_pdk, mock_create_fsk, + def _test_configure_secure_vm(self, mock_create_fsk, mock_feature_requested, mock_check_vtpm_requirements, requires_shielded, requires_encryption): diff --git a/compute_hyperv/tests/unit/test_volumeops.py b/compute_hyperv/tests/unit/test_volumeops.py index e3084337..f0cf8415 100644 --- a/compute_hyperv/tests/unit/test_volumeops.py +++ b/compute_hyperv/tests/unit/test_volumeops.py @@ -62,12 +62,15 @@ def get_fake_connection_info(**kwargs): class VolumeOpsTestCase(test_base.HyperVBaseTestCase): """Unit tests for VolumeOps class.""" + _autospec_classes = [ + volumeops.cinder.API, + ] + def setUp(self): super(VolumeOpsTestCase, self).setUp() self._volumeops = volumeops.VolumeOps() self._volumeops._volutils = mock.MagicMock() self._volumeops._vmutils = mock.Mock() - self._volumeops._volume_api = mock.Mock() self._volume_api = self._volumeops._volume_api def test_get_volume_driver(self): @@ -854,6 +857,10 @@ class ISCSIVolumeDriverTestCase(test_base.HyperVBaseTestCase): class SMBFSVolumeDriverTestCase(test_base.HyperVBaseTestCase): """Unit tests for the Hyper-V SMBFSVolumeDriver class.""" + _autospec_classes = [ + volumeops.pathutils.PathUtils, + ] + _FAKE_EXPORT_PATH = '//ip/share/' _FAKE_CONN_INFO = get_fake_connection_info(export=_FAKE_EXPORT_PATH) @@ -861,7 +868,6 @@ class SMBFSVolumeDriverTestCase(test_base.HyperVBaseTestCase): super(SMBFSVolumeDriverTestCase, self).setUp() self._volume_driver = volumeops.SMBFSVolumeDriver() self._volume_driver._conn = mock.Mock() - self._volume_driver._pathutils = mock.Mock() self._volume_driver._vmutils = mock.Mock() self._volume_driver._vhdutils = mock.Mock() self._conn = self._volume_driver._conn