Changes in getting image id from image name functionality

(types.ImageResourceType.transform method)

1. Changing sample scenario files to store image name as
regexp. This will help avoid further issues with current
image version of devstack and rally being out of sync.

2. Changing logic of _id_from_name method. name and regex
keys from resource_config dictionary are treated the same,
(as regexp) with name having priority. Going forward 'name'
key should always be used, and 'regexp' key is to there to
support legacy configurations. Also, exact check will be
performed on resource name.

3. Related unit test changed correspodently..

4. Added unit test for multiple maches of the same image name.

Change-Id: Ie0fc509445a652384f78864ad7d491e34b5a4d88
This commit is contained in:
Igor Pavlovic 2014-10-29 16:54:51 +00:00
parent beab98a853
commit dcf2d7b074
26 changed files with 91 additions and 53 deletions

View File

@ -4,7 +4,7 @@
"args": {
"volume_size": 10,
"image": {
"name": "cirros-0.3.2-x86_64-uec"
"name": "^cirros.*uec$"
},
"flavor": {
"name": "m1.nano"

View File

@ -4,7 +4,7 @@
args:
volume_size: 10
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
flavor:
name: "m1.nano"
runner:

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
}
},
"runner": {

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 10

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"detailed": true
},

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
detailed: True
runner:
type: "constant"

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"actions": [
{"hard_reboot": 1},

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
actions:
-
hard_reboot: 1

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"volume_size": 10
},

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
volume_size: 10
runner:
type: "constant"

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"volume_size": 10
},

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
volume_size: 10
runner:
type: "constant"

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
}
},
"runner": {

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 10

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
}
},
"runner": {

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 10

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"to_flavor": {
"name": "m1.small"

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
to_flavor:
name: "m1.small"
confirm: true

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"volume_args": {
"size": 2

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
volume_args:
size: 2
fixed_network: "private"

View File

@ -6,7 +6,7 @@
"name": "m1.nano"
},
"image": {
"name": "cirros-0.3.1-x86_64-uec"
"name": "^cirros.*uec$"
},
"fixed_network": "private",
"floating_network": "public",

View File

@ -5,7 +5,7 @@
flavor:
name: "m1.nano"
image:
name: "cirros-0.3.1-x86_64-uec"
name: "^cirros.*uec$"
fixed_network: "private"
floating_network: "public"
use_floatingip: true

View File

@ -290,7 +290,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 6
@ -308,7 +308,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 6
@ -326,7 +326,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
detailed: True
runner:
type: "constant"
@ -345,7 +345,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
actions:
-
hard_reboot: 1
@ -372,7 +372,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
volume_size: 1
runner:
type: "constant"
@ -391,7 +391,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
volume_size: 1
runner:
type: "constant"
@ -410,7 +410,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 2
@ -428,7 +428,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
to_flavor:
name: "m1.small"
confirm: true

View File

@ -668,7 +668,7 @@
args:
volume_size: 1
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
flavor:
name: "m1.tiny"
runner:
@ -760,7 +760,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 4
@ -778,7 +778,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
detailed: True
runner:
type: "constant"
@ -797,7 +797,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
to_flavor:
name: "m1.small"
confirm: true
@ -818,7 +818,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
actions:
-
hard_reboot: 1
@ -845,7 +845,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
volume_size: 1
runner:
type: "constant"
@ -864,7 +864,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
volume_size: 1
runner:
type: "constant"
@ -883,7 +883,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 2
@ -901,7 +901,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
auto_assign_nics: false
runner:
type: "constant"
@ -918,7 +918,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
runner:
type: "constant"
times: 4
@ -936,7 +936,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
fixed_network: "private"
floating_network: "public"
use_floatingip: true
@ -959,7 +959,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
volume_args:
size: 2
fixed_network: "private"
@ -984,7 +984,7 @@
flavor:
name: "m1.tiny"
image:
name: "cirros-0.3.2-x86_64-uec"
name: "^cirros.*uec$"
fixed_network: "private"
use_floatingip: false
script: "/home/jenkins/.rally/extra/instance_dd_test.sh"

View File

@ -79,8 +79,8 @@ class ResourceType(object):
def _id_from_name(resource_config, resources, typename):
"""Return the id of the resource whose name matches the pattern.
When resource_config contains `name`, an exact match is used.
When resource_config contains `regex`, a pattern match is used.
resource_config has to contain `name`, as it is used to lookup an id.
Value of the name will be treated as regexp.
An `InvalidScenarioArgument` is thrown if the pattern does
not match unambiguously.
@ -91,10 +91,25 @@ def _id_from_name(resource_config, resources, typename):
:returns: resource id uniquely mapped to `name` or `regex`
"""
if resource_config.get('name'):
patternstr = "^{0}$".format(resource_config.get('name'))
elif resource_config.get('regex'):
patternstr = resource_config.get('regex')
if "name" in resource_config:
# In a case of pattern string exactly maches resource name
matching_exact = filter(lambda r: r.name == resource_config["name"],
resources)
if len(matching_exact) == 1:
return matching_exact[0].id
elif len(matching_exact) > 1:
raise exceptions.InvalidScenarioArgument(
"{typename} with name '{pattern}' "
"is ambiguous, possible matches "
"by id: {ids}".format(typename=typename.title(),
pattern=resource_config["name"],
ids=", ".join(map(
operator.attrgetter("id"),
matching_exact))))
# Else look up as regex
patternstr = resource_config["name"]
elif "regex" in resource_config:
patternstr = resource_config["regex"]
else:
raise exceptions.InvalidScenarioArgument(
"{typename} 'id', 'name', or 'regex' not found "
@ -153,7 +168,8 @@ class ImageResourceType(ResourceType):
if not resource_id:
glanceclient = clients.glance()
resource_id = _id_from_name(resource_config=resource_config,
resources=glanceclient.images.list(),
resources=list(
glanceclient.images.list()),
typename='image')
return resource_id
@ -201,4 +217,4 @@ class NeutronNetworkResourceType(ResourceType):
raise exceptions.InvalidScenarioArgument(
"Neutron network with name '{name}' not found".format(
name=resource_config.get("name")))
name=resource_config.get("name")))

View File

@ -30,6 +30,10 @@ class FlavorResourceTypeTestCase(test.TestCase):
id="1"))
self.clients.nova().flavors._cache(fakes.FakeResource(name='m1.nano',
id="42"))
self.clients.nova().flavors._cache(fakes.FakeResource(name='m1.large',
id="44"))
self.clients.nova().flavors._cache(fakes.FakeResource(name='m1.large',
id="45"))
def test_transform_by_id(self):
resource_config = {"id": "42"}
@ -57,6 +61,12 @@ class FlavorResourceTypeTestCase(test.TestCase):
types.FlavorResourceType.transform, self.clients,
resource_config)
def test_transform_by_name_multiple_match(self):
resource_config = {"name": "m1.large"}
self.assertRaises(exceptions.InvalidScenarioArgument,
types.FlavorResourceType.transform, self.clients,
resource_config)
def test_transform_by_regex(self):
resource_config = {"regex": "m(1|2)\.nano"}
flavor_id = types.FlavorResourceType.transform(
@ -86,6 +96,12 @@ class ImageResourceTypeTestCase(test.TestCase):
self.clients.glance().images._cache(image1)
image2 = fakes.FakeResource(name="cirros-0.3.1-uec-ramdisk", id="101")
self.clients.glance().images._cache(image2)
image3 = fakes.FakeResource(name="cirros-0.3.1-uec-ramdisk-copy",
id="102")
self.clients.glance().images._cache(image3)
image4 = fakes.FakeResource(name="cirros-0.3.1-uec-ramdisk-copy",
id="103")
self.clients.glance().images._cache(image4)
def test_transform_by_id(self):
resource_config = {"id": "100"}
@ -95,7 +111,7 @@ class ImageResourceTypeTestCase(test.TestCase):
self.assertEqual(image_id, "100")
def test_transform_by_name(self):
resource_config = {"name": "cirros-0.3.1-uec"}
resource_config = {"name": "^cirros-0.3.1-uec$"}
image_id = types.ImageResourceType.transform(
clients=self.clients,
resource_config=resource_config)
@ -107,6 +123,12 @@ class ImageResourceTypeTestCase(test.TestCase):
types.ImageResourceType.transform, self.clients,
resource_config)
def test_transform_by_name_match_multiple(self):
resource_config = {"name": "cirros-0.3.1-uec-ramdisk-copy"}
self.assertRaises(exceptions.InvalidScenarioArgument,
types.ImageResourceType.transform, self.clients,
resource_config)
def test_transform_by_regex(self):
resource_config = {"regex": "-uec$"}
image_id = types.ImageResourceType.transform(
@ -228,4 +250,4 @@ class PreprocessTestCase(test.TestCase):
attr_name="preprocessors")
mock_osclients.Clients.assert_called_once_with(
context["admin"]["endpoint"])
self.assertEqual({"a": 20, "b": 20}, result)
self.assertEqual({"a": 20, "b": 20}, result)