summaryrefslogtreecommitdiff
path: root/glance_store/tests
diff options
context:
space:
mode:
authorwhoami-rajat <rajatdhasmana@gmail.com>2022-03-10 22:28:29 +0530
committerwhoami-rajat <rajatdhasmana@gmail.com>2022-03-11 14:26:40 +0530
commitbb790de1dca91bd143d493ba94f5b9c48b74302e (patch)
tree5e118262ec78dc30dece641b4a819020b3dc04f0 /glance_store/tests
parent7b5b50fd9f49aab8c145d4fa2681f865cc07cbf6 (diff)
downloadglance_store-bb790de1dca91bd143d493ba94f5b9c48b74302e.tar.gz
Refactor cinder store tests[1/2]
This patch aims at a refactoring effort that would remove duplicate tests (current and future) by moving them into a common base class which is called via both single and multi store test modules with their specific configurations. This has a lot of benefits: 1) Removes duplicate code 2) Makes addition of new tests easier and cleaner 3) Ensuring a new method/code path added is tested in both single and multi store configurations 4) Fixing issues detected while refactoring methods (Eg: fake_chown accepted an optional backend parameter which does not match the signature of original method temporary_chown) Change-Id: Iaacb3e117cac2a661750bdb21bd0a7496078ea26
Diffstat (limited to 'glance_store/tests')
-rw-r--r--glance_store/tests/unit/test_cinder_base.py371
-rw-r--r--glance_store/tests/unit/test_cinder_store.py338
-rw-r--r--glance_store/tests/unit/test_multistore_cinder.py344
3 files changed, 414 insertions, 639 deletions
diff --git a/glance_store/tests/unit/test_cinder_base.py b/glance_store/tests/unit/test_cinder_base.py
new file mode 100644
index 0000000..45d786a
--- /dev/null
+++ b/glance_store/tests/unit/test_cinder_base.py
@@ -0,0 +1,371 @@
+# Copyright 2022 RedHat Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import contextlib
+import os
+from unittest import mock
+
+import six
+import socket
+import sys
+import tempfile
+import time
+import uuid
+
+from os_brick.initiator import connector
+from oslo_concurrency import processutils
+from oslo_utils import units
+
+from glance_store.common import attachment_state_manager
+from glance_store.common import cinder_utils
+from glance_store import exceptions
+from glance_store import location
+
+sys.modules['glance_store.common.fs_mount'] = mock.Mock()
+from glance_store._drivers import cinder # noqa
+
+
+class TestCinderStoreBase(object):
+
+ def test_get_cinderclient(self):
+ cc = self.store.get_cinderclient(self.context)
+ self.assertEqual('fake_token', cc.client.auth.token)
+ self.assertEqual('http://foo/public_url', cc.client.auth.endpoint)
+
+ def test_temporary_chown(self):
+ fake_stat = mock.MagicMock(st_uid=1)
+
+ with mock.patch.object(os, 'stat', return_value=fake_stat), \
+ mock.patch.object(os, 'getuid', return_value=2), \
+ mock.patch.object(processutils, 'execute') as mock_execute, \
+ mock.patch.object(cinder.Store, 'get_root_helper',
+ return_value='sudo'):
+ with self.store.temporary_chown('test'):
+ pass
+ expected_calls = [mock.call('chown', 2, 'test', run_as_root=True,
+ root_helper='sudo'),
+ mock.call('chown', 1, 'test', run_as_root=True,
+ root_helper='sudo')]
+ self.assertEqual(expected_calls, mock_execute.call_args_list)
+
+ @mock.patch.object(time, 'sleep')
+ def test_wait_volume_status(self, mock_sleep):
+ fake_manager = mock.MagicMock(get=mock.Mock())
+ volume_available = mock.MagicMock(manager=fake_manager,
+ id='fake-id',
+ status='available')
+ volume_in_use = mock.MagicMock(manager=fake_manager,
+ id='fake-id',
+ status='in-use')
+ fake_manager.get.side_effect = [volume_available, volume_in_use]
+ self.assertEqual(volume_in_use,
+ self.store._wait_volume_status(
+ volume_available, 'available', 'in-use'))
+ fake_manager.get.assert_called_with('fake-id')
+ mock_sleep.assert_called_once_with(0.5)
+
+ @mock.patch.object(time, 'sleep')
+ def test_wait_volume_status_unexpected(self, mock_sleep):
+ fake_manager = mock.MagicMock(get=mock.Mock())
+ volume_available = mock.MagicMock(manager=fake_manager,
+ id='fake-id',
+ status='error')
+ fake_manager.get.return_value = volume_available
+ self.assertRaises(exceptions.BackendException,
+ self.store._wait_volume_status,
+ volume_available, 'available', 'in-use')
+ fake_manager.get.assert_called_with('fake-id')
+
+ @mock.patch.object(time, 'sleep')
+ def test_wait_volume_status_timeout(self, mock_sleep):
+ fake_manager = mock.MagicMock(get=mock.Mock())
+ volume_available = mock.MagicMock(manager=fake_manager,
+ id='fake-id',
+ status='available')
+ fake_manager.get.return_value = volume_available
+ self.assertRaises(exceptions.BackendException,
+ self.store._wait_volume_status,
+ volume_available, 'available', 'in-use')
+ fake_manager.get.assert_called_with('fake-id')
+
+ def _test_open_cinder_volume(self, open_mode, attach_mode, error,
+ multipath_supported=False,
+ enforce_multipath=False,
+ encrypted_nfs=False, qcow2_vol=False,
+ multiattach=False):
+ fake_volume = mock.MagicMock(id=str(uuid.uuid4()), status='available',
+ multiattach=multiattach)
+ fake_volume.manager.get.return_value = fake_volume
+ fake_attachment_id = str(uuid.uuid4())
+ fake_attachment_create = {'id': fake_attachment_id}
+ if encrypted_nfs or qcow2_vol:
+ fake_attachment_update = mock.MagicMock(
+ id=fake_attachment_id,
+ connection_info={'driver_volume_type': 'nfs'})
+ else:
+ fake_attachment_update = mock.MagicMock(id=fake_attachment_id)
+ fake_conn_info = mock.MagicMock(connector={})
+ fake_volumes = mock.MagicMock(get=lambda id: fake_volume)
+ fake_client = mock.MagicMock(volumes=fake_volumes)
+ _, fake_dev_path = tempfile.mkstemp(dir=self.test_dir)
+ fake_devinfo = {'path': fake_dev_path}
+ fake_connector = mock.MagicMock(
+ connect_volume=mock.Mock(return_value=fake_devinfo),
+ disconnect_volume=mock.Mock())
+
+ @contextlib.contextmanager
+ def fake_chown(path):
+ yield
+
+ def do_open():
+ if multiattach:
+ with mock.patch.object(
+ attachment_state_manager._AttachmentStateManager,
+ 'get_state') as mock_get_state:
+ mock_get_state.return_value.__enter__.return_value = (
+ attachment_state_manager._AttachmentState())
+ with self.store._open_cinder_volume(
+ fake_client, fake_volume, open_mode):
+ pass
+ else:
+ with self.store._open_cinder_volume(
+ fake_client, fake_volume, open_mode):
+ if error:
+ raise error
+
+ def fake_factory(protocol, root_helper, **kwargs):
+ return fake_connector
+
+ root_helper = "sudo glance-rootwrap /etc/glance/rootwrap.conf"
+ with mock.patch.object(cinder.Store,
+ '_wait_volume_status',
+ return_value=fake_volume), \
+ mock.patch.object(cinder.Store, 'temporary_chown',
+ side_effect=fake_chown), \
+ mock.patch.object(cinder.Store, 'get_root_helper',
+ return_value=root_helper), \
+ mock.patch.object(connector.InitiatorConnector, 'factory',
+ side_effect=fake_factory
+ ) as fake_conn_obj, \
+ mock.patch.object(cinder_utils.API,
+ 'attachment_create',
+ return_value=fake_attachment_create
+ ) as attach_create, \
+ mock.patch.object(cinder_utils.API,
+ 'attachment_update',
+ return_value=fake_attachment_update
+ ) as attach_update, \
+ mock.patch.object(cinder_utils.API,
+ 'attachment_delete') as attach_delete, \
+ mock.patch.object(cinder_utils.API,
+ 'attachment_get') as attach_get, \
+ mock.patch.object(cinder_utils.API,
+ 'attachment_complete') as attach_complete, \
+ mock.patch.object(socket,
+ 'gethostname') as mock_get_host, \
+ mock.patch.object(socket,
+ 'getaddrinfo') as mock_get_host_ip:
+
+ fake_host = 'fake_host'
+ fake_addr_info = [[0, 1, 2, 3, ['127.0.0.1']]]
+ fake_ip = fake_addr_info[0][4][0]
+ mock_get_host.return_value = fake_host
+ mock_get_host_ip.return_value = fake_addr_info
+
+ with mock.patch.object(connector,
+ 'get_connector_properties',
+ return_value=fake_conn_info) as mock_conn:
+ if error:
+ self.assertRaises(error, do_open)
+ elif encrypted_nfs or qcow2_vol:
+ fake_volume.encrypted = False
+ if encrypted_nfs:
+ fake_volume.encrypted = True
+ elif qcow2_vol:
+ attach_get.return_value = mock.MagicMock(
+ connection_info={'format': 'qcow2'})
+ try:
+ with self.store._open_cinder_volume(
+ fake_client, fake_volume, open_mode):
+ pass
+ except exceptions.BackendException:
+ attach_delete.assert_called_once_with(
+ fake_client, fake_attachment_id)
+ else:
+ do_open()
+ if not (encrypted_nfs or qcow2_vol):
+ mock_conn.assert_called_once_with(
+ root_helper, fake_ip,
+ multipath_supported, enforce_multipath,
+ host=fake_host)
+ fake_connector.connect_volume.assert_called_once_with(
+ mock.ANY)
+ fake_connector.disconnect_volume.assert_called_once_with(
+ mock.ANY, fake_devinfo)
+ fake_conn_obj.assert_called_once_with(
+ mock.ANY, root_helper, conn=mock.ANY,
+ use_multipath=multipath_supported)
+ attach_create.assert_called_once_with(
+ fake_client, fake_volume.id, mode=attach_mode)
+ attach_update.assert_called_once_with(
+ fake_client, fake_attachment_id,
+ fake_conn_info, mountpoint='glance_store')
+ attach_complete.assert_called_once_with(
+ fake_client, fake_attachment_id)
+ attach_delete.assert_called_once_with(fake_client,
+ fake_attachment_id)
+ else:
+ mock_conn.assert_called_once_with(
+ root_helper, fake_ip,
+ multipath_supported, enforce_multipath,
+ host=fake_host)
+ fake_connector.connect_volume.assert_not_called()
+ fake_connector.disconnect_volume.assert_not_called()
+ fake_conn_obj.assert_called_once_with(
+ mock.ANY, root_helper, conn=mock.ANY,
+ use_multipath=multipath_supported)
+ attach_create.assert_called_once_with(
+ fake_client, fake_volume.id, mode=attach_mode)
+ attach_update.assert_called_once_with(
+ fake_client, fake_attachment_id,
+ fake_conn_info, mountpoint='glance_store')
+ attach_delete.assert_called_once_with(
+ fake_client, fake_attachment_id)
+
+ def test_open_cinder_volume_rw(self):
+ self._test_open_cinder_volume('wb', 'rw', None)
+
+ def test_open_cinder_volume_ro(self):
+ self._test_open_cinder_volume('rb', 'ro', None)
+
+ def test_open_cinder_volume_error(self):
+ self._test_open_cinder_volume('wb', 'rw', IOError)
+
+ def test_open_cinder_volume_nfs_encrypted(self):
+ self._test_open_cinder_volume('rb', 'ro', None, encrypted_nfs=True)
+
+ def test_open_cinder_volume_nfs_qcow2_volume(self):
+ self._test_open_cinder_volume('rb', 'ro', None, qcow2_vol=True)
+
+ def test_open_cinder_volume_multiattach_volume(self):
+ self._test_open_cinder_volume('rb', 'ro', None, multiattach=True)
+
+ def _fake_volume_type_check(self, name):
+ if name != 'some_type':
+ raise cinder.cinder_exception.NotFound(code=404)
+
+ def _test_configure_add_valid_type(self):
+
+ with mock.patch.object(self.store, 'get_cinderclient') as mocked_cc:
+ mocked_cc.return_value = mock.MagicMock(
+ volume_types=mock.MagicMock(
+ find=self._fake_volume_type_check))
+ # If volume type exists, no exception is raised
+ self.store.configure_add()
+
+ def _test_configure_add_invalid_type(self):
+
+ with mock.patch.object(self.store, 'get_cinderclient') as mocked_cc:
+ mocked_cc.return_value = mock.MagicMock(
+ volume_types=mock.MagicMock(
+ find=self._fake_volume_type_check))
+ with mock.patch.object(cinder, 'LOG') as mock_log:
+ self.store.configure_add()
+ mock_log.warning.assert_called_with(
+ "Invalid `cinder_volume_type some_random_type`")
+
+ def _get_uri_loc(self, fake_volume_uuid, is_multi_store=False):
+ if is_multi_store:
+ uri = "cinder://cinder1/%s" % fake_volume_uuid
+ loc = location.get_location_from_uri_and_backend(
+ uri, "cinder1", conf=self.conf)
+ else:
+ uri = "cinder://%s" % fake_volume_uuid
+ loc = location.get_location_from_uri(uri, conf=self.conf)
+
+ return loc
+
+ def _test_cinder_get(self, is_multi_store=False):
+ expected_size = 5 * units.Ki
+ expected_file_contents = b"*" * expected_size
+ volume_file = six.BytesIO(expected_file_contents)
+ fake_client = mock.MagicMock(auth_token=None, management_url=None)
+ fake_volume_uuid = str(uuid.uuid4())
+ fake_volume = mock.MagicMock(id=fake_volume_uuid,
+ metadata={'image_size': expected_size},
+ status='available')
+ fake_volume.manager.get.return_value = fake_volume
+ fake_volumes = mock.MagicMock(get=lambda id: fake_volume)
+
+ @contextlib.contextmanager
+ def fake_open(client, volume, mode):
+ self.assertEqual('rb', mode)
+ yield volume_file
+
+ with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc, \
+ mock.patch.object(self.store, '_open_cinder_volume',
+ side_effect=fake_open):
+ mock_cc.return_value = mock.MagicMock(client=fake_client,
+ volumes=fake_volumes)
+
+ loc = self._get_uri_loc(fake_volume_uuid,
+ is_multi_store=is_multi_store)
+
+ (image_file, image_size) = self.store.get(loc,
+ context=self.context)
+
+ expected_num_chunks = 2
+ data = b""
+ num_chunks = 0
+
+ for chunk in image_file:
+ num_chunks += 1
+ data += chunk
+ self.assertEqual(expected_num_chunks, num_chunks)
+ self.assertEqual(expected_file_contents, data)
+
+ def _test_cinder_get_size(self, is_multi_store=False):
+ fake_client = mock.MagicMock(auth_token=None, management_url=None)
+ fake_volume_uuid = str(uuid.uuid4())
+ fake_volume = mock.MagicMock(size=5, metadata={})
+ fake_volumes = {fake_volume_uuid: fake_volume}
+
+ with mock.patch.object(cinder.Store, 'get_cinderclient') as mocked_cc:
+ mocked_cc.return_value = mock.MagicMock(client=fake_client,
+ volumes=fake_volumes)
+
+ loc = self._get_uri_loc(fake_volume_uuid,
+ is_multi_store=is_multi_store)
+
+ image_size = self.store.get_size(loc, context=self.context)
+ self.assertEqual(fake_volume.size * units.Gi, image_size)
+
+ def _test_cinder_get_size_with_metadata(self, is_multi_store=False):
+ fake_client = mock.MagicMock(auth_token=None, management_url=None)
+ fake_volume_uuid = str(uuid.uuid4())
+ expected_image_size = 4500 * units.Mi
+ fake_volume = mock.MagicMock(
+ size=5, metadata={'image_size': expected_image_size})
+ fake_volumes = {fake_volume_uuid: fake_volume}
+
+ with mock.patch.object(cinder.Store, 'get_cinderclient') as mocked_cc:
+ mocked_cc.return_value = mock.MagicMock(client=fake_client,
+ volumes=fake_volumes)
+
+ loc = self._get_uri_loc(fake_volume_uuid,
+ is_multi_store=is_multi_store)
+
+ image_size = self.store.get_size(loc, context=self.context)
+ self.assertEqual(expected_image_size, image_size)
diff --git a/glance_store/tests/unit/test_cinder_store.py b/glance_store/tests/unit/test_cinder_store.py
index 05eb7d0..ab4f502 100644
--- a/glance_store/tests/unit/test_cinder_store.py
+++ b/glance_store/tests/unit/test_cinder_store.py
@@ -18,26 +18,20 @@ import errno
import hashlib
import io
import math
-import os
from unittest import mock
import six
-import socket
import sys
-import tempfile
import time
import uuid
-from os_brick.initiator import connector
-from oslo_concurrency import processutils
from oslo_utils.secretutils import md5
from oslo_utils import units
-from glance_store.common import attachment_state_manager
-from glance_store.common import cinder_utils
from glance_store import exceptions
from glance_store import location
from glance_store.tests import base
+from glance_store.tests.unit import test_cinder_base
from glance_store.tests.unit import test_store_capabilities
sys.modules['glance_store.common.fs_mount'] = mock.Mock()
@@ -45,7 +39,8 @@ from glance_store._drivers import cinder # noqa
class TestCinderStore(base.StoreBaseTest,
- test_store_capabilities.TestStoreCapabilitiesChecking):
+ test_store_capabilities.TestStoreCapabilitiesChecking,
+ test_cinder_base.TestCinderStoreBase):
def setUp(self):
super(TestCinderStore, self).setUp()
@@ -65,11 +60,7 @@ class TestCinderStore(base.StoreBaseTest,
project_id='fake_project')
self.hash_algo = 'sha256'
cinder._reset_cinder_session()
-
- def test_get_cinderclient(self):
- cc = self.store.get_cinderclient(self.context)
- self.assertEqual('fake_token', cc.client.auth.token)
- self.assertEqual('http://foo/public_url', cc.client.auth.endpoint)
+ self.config(cinder_mount_point_base=None)
def _test_get_cinderclient_with_user_overriden(self):
self.config(cinder_store_user_name='test_user')
@@ -89,221 +80,16 @@ class TestCinderStore(base.StoreBaseTest,
cc = self._test_get_cinderclient_with_user_overriden()
self.assertEqual('test_region', cc.client.region_name)
- def test_temporary_chown(self):
- class fake_stat(object):
- st_uid = 1
-
- with mock.patch.object(os, 'stat', return_value=fake_stat()), \
- mock.patch.object(os, 'getuid', return_value=2), \
- mock.patch.object(processutils, 'execute') as mock_execute, \
- mock.patch.object(cinder.Store, 'get_root_helper',
- return_value='sudo'):
- with self.store.temporary_chown('test'):
- pass
- expected_calls = [mock.call('chown', 2, 'test', run_as_root=True,
- root_helper='sudo'),
- mock.call('chown', 1, 'test', run_as_root=True,
- root_helper='sudo')]
- self.assertEqual(expected_calls, mock_execute.call_args_list)
-
- @mock.patch.object(time, 'sleep')
- def test_wait_volume_status(self, mock_sleep):
- fake_manager = mock.MagicMock(get=mock.Mock())
- volume_available = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='available')
- volume_in_use = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='in-use')
- fake_manager.get.side_effect = [volume_available, volume_in_use]
- self.assertEqual(volume_in_use,
- self.store._wait_volume_status(
- volume_available, 'available', 'in-use'))
- fake_manager.get.assert_called_with('fake-id')
- mock_sleep.assert_called_once_with(0.5)
-
- @mock.patch.object(time, 'sleep')
- def test_wait_volume_status_unexpected(self, mock_sleep):
- fake_manager = mock.MagicMock(get=mock.Mock())
- volume_available = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='error')
- fake_manager.get.return_value = volume_available
- self.assertRaises(exceptions.BackendException,
- self.store._wait_volume_status,
- volume_available, 'available', 'in-use')
- fake_manager.get.assert_called_with('fake-id')
-
- @mock.patch.object(time, 'sleep')
- def test_wait_volume_status_timeout(self, mock_sleep):
- fake_manager = mock.MagicMock(get=mock.Mock())
- volume_available = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='available')
- fake_manager.get.return_value = volume_available
- self.assertRaises(exceptions.BackendException,
- self.store._wait_volume_status,
- volume_available, 'available', 'in-use')
- fake_manager.get.assert_called_with('fake-id')
-
- def _test_open_cinder_volume(self, open_mode, attach_mode, error,
- multipath_supported=False,
- enforce_multipath=False,
- encrypted_nfs=False, qcow2_vol=False,
- multiattach=False):
- self.config(cinder_mount_point_base=None)
- fake_volume = mock.MagicMock(id=str(uuid.uuid4()), status='available',
- multiattach=multiattach)
- fake_volume.manager.get.return_value = fake_volume
- fake_volumes = mock.MagicMock(get=lambda id: fake_volume)
- fake_attachment_id = str(uuid.uuid4())
- fake_attachment_create = {'id': fake_attachment_id}
- if encrypted_nfs or qcow2_vol:
- fake_attachment_update = mock.MagicMock(
- id=fake_attachment_id,
- connection_info={'driver_volume_type': 'nfs'})
- else:
- fake_attachment_update = mock.MagicMock(id=fake_attachment_id)
- fake_conn_info = mock.MagicMock(connector={})
- fake_client = mock.MagicMock(volumes=fake_volumes)
- _, fake_dev_path = tempfile.mkstemp(dir=self.test_dir)
- fake_devinfo = {'path': fake_dev_path}
- fake_connector = mock.MagicMock(
- connect_volume=mock.Mock(return_value=fake_devinfo),
- disconnect_volume=mock.Mock())
-
- @contextlib.contextmanager
- def fake_chown(path, backend=None):
- yield
-
- def do_open():
- if multiattach:
- with mock.patch.object(
- attachment_state_manager._AttachmentStateManager,
- 'get_state') as mock_get_state:
- mock_get_state.return_value.__enter__.return_value = (
- attachment_state_manager._AttachmentState())
- with self.store._open_cinder_volume(
- fake_client, fake_volume, open_mode):
- pass
- else:
- with self.store._open_cinder_volume(
- fake_client, fake_volume, open_mode):
- if error:
- raise error
-
- def fake_factory(protocol, root_helper, **kwargs):
- return fake_connector
-
- root_helper = "sudo glance-rootwrap /etc/glance/rootwrap.conf"
- with mock.patch.object(cinder.Store,
- '_wait_volume_status',
- return_value=fake_volume), \
- mock.patch.object(cinder.Store, 'temporary_chown',
- side_effect=fake_chown), \
- mock.patch.object(cinder.Store, 'get_root_helper',
- return_value=root_helper), \
- mock.patch.object(connector.InitiatorConnector, 'factory',
- side_effect=fake_factory
- ) as fake_conn_obj, \
- mock.patch.object(cinder_utils.API, 'attachment_create',
- return_value=fake_attachment_create
- ) as attach_create, \
- mock.patch.object(cinder_utils.API, 'attachment_update',
- return_value=fake_attachment_update
- ) as attach_update, \
- mock.patch.object(cinder_utils.API,
- 'attachment_delete') as attach_delete, \
- mock.patch.object(cinder_utils.API,
- 'attachment_get') as attach_get, \
- mock.patch.object(cinder_utils.API,
- 'attachment_complete') as attach_complete, \
- mock.patch.object(socket,
- 'gethostname') as mock_get_host, \
- mock.patch.object(socket,
- 'getaddrinfo') as mock_get_host_ip:
-
- fake_host = 'fake_host'
- fake_addr_info = [[0, 1, 2, 3, ['127.0.0.1']]]
- fake_ip = fake_addr_info[0][4][0]
- mock_get_host.return_value = fake_host
- mock_get_host_ip.return_value = fake_addr_info
-
- with mock.patch.object(connector,
- 'get_connector_properties',
- return_value=fake_conn_info) as mock_conn:
- if error:
- self.assertRaises(error, do_open)
- elif encrypted_nfs or qcow2_vol:
- fake_volume.encrypted = False
- if encrypted_nfs:
- fake_volume.encrypted = True
- elif qcow2_vol:
- attach_get.return_value = mock.MagicMock(
- connection_info={'format': 'qcow2'})
- try:
- with self.store._open_cinder_volume(
- fake_client, fake_volume, open_mode):
- pass
- except exceptions.BackendException:
- attach_delete.assert_called_once_with(
- fake_client, fake_attachment_id)
- else:
- do_open()
-
- if not (encrypted_nfs or qcow2_vol):
- mock_conn.assert_called_once_with(
- root_helper, fake_ip,
- multipath_supported, enforce_multipath,
- host=fake_host)
- fake_connector.connect_volume.assert_called_once_with(
- mock.ANY)
- fake_connector.disconnect_volume.assert_called_once_with(
- mock.ANY, fake_devinfo)
- fake_conn_obj.assert_called_once_with(
- mock.ANY, root_helper, conn=mock.ANY,
- use_multipath=multipath_supported)
- attach_create.assert_called_once_with(
- fake_client, fake_volume.id, mode=attach_mode)
- attach_update.assert_called_once_with(
- fake_client, fake_attachment_id,
- fake_conn_info, mountpoint='glance_store')
- attach_complete.assert_called_once_with(
- fake_client, fake_attachment_id)
- attach_delete.assert_called_once_with(
- fake_client, fake_attachment_id)
- else:
- mock_conn.assert_called_once_with(
- root_helper, fake_ip,
- multipath_supported, enforce_multipath,
- host=fake_host)
- fake_connector.connect_volume.assert_not_called()
- fake_connector.disconnect_volume.assert_not_called()
- fake_conn_obj.assert_called_once_with(
- mock.ANY, root_helper, conn=mock.ANY,
- use_multipath=multipath_supported)
- attach_create.assert_called_once_with(
- fake_client, fake_volume.id, mode=attach_mode)
- attach_update.assert_called_once_with(
- fake_client, fake_attachment_id,
- fake_conn_info, mountpoint='glance_store')
- attach_delete.assert_called_once_with(
- fake_client, fake_attachment_id)
-
- def test_open_cinder_volume_rw(self):
- self._test_open_cinder_volume('wb', 'rw', None)
-
- def test_open_cinder_volume_ro(self):
- self._test_open_cinder_volume('rb', 'ro', None)
-
- def test_open_cinder_volume_error(self):
- self._test_open_cinder_volume('wb', 'rw', IOError)
-
- def test_open_cinder_volume_multipath_supported(self):
+ def test_open_cinder_volume_multipath_enabled(self):
self.config(cinder_use_multipath=True)
self._test_open_cinder_volume('wb', 'rw', None,
multipath_supported=True)
+ def test_open_cinder_volume_multipath_disabled(self):
+ self.config(cinder_use_multipath=False)
+ self._test_open_cinder_volume('wb', 'rw', None,
+ multipath_supported=False)
+
def test_open_cinder_volume_enforce_multipath(self):
self.config(cinder_use_multipath=True)
self.config(cinder_enforce_multipath=True)
@@ -311,15 +97,6 @@ class TestCinderStore(base.StoreBaseTest,
multipath_supported=True,
enforce_multipath=True)
- def test_open_cinder_volume_nfs_encrypted(self):
- self._test_open_cinder_volume('rb', 'ro', None, encrypted_nfs=True)
-
- def test_open_cinder_volume_nfs_qcow2_volume(self):
- self._test_open_cinder_volume('rb', 'ro', None, qcow2_vol=True)
-
- def test_open_cinder_volume_multiattach_volume(self):
- self._test_open_cinder_volume('rb', 'ro', None, multiattach=True)
-
def test_cinder_configure_add(self):
self.assertRaises(exceptions.BadStoreConfiguration,
self.store._check_context, None)
@@ -331,73 +108,13 @@ class TestCinderStore(base.StoreBaseTest,
self.store._check_context(mock.MagicMock(service_catalog='fake'))
def test_cinder_get(self):
- expected_size = 5 * units.Ki
- expected_file_contents = b"*" * expected_size
- volume_file = six.BytesIO(expected_file_contents)
- fake_client = mock.MagicMock(auth_token=None, management_url=None)
- fake_volume_uuid = str(uuid.uuid4())
- fake_volume = mock.MagicMock(id=fake_volume_uuid,
- metadata={'image_size': expected_size},
- status='available')
- fake_volume.manager.get.return_value = fake_volume
- fake_volumes = mock.MagicMock(get=lambda id: fake_volume)
-
- @contextlib.contextmanager
- def fake_open(client, volume, mode):
- self.assertEqual('rb', mode)
- yield volume_file
-
- with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc, \
- mock.patch.object(self.store, '_open_cinder_volume',
- side_effect=fake_open):
- mock_cc.return_value = mock.MagicMock(client=fake_client,
- volumes=fake_volumes)
- uri = "cinder://%s" % fake_volume_uuid
- loc = location.get_location_from_uri(uri, conf=self.conf)
- (image_file, image_size) = self.store.get(loc,
- context=self.context)
-
- expected_num_chunks = 2
- data = b""
- num_chunks = 0
-
- for chunk in image_file:
- num_chunks += 1
- data += chunk
- self.assertEqual(expected_num_chunks, num_chunks)
- self.assertEqual(expected_file_contents, data)
+ self._test_cinder_get()
def test_cinder_get_size(self):
- fake_client = mock.MagicMock(auth_token=None, management_url=None)
- fake_volume_uuid = str(uuid.uuid4())
- fake_volume = mock.MagicMock(size=5, metadata={})
- fake_volumes = {fake_volume_uuid: fake_volume}
-
- with mock.patch.object(cinder.Store, 'get_cinderclient') as mocked_cc:
- mocked_cc.return_value = mock.MagicMock(client=fake_client,
- volumes=fake_volumes)
-
- uri = 'cinder://%s' % fake_volume_uuid
- loc = location.get_location_from_uri(uri, conf=self.conf)
- image_size = self.store.get_size(loc, context=self.context)
- self.assertEqual(fake_volume.size * units.Gi, image_size)
+ self._test_cinder_get_size()
def test_cinder_get_size_with_metadata(self):
- fake_client = mock.MagicMock(auth_token=None, management_url=None)
- fake_volume_uuid = str(uuid.uuid4())
- expected_image_size = 4500 * units.Mi
- fake_volume = mock.MagicMock(
- size=5, metadata={'image_size': expected_image_size})
- fake_volumes = {fake_volume_uuid: fake_volume}
-
- with mock.patch.object(cinder.Store, 'get_cinderclient') as mocked_cc:
- mocked_cc.return_value = mock.MagicMock(client=fake_client,
- volumes=fake_volumes)
-
- uri = 'cinder://%s' % fake_volume_uuid
- loc = location.get_location_from_uri(uri, conf=self.conf)
- image_size = self.store.get_size(loc, context=self.context)
- self.assertEqual(expected_image_size, image_size)
+ self._test_cinder_get_size_with_metadata()
def _test_cinder_add(self, fake_volume, volume_file, size_kb=5,
verifier=None, fail_resize=False):
@@ -489,26 +206,15 @@ class TestCinderStore(base.StoreBaseTest,
def test_set_url_prefix(self):
self.assertEqual('cinder://', self.store._url_prefix)
- def test_configure_add(self):
-
- def fake_volume_type(name):
- if name != 'some_type':
- raise cinder.cinder_exception.NotFound(code=404)
-
- with mock.patch.object(self.store, 'get_cinderclient') as mocked_cc:
- mocked_cc.return_value = mock.MagicMock(
- volume_types=mock.MagicMock(
- find=fake_volume_type))
- self.config(cinder_volume_type='some_type')
- # If volume type exists, no exception is raised
- self.store.configure_add()
- # setting cinder_volume_type to non-existent value will log a
- # warning
- self.config(cinder_volume_type='some_random_type')
- with mock.patch.object(cinder, 'LOG') as mock_log:
- self.store.configure_add()
- mock_log.warning.assert_called_with(
- "Invalid `cinder_volume_type some_random_type`")
+ def test_configure_add_valid_type(self):
+ self.config(cinder_volume_type='some_type')
+ self._test_configure_add_valid_type()
+
+ def test_configure_add_invalid_type(self):
+ # setting cinder_volume_type to non-existent value will log a
+ # warning
+ self.config(cinder_volume_type='some_random_type')
+ self._test_configure_add_invalid_type()
def test__get_device_size(self):
fake_data = b"fake binary data"
diff --git a/glance_store/tests/unit/test_multistore_cinder.py b/glance_store/tests/unit/test_multistore_cinder.py
index 0c7bbfa..82bf7a2 100644
--- a/glance_store/tests/unit/test_multistore_cinder.py
+++ b/glance_store/tests/unit/test_multistore_cinder.py
@@ -17,29 +17,23 @@ import contextlib
import errno
import io
import math
-import os
from unittest import mock
import six
-import socket
import sys
-import tempfile
import time
import uuid
import fixtures
-from os_brick.initiator import connector
-from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_utils.secretutils import md5
from oslo_utils import units
import glance_store as store
-from glance_store.common import attachment_state_manager
-from glance_store.common import cinder_utils
from glance_store import exceptions
from glance_store import location
from glance_store.tests import base
+from glance_store.tests.unit import test_cinder_base
from glance_store.tests.unit import test_store_capabilities as test_cap
sys.modules['glance_store.common.fs_mount'] = mock.Mock()
@@ -47,7 +41,8 @@ from glance_store._drivers import cinder # noqa
class TestMultiCinderStore(base.MultiStoreBaseTest,
- test_cap.TestStoreCapabilitiesChecking):
+ test_cap.TestStoreCapabilitiesChecking,
+ test_cinder_base.TestCinderStoreBase):
# NOTE(flaper87): temporary until we
# can move to a fully-local lib.
@@ -97,15 +92,11 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
auth_token='admin_token',
project_id='admin_project')
cinder._reset_cinder_session()
+ self.config(cinder_mount_point_base=None, group='cinder1')
def test_location_url_prefix_is_set(self):
self.assertEqual("cinder://cinder1", self.store.url_prefix)
- def test_get_cinderclient(self):
- cc = self.store.get_cinderclient(self.context)
- self.assertEqual('fake_token', cc.client.auth.token)
- self.assertEqual('http://foo/public_url', cc.client.auth.endpoint)
-
def test_get_cinderclient_with_user_overriden(self):
self.config(cinder_store_user_name='test_user', group="cinder1")
self.config(cinder_store_password='test_password', group="cinder1")
@@ -121,216 +112,10 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
self.assertEqual('admin_token', cc.client.auth.token)
self.assertEqual('http://foo/public_url', cc.client.auth.endpoint)
- def test_temporary_chown(self):
- class fake_stat(object):
- st_uid = 1
-
- with mock.patch.object(os, 'stat', return_value=fake_stat()), \
- mock.patch.object(os, 'getuid', return_value=2), \
- mock.patch.object(processutils, 'execute') as mock_execute, \
- mock.patch.object(cinder.Store, 'get_root_helper',
- return_value='sudo'):
- with self.store.temporary_chown('test'):
- pass
- expected_calls = [mock.call('chown', 2, 'test', run_as_root=True,
- root_helper='sudo'),
- mock.call('chown', 1, 'test', run_as_root=True,
- root_helper='sudo')]
- self.assertEqual(expected_calls, mock_execute.call_args_list)
-
- @mock.patch.object(time, 'sleep')
- def test_wait_volume_status(self, mock_sleep):
- fake_manager = mock.MagicMock(get=mock.Mock())
- volume_available = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='available')
- volume_in_use = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='in-use')
- fake_manager.get.side_effect = [volume_available, volume_in_use]
- self.assertEqual(volume_in_use,
- self.store._wait_volume_status(
- volume_available, 'available', 'in-use'))
- fake_manager.get.assert_called_with('fake-id')
- mock_sleep.assert_called_once_with(0.5)
-
- @mock.patch.object(time, 'sleep')
- def test_wait_volume_status_unexpected(self, mock_sleep):
- fake_manager = mock.MagicMock(get=mock.Mock())
- volume_available = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='error')
- fake_manager.get.return_value = volume_available
- self.assertRaises(exceptions.BackendException,
- self.store._wait_volume_status,
- volume_available, 'available', 'in-use')
- fake_manager.get.assert_called_with('fake-id')
-
- @mock.patch.object(time, 'sleep')
- def test_wait_volume_status_timeout(self, mock_sleep):
- fake_manager = mock.MagicMock(get=mock.Mock())
- volume_available = mock.MagicMock(manager=fake_manager,
- id='fake-id',
- status='available')
- fake_manager.get.return_value = volume_available
- self.assertRaises(exceptions.BackendException,
- self.store._wait_volume_status,
- volume_available, 'available', 'in-use')
- fake_manager.get.assert_called_with('fake-id')
-
- def _test_open_cinder_volume(self, open_mode, attach_mode, error,
- multipath_supported=False,
- enforce_multipath=False,
- encrypted_nfs=False, qcow2_vol=False,
- multiattach=False):
- self.config(cinder_mount_point_base=None, group='cinder1')
- fake_volume = mock.MagicMock(id=str(uuid.uuid4()), status='available',
- multiattach=multiattach)
- fake_volume.manager.get.return_value = fake_volume
- fake_attachment_id = str(uuid.uuid4())
- fake_attachment_create = {'id': fake_attachment_id}
- if encrypted_nfs or qcow2_vol:
- fake_attachment_update = mock.MagicMock(
- id=fake_attachment_id,
- connection_info={'driver_volume_type': 'nfs'})
- else:
- fake_attachment_update = mock.MagicMock(id=fake_attachment_id)
- fake_conn_info = mock.MagicMock(connector={})
- fake_volumes = mock.MagicMock(get=lambda id: fake_volume)
- fake_client = mock.MagicMock(volumes=fake_volumes)
- _, fake_dev_path = tempfile.mkstemp(dir=self.test_dir)
- fake_devinfo = {'path': fake_dev_path}
- fake_connector = mock.MagicMock(
- connect_volume=mock.Mock(return_value=fake_devinfo),
- disconnect_volume=mock.Mock())
-
- @contextlib.contextmanager
- def fake_chown(path, backend=None):
- yield
-
- def do_open():
- if multiattach:
- with mock.patch.object(
- attachment_state_manager._AttachmentStateManager,
- 'get_state') as mock_get_state:
- mock_get_state.return_value.__enter__.return_value = (
- attachment_state_manager._AttachmentState())
- with self.store._open_cinder_volume(
- fake_client, fake_volume, open_mode):
- pass
- else:
- with self.store._open_cinder_volume(
- fake_client, fake_volume, open_mode):
- if error:
- raise error
-
- def fake_factory(protocol, root_helper, **kwargs):
- return fake_connector
-
- root_helper = "sudo glance-rootwrap /etc/glance/rootwrap.conf"
- with mock.patch.object(cinder.Store,
- '_wait_volume_status',
- return_value=fake_volume), \
- mock.patch.object(cinder.Store, 'temporary_chown',
- side_effect=fake_chown), \
- mock.patch.object(cinder.Store, 'get_root_helper',
- return_value=root_helper), \
- mock.patch.object(connector.InitiatorConnector, 'factory',
- side_effect=fake_factory
- ) as fake_conn_obj, \
- mock.patch.object(cinder_utils.API,
- 'attachment_create',
- return_value=fake_attachment_create
- ) as attach_create, \
- mock.patch.object(cinder_utils.API,
- 'attachment_update',
- return_value=fake_attachment_update
- ) as attach_update, \
- mock.patch.object(cinder_utils.API,
- 'attachment_delete') as attach_delete, \
- mock.patch.object(cinder_utils.API,
- 'attachment_get') as attach_get, \
- mock.patch.object(cinder_utils.API,
- 'attachment_complete') as attach_complete, \
- mock.patch.object(socket,
- 'gethostname') as mock_get_host, \
- mock.patch.object(socket,
- 'getaddrinfo') as mock_get_host_ip:
-
- fake_host = 'fake_host'
- fake_addr_info = [[0, 1, 2, 3, ['127.0.0.1']]]
- fake_ip = fake_addr_info[0][4][0]
- mock_get_host.return_value = fake_host
- mock_get_host_ip.return_value = fake_addr_info
-
- with mock.patch.object(connector,
- 'get_connector_properties',
- return_value=fake_conn_info) as mock_conn:
- if error:
- self.assertRaises(error, do_open)
- elif encrypted_nfs or qcow2_vol:
- fake_volume.encrypted = False
- if encrypted_nfs:
- fake_volume.encrypted = True
- elif qcow2_vol:
- attach_get.return_value = mock.MagicMock(
- connection_info={'format': 'qcow2'})
- try:
- with self.store._open_cinder_volume(
- fake_client, fake_volume, open_mode):
- pass
- except exceptions.BackendException:
- attach_delete.assert_called_once_with(
- fake_client, fake_attachment_id)
- else:
- do_open()
- if not (encrypted_nfs or qcow2_vol):
- mock_conn.assert_called_once_with(
- root_helper, fake_ip,
- multipath_supported, enforce_multipath,
- host=fake_host)
- fake_connector.connect_volume.assert_called_once_with(
- mock.ANY)
- fake_connector.disconnect_volume.assert_called_once_with(
- mock.ANY, fake_devinfo)
- fake_conn_obj.assert_called_once_with(
- mock.ANY, root_helper, conn=mock.ANY,
- use_multipath=multipath_supported)
- attach_create.assert_called_once_with(
- fake_client, fake_volume.id, mode=attach_mode)
- attach_update.assert_called_once_with(
- fake_client, fake_attachment_id,
- fake_conn_info, mountpoint='glance_store')
- attach_complete.assert_called_once_with(
- fake_client, fake_attachment_id)
- attach_delete.assert_called_once_with(fake_client,
- fake_attachment_id)
- else:
- mock_conn.assert_called_once_with(
- root_helper, fake_ip,
- multipath_supported, enforce_multipath,
- host=fake_host)
- fake_connector.connect_volume.assert_not_called()
- fake_connector.disconnect_volume.assert_not_called()
- fake_conn_obj.assert_called_once_with(
- mock.ANY, root_helper, conn=mock.ANY,
- use_multipath=multipath_supported)
- attach_create.assert_called_once_with(
- fake_client, fake_volume.id, mode=attach_mode)
- attach_update.assert_called_once_with(
- fake_client, fake_attachment_id,
- fake_conn_info, mountpoint='glance_store')
- attach_delete.assert_called_once_with(
- fake_client, fake_attachment_id)
-
- def test_open_cinder_volume_rw(self):
- self._test_open_cinder_volume('wb', 'rw', None)
-
- def test_open_cinder_volume_ro(self):
- self._test_open_cinder_volume('rb', 'ro', None)
-
- def test_open_cinder_volume_error(self):
- self._test_open_cinder_volume('wb', 'rw', IOError)
+ def test_open_cinder_volume_multipath_enabled(self):
+ self.config(cinder_use_multipath=True, group='cinder1')
+ self._test_open_cinder_volume('wb', 'rw', None,
+ multipath_supported=True)
def test_open_cinder_volume_multipath_disabled(self):
self.config(cinder_use_multipath=False, group='cinder1')
@@ -338,22 +123,12 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
multipath_supported=False)
def test_open_cinder_volume_enforce_multipath(self):
-
self.config(cinder_use_multipath=True, group='cinder1')
self.config(cinder_enforce_multipath=True, group='cinder1')
self._test_open_cinder_volume('wb', 'rw', None,
multipath_supported=True,
enforce_multipath=True)
- def test_open_cinder_volume_nfs_encrypted(self):
- self._test_open_cinder_volume('rb', 'ro', None, encrypted_nfs=True)
-
- def test_open_cinder_volume_nfs_qcow2_volume(self):
- self._test_open_cinder_volume('rb', 'ro', None, qcow2_vol=True)
-
- def test_open_cinder_volume_multiattach_volume(self):
- self._test_open_cinder_volume('rb', 'ro', None, multiattach=True)
-
def test_cinder_check_context(self):
self.assertRaises(exceptions.BadStoreConfiguration,
self.store._check_context, None)
@@ -364,28 +139,17 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
self.store._check_context(mock.MagicMock(service_catalog='fake'))
- def test_configure_add(self):
-
- def fake_volume_type_check(name):
- if name != 'some_type':
- raise cinder.cinder_exception.NotFound(code=404)
+ def test_configure_add_valid_type(self):
+ self.config(cinder_volume_type='some_type',
+ group=self.store.backend_group)
+ self._test_configure_add_valid_type()
- with mock.patch.object(self.store, 'get_cinderclient') as mocked_cc:
- mocked_cc.return_value = mock.MagicMock(
- volume_types=mock.MagicMock(
- find=fake_volume_type_check))
- self.config(cinder_volume_type='some_type',
- group=self.store.backend_group)
- # If volume type exists, no exception is raised
- self.store.configure_add()
- # setting cinder_volume_type to non-existent value will log a
- # warning
- self.config(cinder_volume_type='some_random_type',
- group=self.store.backend_group)
- with mock.patch.object(cinder, 'LOG') as mock_log:
- self.store.configure_add()
- mock_log.warning.assert_called_with(
- "Invalid `cinder_volume_type some_random_type`")
+ def test_configure_add_invalid_type(self):
+ # setting cinder_volume_type to non-existent value will log a
+ # warning
+ self.config(cinder_volume_type='some_random_type',
+ group=self.store.backend_group)
+ self._test_configure_add_invalid_type()
def test_configure_add_cinder_service_down(self):
@@ -454,79 +218,13 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
self.assertFalse(type_match)
def test_cinder_get(self):
- expected_size = 5 * units.Ki
- expected_file_contents = b"*" * expected_size
- volume_file = six.BytesIO(expected_file_contents)
- fake_client = mock.MagicMock(auth_token=None, management_url=None)
- fake_volume_uuid = str(uuid.uuid4())
- fake_volume = mock.MagicMock(id=fake_volume_uuid,
- metadata={'image_size': expected_size},
- status='available')
- fake_volume.manager.get.return_value = fake_volume
- fake_volumes = mock.MagicMock(get=lambda id: fake_volume)
-
- @contextlib.contextmanager
- def fake_open(client, volume, mode):
- self.assertEqual('rb', mode)
- yield volume_file
-
- with mock.patch.object(cinder.Store, 'get_cinderclient') as mock_cc, \
- mock.patch.object(self.store, '_open_cinder_volume',
- side_effect=fake_open):
- mock_cc.return_value = mock.MagicMock(client=fake_client,
- volumes=fake_volumes)
- uri = "cinder://cinder1/%s" % fake_volume_uuid
- loc = location.get_location_from_uri_and_backend(uri,
- "cinder1",
- conf=self.conf)
- (image_file, image_size) = self.store.get(loc,
- context=self.context)
-
- expected_num_chunks = 2
- data = b""
- num_chunks = 0
-
- for chunk in image_file:
- num_chunks += 1
- data += chunk
- self.assertEqual(expected_num_chunks, num_chunks)
- self.assertEqual(expected_file_contents, data)
+ self._test_cinder_get(is_multi_store=True)
def test_cinder_get_size(self):
- fake_client = mock.MagicMock(auth_token=None, management_url=None)
- fake_volume_uuid = str(uuid.uuid4())
- fake_volume = mock.MagicMock(size=5, metadata={})
- fake_volumes = {fake_volume_uuid: fake_volume}
-
- with mock.patch.object(cinder.Store, 'get_cinderclient') as mocked_cc:
- mocked_cc.return_value = mock.MagicMock(client=fake_client,
- volumes=fake_volumes)
-
- uri = 'cinder://cinder1/%s' % fake_volume_uuid
- loc = location.get_location_from_uri_and_backend(uri,
- "cinder1",
- conf=self.conf)
- image_size = self.store.get_size(loc, context=self.context)
- self.assertEqual(fake_volume.size * units.Gi, image_size)
+ self._test_cinder_get_size(is_multi_store=True)
def test_cinder_get_size_with_metadata(self):
- fake_client = mock.MagicMock(auth_token=None, management_url=None)
- fake_volume_uuid = str(uuid.uuid4())
- expected_image_size = 4500 * units.Mi
- fake_volume = mock.MagicMock(
- size=5, metadata={'image_size': expected_image_size})
- fake_volumes = {fake_volume_uuid: fake_volume}
-
- with mock.patch.object(cinder.Store, 'get_cinderclient') as mocked_cc:
- mocked_cc.return_value = mock.MagicMock(client=fake_client,
- volumes=fake_volumes)
-
- uri = 'cinder://cinder1/%s' % fake_volume_uuid
- loc = location.get_location_from_uri_and_backend(uri,
- "cinder1",
- conf=self.conf)
- image_size = self.store.get_size(loc, context=self.context)
- self.assertEqual(expected_image_size, image_size)
+ self._test_cinder_get_size_with_metadata(is_multi_store=True)
def _test_cinder_add(self, fake_volume, volume_file, size_kb=5,
verifier=None, backend="cinder1", fail_resize=False):