rally-openstack/tests/unit/contexts/glance/test_images.py

280 lines
10 KiB
Python

# 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 copy
import ddt
import mock
from rally_openstack.contexts.glance import images
from tests.unit import test
CTX = "rally_openstack.contexts.glance.images"
SCN = "rally_openstack.scenarios.glance"
@ddt.ddt
class ImageGeneratorTestCase(test.ScenarioTestCase):
tenants_num = 1
users_per_tenant = 5
users_num = tenants_num * users_per_tenant
threads = 10
def setUp(self):
super(ImageGeneratorTestCase, self).setUp()
self.context.update({
"config": {
"users": {
"tenants": self.tenants_num,
"users_per_tenant": self.users_per_tenant,
"resource_management_workers": self.threads,
}
},
"admin": {"credential": mock.MagicMock()},
"users": [],
"task": {"uuid": "task_id"}
})
patch = mock.patch(
"rally_openstack.services.image.image.Image")
self.addCleanup(patch.stop)
self.mock_image = patch.start()
def _gen_tenants(self, count):
tenants = {}
for id_ in range(count):
tenants[str(id_)] = {"name": str(id_)}
return tenants
@ddt.data(
{},
{"min_disk": 1, "min_ram": 2},
{"image_name": "foo"},
{"tenants": 3, "users_per_tenant": 2, "images_per_tenant": 5})
@ddt.unpack
@mock.patch("rally_openstack.osclients.Clients")
def test_setup(self, mock_clients,
container_format="bare", disk_format="qcow2",
image_url="http://example.com/fake/url",
tenants=1, users_per_tenant=1, images_per_tenant=1,
image_name=None, min_ram=None, min_disk=None,
visibility="public"):
image_service = self.mock_image.return_value
tenant_data = self._gen_tenants(tenants)
users = []
for tenant_id in tenant_data:
for i in range(users_per_tenant):
users.append({"id": i, "tenant_id": tenant_id,
"credential": mock.MagicMock()})
self.context.update({
"config": {
"users": {
"tenants": tenants,
"users_per_tenant": users_per_tenant,
"concurrent": 10,
},
"images": {
"image_url": image_url,
"disk_format": disk_format,
"container_format": container_format,
"images_per_tenant": images_per_tenant,
"visibility": visibility,
}
},
"admin": {
"credential": mock.MagicMock()
},
"users": users,
"tenants": tenant_data
})
expected_image_args = {}
if image_name is not None:
self.context["config"]["images"]["image_name"] = image_name
if min_ram is not None:
self.context["config"]["images"]["min_ram"] = min_ram
expected_image_args["min_ram"] = min_ram
if min_disk is not None:
self.context["config"]["images"]["min_disk"] = min_disk
expected_image_args["min_disk"] = min_disk
new_context = copy.deepcopy(self.context)
for tenant_id in new_context["tenants"].keys():
new_context["tenants"][tenant_id]["images"] = [
image_service.create_image.return_value.id
] * images_per_tenant
images_ctx = images.ImageGenerator(self.context)
images_ctx.setup()
self.assertEqual(new_context, self.context)
wrapper_calls = []
wrapper_calls.extend([mock.call(mock_clients.return_value.glance,
images_ctx)] * tenants)
wrapper_calls.extend(
[mock.call().create_image(
container_format, image_url, disk_format,
name=mock.ANY, **expected_image_args)]
* tenants * images_per_tenant)
mock_clients.assert_has_calls([mock.call(mock.ANY)] * tenants)
@mock.patch("%s.image.Image" % CTX)
@mock.patch("%s.LOG" % CTX)
def test_setup_with_deprecated_args(self, mock_log, mock_image):
image_type = "itype"
image_container = "icontainer"
is_public = True
d_min_ram = mock.Mock()
d_min_disk = mock.Mock()
self.context.update({
"config": {
"images": {"image_type": image_type,
"image_container": image_container,
"image_args": {"is_public": is_public,
"min_ram": d_min_ram,
"min_disk": d_min_disk}}
},
"users": [{"tenant_id": "foo-tenant",
"credential": mock.MagicMock()}],
"tenants": {"foo-tenant": {}}
})
images_ctx = images.ImageGenerator(self.context)
images_ctx.setup()
mock_image.return_value.create_image.assert_called_once_with(
image_name=None,
container_format=image_container,
image_location=None,
disk_format=image_type,
visibility="public",
min_disk=d_min_disk,
min_ram=d_min_ram
)
expected_warns = [
mock.call("The 'image_type' argument is deprecated since "
"Rally 0.10.0, use disk_format argument instead"),
mock.call("The 'image_container' argument is deprecated since "
"Rally 0.10.0; use container_format argument instead"),
mock.call("The 'image_args' argument is deprecated since "
"Rally 0.10.0; specify arguments in a root "
"section of context instead")]
self.assertEqual(expected_warns, mock_log.warning.call_args_list)
mock_image.return_value.create_image.reset_mock()
mock_log.warning.reset_mock()
min_ram = mock.Mock()
min_disk = mock.Mock()
visibility = "foo"
disk_format = "dformat"
container_format = "cformat"
self.context["config"]["images"].update({
"min_ram": min_ram,
"min_disk": min_disk,
"visibility": visibility,
"disk_format": disk_format,
"container_format": container_format
})
images_ctx = images.ImageGenerator(self.context)
images_ctx.setup()
# check that deprecated arguments are not used
mock_image.return_value.create_image.assert_called_once_with(
image_name=None,
container_format=container_format,
image_location=None,
disk_format=disk_format,
visibility=visibility,
min_disk=min_disk,
min_ram=min_ram
)
# No matter will be deprecated arguments used or not, if they are
# specified, warning message should be printed.
self.assertEqual(expected_warns, mock_log.warning.call_args_list)
@ddt.data({"admin": True})
@ddt.unpack
@mock.patch("%s.resource_manager.cleanup" % CTX)
def test_cleanup(self, mock_cleanup, admin=None):
images_per_tenant = 5
tenants = self._gen_tenants(self.tenants_num)
users = []
created_images = []
for tenant_id in tenants:
for i in range(self.users_per_tenant):
users.append({"id": i, "tenant_id": tenant_id,
"credential": mock.MagicMock()})
tenants[tenant_id].setdefault("images", [])
for j in range(images_per_tenant):
image = mock.Mock()
created_images.append(image)
tenants[tenant_id]["images"].append(image)
self.context.update({
"config": {
"users": {
"tenants": self.tenants_num,
"users_per_tenant": self.users_per_tenant,
"concurrent": 10,
},
"images": {}
},
"users": mock.Mock()
})
if admin:
self.context["admin"] = {"credential": mock.MagicMock()}
else:
# ensure that there is no admin
self.context.pop("admin")
images_ctx = images.ImageGenerator(self.context)
images_ctx.cleanup()
mock_cleanup.assert_called_once_with(
names=["glance.images", "cinder.image_volumes_cache"],
admin=self.context.get("admin"),
admin_required=None if admin else False,
users=self.context["users"],
superclass=images_ctx.__class__,
task_id=self.context["owner_id"])
@mock.patch("%s.rutils.make_name_matcher" % CTX)
@mock.patch("%s.resource_manager.cleanup" % CTX)
def test_cleanup_for_predefined_name(self, mock_cleanup,
mock_make_name_matcher):
self.context.update({
"config": {
"images": {"image_name": "foo"}
},
"users": mock.Mock()
})
images_ctx = images.ImageGenerator(self.context)
images_ctx.cleanup()
mock_cleanup.assert_called_once_with(
names=["glance.images", "cinder.image_volumes_cache"],
admin=self.context.get("admin"),
admin_required=None,
users=self.context["users"],
superclass=mock_make_name_matcher.return_value,
task_id=self.context["owner_id"])