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:
parent
54e0590ce7
commit
db88d1ed36
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user