Add coverage for add method

This patch adds test coverage of code paths like extend volume,
exception blocks, when image_size is zero, volume delete call etc

Change-Id: I59b1579dc9877668b82d4195431c14cc41cfe892
This commit is contained in:
whoami-rajat 2022-03-17 14:11:15 +05:30
parent 4bd0304efb
commit f9253a4ade
3 changed files with 173 additions and 0 deletions

View File

@ -570,6 +570,173 @@ class TestCinderStoreBase(object):
if is_multi_store:
self.assertEqual(backend, metadata["store"])
def test_cinder_add_volume_not_found(self):
image_file = mock.MagicMock()
fake_image_id = str(uuid.uuid4())
expected_size = 0
fake_volumes = mock.MagicMock(create=mock.MagicMock(
side_effect=cinder.cinder_exception.NotFound(code=404)))
with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc:
mock_cc.return_value = mock.MagicMock(volumes=fake_volumes)
self.assertRaises(
exceptions.BackendException, self.store.add,
fake_image_id, image_file, expected_size, self.hash_algo,
self.context, None)
def _test_cinder_add_extend(self, is_multi_store=False):
expected_volume_size = 2 * units.Gi
expected_multihash = 'fake_hash'
fakebuffer = mock.MagicMock()
fakebuffer.__len__.return_value = expected_volume_size
def get_fake_hash(type, secure=False):
if type == 'md5':
return mock.MagicMock(hexdigest=lambda: expected_checksum)
else:
return mock.MagicMock(hexdigest=lambda: expected_multihash)
expected_image_id = str(uuid.uuid4())
expected_volume_id = str(uuid.uuid4())
expected_size = 0
image_file = mock.MagicMock(
read=mock.MagicMock(side_effect=[fakebuffer, None]))
fake_volume = mock.MagicMock(id=expected_volume_id, status='available',
size=1)
expected_checksum = 'fake_checksum'
verifier = None
backend = 'glance_store'
expected_location = 'cinder://%s' % fake_volume.id
if is_multi_store:
# Default backend is 'glance_store' for single store but in case
# of multi store, if the backend option is not passed, we should
# assign it to the default i.e. 'cinder1'
backend = 'cinder1'
expected_location = 'cinder://%s/%s' % (backend, fake_volume.id)
self.config(cinder_volume_type='some_type', group=backend)
fake_client = mock.MagicMock(auth_token=None, management_url=None)
fake_volume.manager.get.return_value = fake_volume
fake_volumes = mock.MagicMock(create=mock.Mock(
return_value=fake_volume))
@contextlib.contextmanager
def fake_open(client, volume, mode):
self.assertEqual('wb', mode)
yield mock.MagicMock()
with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc, \
mock.patch.object(self.store, '_open_cinder_volume',
side_effect=fake_open), \
mock.patch.object(cinder.Store, '_wait_resize_device'), \
mock.patch.object(cinder.utils, 'get_hasher') as fake_hasher, \
mock.patch.object(cinder.Store, '_wait_volume_status',
return_value=fake_volume) as mock_wait:
mock_cc.return_value = mock.MagicMock(client=fake_client,
volumes=fake_volumes)
fake_hasher.side_effect = get_fake_hash
loc, size, checksum, multihash, metadata = self.store.add(
expected_image_id, image_file, expected_size, self.hash_algo,
self.context, verifier)
self.assertEqual(expected_location, loc)
self.assertEqual(expected_volume_size, size)
self.assertEqual(expected_checksum, checksum)
self.assertEqual(expected_multihash, multihash)
fake_volumes.create.assert_called_once_with(
1,
name='image-%s' % expected_image_id,
metadata={'image_owner': self.context.project_id,
'glance_image_id': expected_image_id,
'image_size': str(expected_volume_size)},
volume_type='some_type')
if is_multi_store:
self.assertEqual(backend, metadata["store"])
fake_volume.extend.assert_called_once_with(
fake_volume, expected_volume_size // units.Gi)
mock_wait.assert_has_calls(
[mock.call(fake_volume, 'creating', 'available'),
mock.call(fake_volume, 'extending', 'available')])
def test_cinder_add_extend_storage_full(self):
expected_volume_size = 2 * units.Gi
fakebuffer = mock.MagicMock()
fakebuffer.__len__.return_value = expected_volume_size
expected_image_id = str(uuid.uuid4())
expected_volume_id = str(uuid.uuid4())
expected_size = 0
image_file = mock.MagicMock(
read=mock.MagicMock(side_effect=[fakebuffer, None]))
fake_volume = mock.MagicMock(id=expected_volume_id, status='available',
size=1)
verifier = None
fake_client = mock.MagicMock()
fake_volume.manager.get.return_value = fake_volume
fake_volumes = mock.MagicMock(create=mock.Mock(
return_value=fake_volume))
with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc, \
mock.patch.object(self.store, '_open_cinder_volume'), \
mock.patch.object(cinder.Store, '_wait_resize_device'), \
mock.patch.object(cinder.utils, 'get_hasher'), \
mock.patch.object(
cinder.Store, '_wait_volume_status') as mock_wait:
mock_cc.return_value = mock.MagicMock(client=fake_client,
volumes=fake_volumes)
mock_wait.side_effect = [fake_volume, exceptions.BackendException]
self.assertRaises(
exceptions.StorageFull, self.store.add, expected_image_id,
image_file, expected_size, self.hash_algo, self.context,
verifier)
def test_cinder_add_extend_volume_delete_exception(self):
expected_volume_size = 2 * units.Gi
fakebuffer = mock.MagicMock()
fakebuffer.__len__.return_value = expected_volume_size
expected_image_id = str(uuid.uuid4())
expected_volume_id = str(uuid.uuid4())
expected_size = 0
image_file = mock.MagicMock(
read=mock.MagicMock(side_effect=[fakebuffer, None]))
fake_volume = mock.MagicMock(
id=expected_volume_id, status='available', size=1,
delete=mock.MagicMock(side_effect=Exception()))
fake_client = mock.MagicMock()
fake_volume.manager.get.return_value = fake_volume
fake_volumes = mock.MagicMock(create=mock.Mock(
return_value=fake_volume))
verifier = None
with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc, \
mock.patch.object(self.store, '_open_cinder_volume'), \
mock.patch.object(cinder.Store, '_wait_resize_device'), \
mock.patch.object(cinder.utils, 'get_hasher'), \
mock.patch.object(
cinder.Store, '_wait_volume_status') as mock_wait:
mock_cc.return_value = mock.MagicMock(client=fake_client,
volumes=fake_volumes)
mock_wait.side_effect = [fake_volume, exceptions.BackendException]
self.assertRaises(
Exception, self.store.add, expected_image_id, # noqa
image_file, expected_size, self.hash_algo, self.context,
verifier)
fake_volume.delete.assert_called_once()
def _test_cinder_delete(self, is_multi_store=False):
fake_client = mock.MagicMock(auth_token=None, management_url=None)
fake_volume_uuid = str(uuid.uuid4())

View File

@ -145,6 +145,9 @@ class TestCinderStore(base.StoreBaseTest,
fail_resize=True)
fake_volume.delete.assert_called_once()
def test_cinder_add_extend(self):
self._test_cinder_add_extend()
def test_cinder_delete(self):
self._test_cinder_delete()

View File

@ -283,6 +283,9 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
fail_resize=True, is_multi_store=True)
fake_volume.delete.assert_called_once()
def test_cinder_add_extend(self):
self._test_cinder_add_extend(is_multi_store=True)
def test_cinder_delete(self):
self._test_cinder_delete(is_multi_store=True)