From 07dd90cf86b91099dd7e709e4f5d3639ab3933b4 Mon Sep 17 00:00:00 2001 From: git-harry Date: Mon, 8 Sep 2014 16:30:03 +0100 Subject: [PATCH] Remove Mock class monkey patching Replace use of Mock with Mock(). The Mock class was being modified and so affecting other tests where Mock is used. An instance of the Mock class is now used to keep the tests isolated. Change-Id: Iccab8430d5814258c8c2d1f9af015bce999549bc Closes-Bug: #1286245 --- cinder/tests/test_backup_ceph.py | 184 +++++++++++++------------------ cinder/tests/test_rbd.py | 169 ++++++++++++---------------- 2 files changed, 151 insertions(+), 202 deletions(-) diff --git a/cinder/tests/test_backup_ceph.py b/cinder/tests/test_backup_ceph.py index 75fc6cc11..293b14546 100644 --- a/cinder/tests/test_backup_ceph.py +++ b/cinder/tests/test_backup_ceph.py @@ -77,8 +77,8 @@ def common_mocks(f): @mock.patch('time.time', spec=True) # NOTE(dosaboy): set spec to empty object so that hasattr calls return # False by default. - @mock.patch('cinder.backup.drivers.ceph.rbd', spec=object) - @mock.patch('cinder.backup.drivers.ceph.rados', spec=object) + @mock.patch('cinder.backup.drivers.ceph.rbd') + @mock.patch('cinder.backup.drivers.ceph.rados') def _common_inner_inner2(mock_rados, mock_rbd, mock_time, mock_sleep, mock_popen): mock_time.side_effect = inst.time_inc @@ -86,11 +86,6 @@ def common_mocks(f): inst.mock_rados = mock_rados inst.mock_rbd = mock_rbd - inst.mock_rados.Rados = mock.Mock - inst.mock_rados.Rados.ioctx = mock.Mock() - inst.mock_rbd.RBD = mock.Mock - inst.mock_rbd.Image = mock.Mock - inst.mock_rbd.Image.close = mock.Mock() inst.mock_rbd.ImageBusy = MockImageBusyException inst.mock_rbd.ImageNotFound = MockImageNotFoundException @@ -201,6 +196,8 @@ class BackupCephTestCase(test.TestCase): @common_mocks def test_get_rbd_support(self): + del self.service.rbd.RBD_FEATURE_LAYERING + del self.service.rbd.RBD_FEATURE_STRIPINGV2 self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_LAYERING')) self.assertFalse(hasattr(self.service.rbd, 'RBD_FEATURE_STRIPINGV2')) @@ -224,14 +221,14 @@ class BackupCephTestCase(test.TestCase): def test_get_most_recent_snap(self): last = 'backup.%s.snap.9824923.1212' % (uuid.uuid4()) - self.mock_rbd.Image.list_snaps = mock.Mock() - self.mock_rbd.Image.list_snaps.return_value = \ + image = self.mock_rbd.Image.return_value + image.list_snaps.return_value = \ [{'name': 'backup.%s.snap.6423868.2342' % (uuid.uuid4())}, {'name': 'backup.%s.snap.1321319.3235' % (uuid.uuid4())}, {'name': last}, {'name': 'backup.%s.snap.3824923.1412' % (uuid.uuid4())}] - snap = self.service._get_most_recent_snap(self.service.rbd.Image()) + snap = self.service._get_most_recent_snap(image) self.assertEqual(last, snap) @common_mocks @@ -261,21 +258,24 @@ class BackupCephTestCase(test.TestCase): @common_mocks def test_get_backup_snaps(self): - self.mock_rbd.Image.list_snaps = mock.Mock() - self.mock_rbd.Image.list_snaps.return_value = \ - [{'name': 'backup.%s.snap.6423868.2342' % (uuid.uuid4())}, - {'name': 'backup.%s.wambam.6423868.2342' % (uuid.uuid4())}, - {'name': 'backup.%s.snap.1321319.3235' % (uuid.uuid4())}, - {'name': 'bbbackup.%s.snap.1321319.3235' % (uuid.uuid4())}, - {'name': 'backup.%s.snap.3824923.1412' % (uuid.uuid4())}] - snaps = self.service.get_backup_snaps(self.service.rbd.Image()) + image = self.mock_rbd.Image.return_value + image.list_snaps.return_value = [ + {'name': 'backup.%s.snap.6423868.2342' % (uuid.uuid4())}, + {'name': 'backup.%s.wambam.6423868.2342' % (uuid.uuid4())}, + {'name': 'backup.%s.snap.1321319.3235' % (uuid.uuid4())}, + {'name': 'bbbackup.%s.snap.1321319.3235' % (uuid.uuid4())}, + {'name': 'backup.%s.snap.3824923.1412' % (uuid.uuid4())}] + snaps = self.service.get_backup_snaps(image) self.assertEqual(len(snaps), 3) @common_mocks def test_transfer_data_from_rbd_to_file(self): - self.mock_rbd.Image.read = mock.Mock() - self.mock_rbd.Image.read.return_value = \ - self.volume_file.read(self.data_length) + def fake_read(offset, length): + self.volume_file.seek(offset) + return self.volume_file.read(length) + + self.mock_rbd.Image.return_value.read.side_effect = fake_read + self.mock_rbd.Image.return_value.size.return_value = self.data_length with tempfile.NamedTemporaryFile() as test_file: self.volume_file.seek(0) @@ -294,29 +294,24 @@ class BackupCephTestCase(test.TestCase): @common_mocks def test_transfer_data_from_rbd_to_rbd(self): + def fake_read(offset, length): + self.volume_file.seek(offset) + return self.volume_file.read(length) def mock_write_data(data, offset): checksum.update(data) test_file.write(data) - self.mock_rbd.Image.read = mock.Mock() - self.mock_rbd.Image.read.return_value = \ - self.volume_file.read(self.data_length) + rbd1 = mock.Mock() + rbd1.read.side_effect = fake_read - self.mock_rbd.Image.size = mock.Mock() - self.mock_rbd.Image.size.return_value = \ - self.chunk_size * self.num_chunks - - self.mock_rbd.Image.write = mock.Mock() - self.mock_rbd.Image.write.side_effect = mock_write_data + rbd2 = mock.Mock() + rbd2.write.side_effect = mock_write_data with tempfile.NamedTemporaryFile() as test_file: self.volume_file.seek(0) checksum = hashlib.sha256() - rbd1 = self.service.rbd.Image() - rbd2 = self.service.rbd.Image() - src_rbd_io = self._get_wrapped_rbd_io(rbd1) dest_rbd_io = self._get_wrapped_rbd_io(rbd2) self.service._transfer_data(src_rbd_io, 'src_foo', dest_rbd_io, @@ -332,8 +327,7 @@ class BackupCephTestCase(test.TestCase): checksum.update(data) test_file.write(data) - self.mock_rbd.Image.write = mock.Mock() - self.mock_rbd.Image.write.side_effect = mock_write_data + self.mock_rbd.Image.return_value.write.side_effect = mock_write_data with tempfile.NamedTemporaryFile() as test_file: self.volume_file.seek(0) @@ -371,8 +365,7 @@ class BackupCephTestCase(test.TestCase): checksum.update(data) test_file.write(data) - self.service.rbd.Image.write = mock.Mock() - self.service.rbd.Image.write.side_effect = mock_write_data + self.service.rbd.Image.return_value.write.side_effect = mock_write_data with mock.patch.object(self.service, '_backup_metadata'): with mock.patch.object(self.service, '_discard_bytes'): @@ -382,7 +375,7 @@ class BackupCephTestCase(test.TestCase): # Ensure the files are equal self.assertEqual(checksum.digest(), self.checksum.digest()) - self.assertTrue(self.service.rbd.Image.write.called) + self.assertTrue(self.service.rbd.Image.return_value.write.called) @common_mocks def test_get_backup_base_name(self): @@ -614,17 +607,14 @@ class BackupCephTestCase(test.TestCase): backup_name = self.service._get_backup_base_name(self.backup_id, diff_format=True) - self.mock_rbd.RBD.list = mock.Mock() - self.mock_rbd.RBD.list.return_value = [backup_name] + self.mock_rbd.RBD.return_value.list.return_value = [backup_name] def mock_read_data(offset, length): return self.volume_file.read(self.data_length) - self.mock_rbd.Image.read = mock.Mock() - self.mock_rbd.Image.read.side_effect = mock_read_data + self.mock_rbd.Image.return_value.read.side_effect = mock_read_data - self.mock_rbd.Image.size = mock.Mock() - self.mock_rbd.Image.size.return_value = \ + self.mock_rbd.Image.return_value.size.return_value = \ self.chunk_size * self.num_chunks with mock.patch.object(self.service, '_restore_metadata') as \ @@ -649,22 +639,19 @@ class BackupCephTestCase(test.TestCase): self.assertTrue(mock_discard_bytes.called) self.assertTrue(mock_discard_bytes.called) - self.assertTrue(self.service.rbd.Image.read.called) + self.assertTrue(self.service.rbd.Image.return_value.read.called) @common_mocks def test_discard_bytes(self): - self.mock_rbd.Image.discard = mock.Mock() - wrapped_rbd = self._get_wrapped_rbd_io(self.mock_rbd.Image()) + image = self.mock_rbd.Image.return_value + wrapped_rbd = self._get_wrapped_rbd_io(image) self.service._discard_bytes(wrapped_rbd, 0, 0) - self.assertEqual(self.mock_rbd.Image.discard.call_count, 0) + self.assertEqual(image.discard.call_count, 0) self.service._discard_bytes(wrapped_rbd, 0, 1234) - self.assertEqual(self.mock_rbd.Image.discard.call_count, 1) - self.mock_rbd.Image.discard.reset_mock() - - self.mock_rbd.Image.write = mock.Mock() - self.mock_rbd.Image.flush = mock.Mock() + self.assertEqual(image.discard.call_count, 1) + image.reset_mock() # Test discard with no remainder with mock.patch.object(self.service, '_file_is_rbd') as \ @@ -674,13 +661,11 @@ class BackupCephTestCase(test.TestCase): self.service._discard_bytes(wrapped_rbd, 0, self.service.chunk_size * 2) - self.assertEqual(self.mock_rbd.Image.write.call_count, 2) - self.assertEqual(self.mock_rbd.Image.flush.call_count, 2) - self.assertFalse(self.mock_rbd.Image.discard.called) + self.assertEqual(image.write.call_count, 2) + self.assertEqual(image.flush.call_count, 2) + self.assertFalse(image.discard.called) - self.mock_rbd.Image.write.reset_mock() - self.mock_rbd.Image.flush.reset_mock() - self.mock_rbd.Image.discard.reset_mock() + image.reset_mock() # Now test with a remainder. with mock.patch.object(self.service, '_file_is_rbd') as \ @@ -690,9 +675,9 @@ class BackupCephTestCase(test.TestCase): self.service._discard_bytes(wrapped_rbd, 0, (self.service.chunk_size * 2) + 1) - self.assertEqual(self.mock_rbd.Image.write.call_count, 3) - self.assertEqual(self.mock_rbd.Image.flush.call_count, 3) - self.assertFalse(self.mock_rbd.Image.discard.called) + self.assertEqual(image.write.call_count, 3) + self.assertEqual(image.flush.call_count, 3) + self.assertFalse(image.discard.called) @common_mocks def test_delete_backup_snapshot(self): @@ -721,9 +706,7 @@ class BackupCephTestCase(test.TestCase): backup_name = self.service._get_backup_base_name(self.volume_id, diff_format=True) - self.mock_rbd.RBD.list = mock.Mock() - self.mock_rbd.RBD.list.return_value = [backup_name] - self.mock_rbd.RBD.remove = mock.Mock() + self.mock_rbd.RBD.return_value.list.return_value = [backup_name] with mock.patch.object(self.service, '_delete_backup_snapshot') as \ mock_del_backup_snap: @@ -734,8 +717,8 @@ class BackupCephTestCase(test.TestCase): self.assertTrue(mock_del_backup_snap.called) #self.assertFalse(self.mock_rbd.ImageNotFound.called) - self.assertTrue(self.mock_rbd.RBD.list.called) - self.assertTrue(self.mock_rbd.RBD.remove.called) + self.assertTrue(self.mock_rbd.RBD.return_value.list.called) + self.assertTrue(self.mock_rbd.RBD.return_value.remove.called) @common_mocks @mock.patch('cinder.backup.drivers.ceph.VolumeMetadataBackup', spec=True) @@ -743,13 +726,11 @@ class BackupCephTestCase(test.TestCase): backup_name = self.service._get_backup_base_name(self.volume_id, self.backup_id) - self.mock_rbd.RBD.list = mock.Mock() - self.mock_rbd.RBD.list.return_value = [backup_name] - self.mock_rbd.RBD.remove = mock.Mock() + self.mock_rbd.RBD.return_value.list.return_value = [backup_name] with mock.patch.object(self.service, 'get_backup_snaps'): self.service.delete(self.backup) - self.assertTrue(self.mock_rbd.RBD.remove.called) + self.assertTrue(self.mock_rbd.RBD.return_value.remove.called) @common_mocks def test_try_delete_base_image_busy(self): @@ -757,10 +738,9 @@ class BackupCephTestCase(test.TestCase): backup_name = self.service._get_backup_base_name(self.volume_id, self.backup_id) - self.mock_rbd.RBD.list = mock.Mock() - self.mock_rbd.RBD.list.return_value = [backup_name] - self.mock_rbd.RBD.remove = mock.Mock() - self.mock_rbd.RBD.remove.side_effect = self.mock_rbd.ImageBusy + rbd = self.mock_rbd.RBD.return_value + rbd.list.return_value = [backup_name] + rbd.remove.side_effect = self.mock_rbd.ImageBusy with mock.patch.object(self.service, 'get_backup_snaps') as \ mock_get_backup_snaps: @@ -769,8 +749,8 @@ class BackupCephTestCase(test.TestCase): self.backup['id'], self.backup['volume_id']) self.assertTrue(mock_get_backup_snaps.called) - self.assertTrue(self.mock_rbd.RBD.list.called) - self.assertTrue(self.mock_rbd.RBD.remove.called) + self.assertTrue(rbd.list.called) + self.assertTrue(rbd.remove.called) self.assertTrue(MockImageBusyException in RAISED_EXCEPTIONS) @common_mocks @@ -940,15 +920,12 @@ class BackupCephTestCase(test.TestCase): glance_tag: {'image_name': 'image.glance'}, 'version': version}) - self.mock_rados.Object = mock.Mock - self.mock_rados.Object.read = mock.Mock() - self.mock_rados.Object.read.side_effect = mock_read - self.mock_rados.Object.stat = mock.Mock() + self.mock_rados.Object.return_value.read.side_effect = mock_read self.service._restore_metadata(self.backup, self.volume_id) - self.assertTrue(self.mock_rados.Object.stat.called) - self.assertTrue(self.mock_rados.Object.read.called) + self.assertTrue(self.mock_rados.Object.return_value.stat.called) + self.assertTrue(self.mock_rados.Object.return_value.read.called) version = 2 try: @@ -1019,9 +996,7 @@ class BackupCephTestCase(test.TestCase): glance_tag: {'image_name': 'image.glance'}, 'version': 2}) - self.mock_rados.Object = mock.Mock - self.mock_rados.Object.read = mock.Mock() - self.mock_rados.Object.read.side_effect = mock_read + self.mock_rados.Object.return_value.read.side_effect = mock_read with mock.patch.object(ceph.VolumeMetadataBackup, '_exists') as \ mock_exists: mock_exists.return_value = True @@ -1032,7 +1007,7 @@ class BackupCephTestCase(test.TestCase): self.assertTrue(mock_exists.called) - self.assertTrue(self.mock_rados.Object.read.called) + self.assertTrue(self.mock_rados.Object.return_value.read.called) def common_meta_backup_mocks(f): @@ -1042,12 +1017,11 @@ def common_meta_backup_mocks(f): mocks that can't/don't get unset. """ def _common_inner_inner1(inst, *args, **kwargs): - @mock.patch('cinder.backup.drivers.ceph.rbd', spec=object) - @mock.patch('cinder.backup.drivers.ceph.rados', spec=object) + @mock.patch('cinder.backup.drivers.ceph.rbd') + @mock.patch('cinder.backup.drivers.ceph.rados') def _common_inner_inner2(mock_rados, mock_rbd): inst.mock_rados = mock_rados inst.mock_rbd = mock_rbd - inst.mock_rados.Object = mock.Mock inst.mock_rados.ObjectNotFound = MockObjectNotFoundException return f(inst, *args, **kwargs) @@ -1071,16 +1045,16 @@ class VolumeMetadataBackupTestCase(test.TestCase): @common_meta_backup_mocks def test_exists(self): # True - with mock.patch.object(self.mock_rados.Object, 'stat') as mock_stat: - self.assertTrue(self.mb.exists) - self.assertTrue(mock_stat.called) + self.assertTrue(self.mb.exists) + self.assertTrue(self.mock_rados.Object.return_value.stat.called) + self.mock_rados.Object.return_value.reset_mock() # False - with mock.patch.object(self.mock_rados.Object, 'stat') as mock_stat: - mock_stat.side_effect = self.mock_rados.ObjectNotFound - self.assertFalse(self.mb.exists) - self.assertTrue(mock_stat.called) - self.assertEqual(RAISED_EXCEPTIONS, [MockObjectNotFoundException]) + self.mock_rados.Object.return_value.stat.side_effect = ( + self.mock_rados.ObjectNotFound) + self.assertFalse(self.mb.exists) + self.assertTrue(self.mock_rados.Object.return_value.stat.called) + self.assertEqual(RAISED_EXCEPTIONS, [MockObjectNotFoundException]) @common_meta_backup_mocks def test_set(self): @@ -1120,14 +1094,12 @@ class VolumeMetadataBackupTestCase(test.TestCase): @common_meta_backup_mocks def test_get(self): - with mock.patch.object(self.mock_rados.Object, 'stat') as mock_stat: - mock_stat.side_effect = self.mock_rados.ObjectNotFound - with mock.patch.object(self.mock_rados.Object, 'read') as \ - mock_read: - mock_read.return_value = 'meta' - self.assertIsNone(self.mb.get()) - mock_stat.side_effect = None - self.assertEqual(self.mb.get(), 'meta') + self.mock_rados.Object.return_value.stat.side_effect = ( + self.mock_rados.ObjectNotFound) + self.mock_rados.Object.return_value.read.return_value = 'meta' + self.assertIsNone(self.mb.get()) + self.mock_rados.Object.return_value.stat.side_effect = None + self.assertEqual(self.mb.get(), 'meta') @common_meta_backup_mocks def remove_if_exists(self): diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py index 99cdfd724..5aa716d35 100644 --- a/cinder/tests/test_rbd.py +++ b/cinder/tests/test_rbd.py @@ -81,11 +81,6 @@ def common_mocks(f): inst.mock_rados = mock_rados inst.mock_client = mock_client inst.mock_proxy = mock_proxy - inst.mock_rados.Rados = mock.Mock - inst.mock_rados.Rados.ioctx = mock.Mock() - inst.mock_rbd.RBD = mock.Mock - inst.mock_rbd.Image = mock.Mock - inst.mock_rbd.Image.close = mock.Mock() inst.mock_rbd.RBD.Error = Exception inst.mock_rados.Error = Exception inst.mock_rbd.ImageBusy = MockImageBusyException @@ -167,7 +162,6 @@ class RBDTestCase(test.TestCase): with mock.patch.object(self.driver, '_supports_layering') as \ mock_supports_layering: mock_supports_layering.return_value = True - self.mock_rbd.RBD.create = mock.Mock() self.driver.create_volume(self.volume) @@ -177,16 +171,17 @@ class RBDTestCase(test.TestCase): self.volume_size * units.Gi, order] kwargs = {'old_format': False, 'features': self.mock_rbd.RBD_FEATURE_LAYERING} - self.mock_rbd.RBD.create.assert_called_once_with(*args, **kwargs) + self.mock_rbd.RBD.return_value.create.assert_called_once_with( + *args, **kwargs) client.__enter__.assert_called_once() client.__exit__.assert_called_once() mock_supports_layering.assert_called_once() @common_mocks def test_manage_existing_get_size(self): - with mock.patch.object(self.driver.rbd.Image, 'size') as \ + with mock.patch.object(self.driver.rbd.Image(), 'size') as \ mock_rbd_image_size: - with mock.patch.object(self.driver.rbd.Image, 'close') \ + with mock.patch.object(self.driver.rbd.Image(), 'close') \ as mock_rbd_image_close: mock_rbd_image_size.return_value = 2 * units.Gi existing_ref = {'source-name': self.volume_name} @@ -200,9 +195,9 @@ class RBDTestCase(test.TestCase): @common_mocks def test_manage_existing_get_invalid_size(self): - with mock.patch.object(self.driver.rbd.Image, 'size') as \ + with mock.patch.object(self.driver.rbd.Image(), 'size') as \ mock_rbd_image_size: - with mock.patch.object(self.driver.rbd.Image, 'close') \ + with mock.patch.object(self.driver.rbd.Image(), 'close') \ as mock_rbd_image_close: mock_rbd_image_size.return_value = 'abcd' existing_ref = {'source-name': self.volume_name} @@ -218,29 +213,24 @@ class RBDTestCase(test.TestCase): client = self.mock_client.return_value client.__enter__.return_value = client - with mock.patch.object(driver, 'RADOSClient') as mock_rados_client: - with mock.patch.object(self.driver.rbd.RBD(), 'rename') as \ - mock_rbd_image_rename: - exist_volume = 'vol-exist' - existing_ref = {'source-name': exist_volume} - mock_rbd_image_rename.return_value = 0 - mock_rbd_image_rename(mock_rados_client.ioctx, - exist_volume, - self.volume_name) - self.driver.manage_existing(self.volume, existing_ref) - mock_rbd_image_rename.assert_called_with( - mock_rados_client.ioctx, - exist_volume, - self.volume_name) + with mock.patch.object(self.driver.rbd.RBD(), 'rename') as \ + mock_rbd_image_rename: + exist_volume = 'vol-exist' + existing_ref = {'source-name': exist_volume} + mock_rbd_image_rename.return_value = 0 + self.driver.manage_existing(self.volume, existing_ref) + mock_rbd_image_rename.assert_called_with( + client.ioctx, + exist_volume, + self.volume_name) @common_mocks def test_manage_existing_with_exist_rbd_image(self): client = self.mock_client.return_value client.__enter__.return_value = client - self.mock_rbd.Image.rename = mock.Mock() - self.mock_rbd.Image.rename.side_effect = \ - MockImageExistsException + self.mock_rbd.RBD.return_value.rename.side_effect = ( + MockImageExistsException) exist_volume = 'vol-exist' existing_ref = {'source-name': exist_volume} @@ -260,7 +250,6 @@ class RBDTestCase(test.TestCase): with mock.patch.object(self.driver, '_supports_layering') as \ mock_supports_layering: mock_supports_layering.return_value = False - self.mock_rbd.RBD.create = mock.Mock() self.driver.create_volume(self.volume) @@ -270,7 +259,8 @@ class RBDTestCase(test.TestCase): self.volume_size * units.Gi, order] kwargs = {'old_format': True, 'features': 0} - self.mock_rbd.RBD.create.assert_called_once_with(*args, **kwargs) + self.mock_rbd.RBD.return_value.create.assert_called_once_with( + *args, **kwargs) client.__enter__.assert_called_once() client.__exit__.assert_called_once() mock_supports_layering.assert_called_once() @@ -284,17 +274,14 @@ class RBDTestCase(test.TestCase): rbd_image = self.driver.rbd.Image() self.driver._delete_backup_snaps(rbd_image) mock_get_backup_snaps.assert_called_once_with(rbd_image) - self.assertTrue(self.driver.rbd.Image.remove_snap.called) + self.assertTrue( + self.driver.rbd.Image.return_value.remove_snap.called) @common_mocks def test_delete_volume(self): client = self.mock_client.return_value - self.driver.rbd.Image.list_snaps = mock.Mock() - self.driver.rbd.Image.list_snaps.return_value = [] - self.driver.rbd.Image.close = mock.Mock() - self.driver.rbd.Image.remove = mock.Mock() - self.driver.rbd.Image.unprotect_snap = mock.Mock() + self.driver.rbd.Image.return_value.list_snaps.return_value = [] with mock.patch.object(self.driver, '_get_clone_info') as \ mock_get_clone_info: @@ -305,12 +292,14 @@ class RBDTestCase(test.TestCase): self.driver.delete_volume(self.volume) mock_get_clone_info.assert_called_once() - self.driver.rbd.Image.list_snaps.assert_called_once() + (self.driver.rbd.Image.return_value + .list_snaps.assert_called_once()) client.__enter__.assert_called_once() client.__exit__.assert_called_once() mock_delete_backup_snaps.assert_called_once() - self.assertFalse(self.driver.rbd.Image.unprotect_snap.called) - self.driver.rbd.RBD.remove.assert_called_once() + self.assertFalse( + self.driver.rbd.Image.return_value.unprotect_snap.called) + self.driver.rbd.RBD.return_value.remove.assert_called_once() @common_mocks def delete_volume_not_found(self): @@ -322,12 +311,10 @@ class RBDTestCase(test.TestCase): @common_mocks def test_delete_busy_volume(self): - self.mock_rbd.Image.list_snaps = mock.Mock() - self.mock_rbd.Image.list_snaps.return_value = [] - self.mock_rbd.Image.unprotect_snap = mock.Mock() + self.mock_rbd.Image.return_value.list_snaps.return_value = [] - self.mock_rbd.RBD.remove = mock.Mock() - self.mock_rbd.RBD.remove.side_effect = self.mock_rbd.ImageBusy + self.mock_rbd.RBD.return_value.remove.side_effect = ( + self.mock_rbd.ImageBusy) with mock.patch.object(self.driver, '_get_clone_info') as \ mock_get_clone_info: @@ -340,11 +327,13 @@ class RBDTestCase(test.TestCase): self.driver.delete_volume, self.volume) mock_get_clone_info.assert_called_once() - self.mock_rbd.Image.list_snaps.assert_called_once() + (self.mock_rbd.Image.return_value.list_snaps + .assert_called_once()) mock_rados_client.assert_called_once() mock_delete_backup_snaps.assert_called_once() - self.assertFalse(self.mock_rbd.Image.unprotect_snap.called) - self.mock_rbd.RBD.remove.assert_called_once() + self.assertFalse( + self.mock_rbd.Image.return_value.unprotect_snap.called) + self.mock_rbd.RBD.return_value.remove.assert_called_once() # Make sure the exception was raised self.assertEqual(RAISED_EXCEPTIONS, [self.mock_rbd.ImageBusy]) @@ -473,30 +462,25 @@ class RBDTestCase(test.TestCase): dst_name = u'volume-00000002' self.cfg.rbd_max_clone_depth = 1 - self.mock_rbd.RBD.clone = mock.Mock() - self.mock_rbd.RBD.clone.side_effect = self.mock_rbd.RBD.Error + self.mock_rbd.RBD.return_value.clone.side_effect = ( + self.mock_rbd.RBD.Error) with mock.patch.object(self.driver, '_get_clone_depth') as \ mock_get_clone_depth: # Try with no flatten required mock_get_clone_depth.return_value = 1 - self.mock_rbd.Image.create_snap = mock.Mock() - self.mock_rbd.Image.protect_snap = mock.Mock() - self.mock_rbd.Image.unprotect_snap = mock.Mock() - self.mock_rbd.Image.remove_snap = mock.Mock() - self.mock_rbd.Image.close = mock.Mock() - self.assertRaises(self.mock_rbd.RBD.Error, self.driver.create_cloned_volume, dict(name=dst_name), dict(name=src_name)) - self.mock_rbd.Image.create_snap.assert_called_once() - self.mock_rbd.Image.protect_snap.assert_called_once() - self.mock_rbd.RBD.clone.assert_called_once() - self.mock_rbd.Image.unprotect_snap.assert_called_once() - self.mock_rbd.Image.remove_snap.assert_called_once() - self.mock_rbd.Image.close.assert_called_once() + self.mock_rbd.Image.return_value.create_snap.assert_called_once() + self.mock_rbd.Image.return_value.protect_snap.assert_called_once() + self.mock_rbd.RBD.return_value.clone.assert_called_once() + (self.mock_rbd.Image.return_value + .unprotect_snap.assert_called_once()) + self.mock_rbd.Image.return_value.remove_snap.assert_called_once() + self.mock_rbd.Image.return_value.close.assert_called_once() self.assertTrue(mock_get_clone_depth.called) @common_mocks @@ -505,19 +489,13 @@ class RBDTestCase(test.TestCase): dst_name = u'volume-00000002' self.cfg.rbd_max_clone_depth = 2 - self.mock_rbd.RBD.clone = mock.Mock() - self.mock_rbd.RBD.clone.side_effect = self.mock_rbd.RBD.Error + self.mock_rbd.RBD.return_value.clone.side_effect = ( + self.mock_rbd.RBD.Error) with mock.patch.object(self.driver, '_get_clone_depth') as \ mock_get_clone_depth: # Try with no flatten required mock_get_clone_depth.return_value = 1 - self.mock_rbd.Image.create_snap = mock.Mock() - self.mock_rbd.Image.protect_snap = mock.Mock() - self.mock_rbd.Image.unprotect_snap = mock.Mock() - self.mock_rbd.Image.remove_snap = mock.Mock() - self.mock_rbd.Image.close = mock.Mock() - self.assertRaises(self.mock_rbd.RBD.Error, self.driver.create_cloned_volume, dict(name=dst_name), dict(name=src_name)) @@ -575,7 +553,8 @@ class RBDTestCase(test.TestCase): mock_get_fsid.return_value = 'abc' location = 'rbd://abc/pool/image/snap' - self.mock_proxy.side_effect = self.mock_rbd.Error + self.driver.rbd.Error = Exception + self.mock_proxy.side_effect = Exception args = [location, {'disk_format': 'raw'}] self.assertFalse(self.driver._is_cloneable(*args)) @@ -717,14 +696,13 @@ class RBDTestCase(test.TestCase): # capture both rados client used to perform the clone client.__enter__.side_effect = mock__enter__(client) - self.mock_rbd.RBD.clone = mock.Mock() - self.driver._clone(self.volume, src_pool, src_image, src_snap) args = [client_stack[0].ioctx, str(src_image), str(src_snap), client_stack[1].ioctx, str(self.volume_name)] kwargs = {'features': self.mock_rbd.RBD_FEATURE_LAYERING} - self.mock_rbd.RBD.clone.assert_called_once_with(*args, **kwargs) + self.mock_rbd.RBD.return_value.clone.assert_called_once_with( + *args, **kwargs) self.assertEqual(client.__enter__.call_count, 2) @common_mocks @@ -778,44 +756,43 @@ class RBDTestCase(test.TestCase): # Default self.cfg.rados_connect_timeout = -1 - self.mock_rados.Rados.connect = mock.Mock() - self.mock_rados.Rados.shutdown = mock.Mock() - self.mock_rados.Rados.open_ioctx = mock.Mock() - self.mock_rados.Rados.open_ioctx.return_value = \ - self.mock_rados.Rados.ioctx + self.mock_rados.Rados.return_value.open_ioctx.return_value = \ + self.mock_rados.Rados.return_value.ioctx # default configured pool ret = self.driver._connect_to_rados() - self.assertTrue(self.mock_rados.Rados.connect.called) + self.assertTrue(self.mock_rados.Rados.return_value.connect.called) # Expect no timeout if default is used - self.mock_rados.Rados.connect.assert_called_once_with() - self.assertTrue(self.mock_rados.Rados.open_ioctx.called) - self.assertIsInstance(ret[0], self.mock_rados.Rados) - self.assertEqual(ret[1], self.mock_rados.Rados.ioctx) - self.mock_rados.Rados.open_ioctx.assert_called_with(self.cfg.rbd_pool) + self.mock_rados.Rados.return_value.connect.assert_called_once_with() + self.assertTrue(self.mock_rados.Rados.return_value.open_ioctx.called) + self.assertEqual(ret[1], self.mock_rados.Rados.return_value.ioctx) + self.mock_rados.Rados.return_value.open_ioctx.assert_called_with( + self.cfg.rbd_pool) # different pool ret = self.driver._connect_to_rados('alt_pool') - self.assertTrue(self.mock_rados.Rados.connect.called) - self.assertTrue(self.mock_rados.Rados.open_ioctx.called) - self.assertIsInstance(ret[0], self.mock_rados.Rados) - self.assertEqual(ret[1], self.mock_rados.Rados.ioctx) - self.mock_rados.Rados.open_ioctx.assert_called_with('alt_pool') + self.assertTrue(self.mock_rados.Rados.return_value.connect.called) + self.assertTrue(self.mock_rados.Rados.return_value.open_ioctx.called) + self.assertEqual(ret[1], self.mock_rados.Rados.return_value.ioctx) + self.mock_rados.Rados.return_value.open_ioctx.assert_called_with( + 'alt_pool') # With timeout self.cfg.rados_connect_timeout = 1 - self.mock_rados.Rados.connect.reset_mock() + self.mock_rados.Rados.return_value.connect.reset_mock() self.driver._connect_to_rados() - self.mock_rados.Rados.connect.assert_called_once_with(timeout=1) + self.mock_rados.Rados.return_value.connect.assert_called_once_with( + timeout=1) # error - self.mock_rados.Rados.open_ioctx.reset_mock() - self.mock_rados.Rados.shutdown.reset_mock() - self.mock_rados.Rados.open_ioctx.side_effect = self.mock_rados.Error + self.mock_rados.Rados.return_value.open_ioctx.reset_mock() + self.mock_rados.Rados.return_value.shutdown.reset_mock() + self.mock_rados.Rados.return_value.open_ioctx.side_effect = ( + self.mock_rados.Error) self.assertRaises(exception.VolumeBackendAPIException, self.driver._connect_to_rados) - self.mock_rados.Rados.open_ioctx.assert_called_once() - self.mock_rados.Rados.shutdown.assert_called_once() + self.mock_rados.Rados.return_value.open_ioctx.assert_called_once() + self.mock_rados.Rados.return_value.shutdown.assert_called_once() class RBDImageIOWrapperTestCase(test.TestCase): -- 2.45.2