diff --git a/rally-jobs/cinder.yaml b/rally-jobs/cinder.yaml index 0a207d4348..2d31c5fb65 100644 --- a/rally-jobs/cinder.yaml +++ b/rally-jobs/cinder.yaml @@ -100,6 +100,33 @@ failure_rate: max: 0 + - + args: + size: 1 + image: + name: "image-context-test" + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 1 + users_per_tenant: 2 + roles: + - admin + images: + image_url: "~/.rally/extra/fake-image.img" + image_type: "qcow2" + image_container: "bare" + images_per_tenant: 1 + image_name: "image-context-test" + image_args: + is_public: True + sla: + failure_rate: + max: 0 + CinderVolumes.create_and_update_volume: - args: diff --git a/rally/plugins/openstack/context/glance/images.py b/rally/plugins/openstack/context/glance/images.py index b42ee9bf0e..d46c15ba66 100644 --- a/rally/plugins/openstack/context/glance/images.py +++ b/rally/plugins/openstack/context/glance/images.py @@ -57,6 +57,10 @@ class ImageGenerator(context.Context): "type": "integer", "minimum": 1 }, + "image_args": { + "type": "object", + "additionalProperties": True + } }, "required": ["image_url", "image_type", "image_container", "images_per_tenant"], @@ -76,6 +80,17 @@ class ImageGenerator(context.Context): current_images = [] glance_scenario = glance_utils.GlanceScenario( {"user": user, "task": self.context["task"]}) + + kwargs = self.config.get("image_args", {}) + if self.config.get("min_ram") is not None: + LOG.warning("The 'min_ram' argument is deprecated; specify " + "arbitrary arguments with 'image_args' instead") + kwargs["min_ram"] = self.config["min_ram"] + if self.config.get("min_disk") is not None: + LOG.warning("The 'min_disk' argument is deprecated; specify " + "arbitrary arguments with 'image_args' instead") + kwargs["min_disk"] = self.config["min_disk"] + for i in range(images_per_tenant): if image_name and i > 0: cur_name = image_name + str(i) @@ -86,8 +101,7 @@ class ImageGenerator(context.Context): image = glance_scenario._create_image( image_container, image_url, image_type, - name=cur_name, min_ram=self.config.get("min_ram", 0), - min_disk=self.config.get("min_disk", 0)) + name=cur_name, **kwargs) current_images.append(image.id) self.context["tenants"][tenant_id]["images"] = current_images diff --git a/tests/unit/plugins/openstack/context/glance/test_images.py b/tests/unit/plugins/openstack/context/glance/test_images.py index 6cc28e2da3..5df9523756 100644 --- a/tests/unit/plugins/openstack/context/glance/test_images.py +++ b/tests/unit/plugins/openstack/context/glance/test_images.py @@ -15,17 +15,18 @@ import copy +import ddt import jsonschema import mock from rally.plugins.openstack.context.glance import images -from tests.unit import fakes from tests.unit import test CTX = "rally.plugins.openstack.context.glance" SCN = "rally.plugins.openstack.scenarios.glance" +@ddt.ddt class ImageGeneratorTestCase(test.ScenarioTestCase): def _gen_tenants(self, count): @@ -44,54 +45,77 @@ class ImageGeneratorTestCase(test.ScenarioTestCase): self.assertRaises(jsonschema.ValidationError, images.ImageGenerator.validate, self.context) - @mock.patch("%s.utils.GlanceScenario._create_image" % SCN, - return_value=fakes.FakeImage(id="uuid")) - def test_setup(self, mock_glance_scenario__create_image): - - tenants_count = 2 - users_per_tenant = 5 - images_per_tenant = 5 - - tenants = self._gen_tenants(tenants_count) + @ddt.data( + {}, + {"min_disk": 1, "min_ram": 2}, + {"image_name": "foo"}, + {"tenants": 3, "users_per_tenant": 2, "images_per_tenant": 5}, + {"image_args": {"min_disk": 1, "min_ram": 2, "visibility": "public"}}) + @ddt.unpack + @mock.patch("%s.utils.GlanceScenario._create_image" % SCN) + def test_setup(self, mock_glance_scenario__create_image, + image_container="bare", image_type="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, + image_args=None): + tenant_data = self._gen_tenants(tenants) users = [] - for id_ in tenants: + for tenant_id in tenant_data: for i in range(users_per_tenant): - users.append({"id": i, "tenant_id": id_, + users.append({"id": i, "tenant_id": tenant_id, "credential": mock.MagicMock()}) self.context.update({ "config": { "users": { - "tenants": tenants_count, + "tenants": tenants, "users_per_tenant": users_per_tenant, "concurrent": 10, }, "images": { - "image_url": "mock_url", - "image_type": "qcow2", - "image_container": "bare", + "image_url": image_url, + "image_type": image_type, + "image_container": image_container, "images_per_tenant": images_per_tenant, - "image_name": "some_name", - "min_ram": 128, - "min_disk": 1, } }, "admin": { "credential": mock.MagicMock() }, "users": users, - "tenants": tenants + "tenants": tenant_data }) + expected_image_args = {} + if image_args is not None: + self.context["config"]["images"]["image_args"] = image_args + expected_image_args.update(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 id_ in new_context["tenants"].keys(): - new_context["tenants"][id_].setdefault("images", []) - for j in range(images_per_tenant): - new_context["tenants"][id_]["images"].append("uuid") + for tenant_id in new_context["tenants"].keys(): + new_context["tenants"][tenant_id]["images"] = [ + mock_glance_scenario__create_image.return_value.id + ] * images_per_tenant images_ctx = images.ImageGenerator(self.context) images_ctx.setup() self.assertEqual(new_context, self.context) + mock_glance_scenario__create_image.assert_has_calls( + [mock.call(image_container, image_url, image_type, + name=mock.ANY, + **expected_image_args)] * tenants * images_per_tenant) + if image_name: + for args in mock_glance_scenario__create_image.call_args_list: + self.assertTrue(args[1]["name"].startswith(image_name)) @mock.patch("%s.images.resource_manager.cleanup" % CTX) def test_cleanup(self, mock_cleanup):