Merge "Remove Mock class monkey patching"
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user