Images context: accept arbitrary image create args

This deprecates the min_ram and min_disk arguments in favor of
image_args, which lets the user specify any image creation keyword
arguments they want.

This provides a workaround for the bug that prevents images created in
the images context from actually being used by letting the user
specify that the image should be public, and thus can be used by
scenarios running other tenants than the admin user's tenant. Also
adds a gate job to ensure that images created by the images context
can be used in a scenario.

Partial-Bug: 1503744
Change-Id: I200821f4850073990878c38f04959ecf1ff9c522
This commit is contained in:
Chris St. Pierre 2015-12-23 15:50:40 -06:00
parent a003008a04
commit 013792c458
3 changed files with 91 additions and 26 deletions

View File

@ -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:

View File

@ -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

View File

@ -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):