diff --git a/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.json b/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.json index 19f613c267..4d1c1637a3 100644 --- a/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.json +++ b/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.json @@ -4,7 +4,7 @@ "args": { "volume_size": 10, "image": { - "name": "cirros-0.3.2-x86_64-uec" + "name": "^cirros.*uec$" }, "flavor": { "name": "m1.nano" diff --git a/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.yaml b/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.yaml index 7189b41cfe..38af4e9c90 100644 --- a/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.yaml +++ b/doc/samples/tasks/scenarios/cinder/create-and-attach-volume.yaml @@ -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: diff --git a/doc/samples/tasks/scenarios/nova/boot-and-delete.json b/doc/samples/tasks/scenarios/nova/boot-and-delete.json index 4316b07df9..fe2ffa9055 100644 --- a/doc/samples/tasks/scenarios/nova/boot-and-delete.json +++ b/doc/samples/tasks/scenarios/nova/boot-and-delete.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" } }, "runner": { diff --git a/doc/samples/tasks/scenarios/nova/boot-and-delete.yaml b/doc/samples/tasks/scenarios/nova/boot-and-delete.yaml index c814737908..534f411de0 100644 --- a/doc/samples/tasks/scenarios/nova/boot-and-delete.yaml +++ b/doc/samples/tasks/scenarios/nova/boot-and-delete.yaml @@ -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 diff --git a/doc/samples/tasks/scenarios/nova/boot-and-list.json b/doc/samples/tasks/scenarios/nova/boot-and-list.json index 810a9ef85c..123cd5f53e 100644 --- a/doc/samples/tasks/scenarios/nova/boot-and-list.json +++ b/doc/samples/tasks/scenarios/nova/boot-and-list.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" }, "detailed": true }, diff --git a/doc/samples/tasks/scenarios/nova/boot-and-list.yaml b/doc/samples/tasks/scenarios/nova/boot-and-list.yaml index a474a356ce..443b73457a 100644 --- a/doc/samples/tasks/scenarios/nova/boot-and-list.yaml +++ b/doc/samples/tasks/scenarios/nova/boot-and-list.yaml @@ -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" diff --git a/doc/samples/tasks/scenarios/nova/boot-bounce-delete.json b/doc/samples/tasks/scenarios/nova/boot-bounce-delete.json index 7ebdde4518..97277dad2c 100644 --- a/doc/samples/tasks/scenarios/nova/boot-bounce-delete.json +++ b/doc/samples/tasks/scenarios/nova/boot-bounce-delete.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" }, "actions": [ {"hard_reboot": 1}, diff --git a/doc/samples/tasks/scenarios/nova/boot-bounce-delete.yaml b/doc/samples/tasks/scenarios/nova/boot-bounce-delete.yaml index e94ec5b6c8..81a6977930 100644 --- a/doc/samples/tasks/scenarios/nova/boot-bounce-delete.yaml +++ b/doc/samples/tasks/scenarios/nova/boot-bounce-delete.yaml @@ -5,7 +5,7 @@ flavor: name: "m1.nano" image: - name: "cirros-0.3.1-x86_64-uec" + name: "^cirros.*uec$" actions: - hard_reboot: 1 diff --git a/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.json b/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.json index 140cc3decc..129eee5332 100644 --- a/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.json +++ b/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" }, "volume_size": 10 }, diff --git a/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.yaml b/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.yaml index 78b0c6a12f..cb92990887 100644 --- a/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.yaml +++ b/doc/samples/tasks/scenarios/nova/boot-from-volume-and-delete.yaml @@ -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" diff --git a/doc/samples/tasks/scenarios/nova/boot-from-volume.json b/doc/samples/tasks/scenarios/nova/boot-from-volume.json index b6a500b183..4dfccfaa21 100644 --- a/doc/samples/tasks/scenarios/nova/boot-from-volume.json +++ b/doc/samples/tasks/scenarios/nova/boot-from-volume.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" }, "volume_size": 10 }, diff --git a/doc/samples/tasks/scenarios/nova/boot-from-volume.yaml b/doc/samples/tasks/scenarios/nova/boot-from-volume.yaml index 7295b2e4c1..d8f8c2ad53 100644 --- a/doc/samples/tasks/scenarios/nova/boot-from-volume.yaml +++ b/doc/samples/tasks/scenarios/nova/boot-from-volume.yaml @@ -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" diff --git a/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.json b/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.json index 0b2ed1ec99..a83facede3 100644 --- a/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.json +++ b/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" } }, "runner": { diff --git a/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.yaml b/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.yaml index 7365aa5509..b0d657db03 100644 --- a/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.yaml +++ b/doc/samples/tasks/scenarios/nova/boot-snapshot-boot-delete.yaml @@ -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 diff --git a/doc/samples/tasks/scenarios/nova/boot.json b/doc/samples/tasks/scenarios/nova/boot.json index 00b6059416..5b3597f192 100644 --- a/doc/samples/tasks/scenarios/nova/boot.json +++ b/doc/samples/tasks/scenarios/nova/boot.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" } }, "runner": { diff --git a/doc/samples/tasks/scenarios/nova/boot.yaml b/doc/samples/tasks/scenarios/nova/boot.yaml index f37f97165a..2db4797f9a 100644 --- a/doc/samples/tasks/scenarios/nova/boot.yaml +++ b/doc/samples/tasks/scenarios/nova/boot.yaml @@ -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 diff --git a/doc/samples/tasks/scenarios/nova/resize-server.json b/doc/samples/tasks/scenarios/nova/resize-server.json index b6dad79598..c54af69ff1 100644 --- a/doc/samples/tasks/scenarios/nova/resize-server.json +++ b/doc/samples/tasks/scenarios/nova/resize-server.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" }, "to_flavor": { "name": "m1.small" diff --git a/doc/samples/tasks/scenarios/nova/resize-server.yaml b/doc/samples/tasks/scenarios/nova/resize-server.yaml index b9818bd373..ae577b2e04 100644 --- a/doc/samples/tasks/scenarios/nova/resize-server.yaml +++ b/doc/samples/tasks/scenarios/nova/resize-server.yaml @@ -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 diff --git a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json index a6e3dd848b..9ffebb6efb 100644 --- a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json +++ b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json @@ -6,7 +6,7 @@ "name": "m1.nano" }, "image": { - "name": "cirros-0.3.1-x86_64-uec" + "name": "^cirros.*uec$" }, "volume_args": { "size": 2 diff --git a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml index 1b17863dca..c8a091fb14 100644 --- a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml +++ b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml @@ -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" diff --git a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.json b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.json index a082592bcc..3bd01902c6 100644 --- a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.json +++ b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.json @@ -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", diff --git a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.yaml b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.yaml index 994b2216dd..c14d569106 100644 --- a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.yaml +++ b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete.yaml @@ -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 diff --git a/rally-scenarios/rally-neutron.yaml b/rally-scenarios/rally-neutron.yaml index c77300c529..34a6047571 100644 --- a/rally-scenarios/rally-neutron.yaml +++ b/rally-scenarios/rally-neutron.yaml @@ -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 diff --git a/rally-scenarios/rally.yaml b/rally-scenarios/rally.yaml index 8c5bee6197..ffd8471e7d 100644 --- a/rally-scenarios/rally.yaml +++ b/rally-scenarios/rally.yaml @@ -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" diff --git a/rally/benchmark/types.py b/rally/benchmark/types.py index 025284ab65..775ad2fbc5 100644 --- a/rally/benchmark/types.py +++ b/rally/benchmark/types.py @@ -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"))) \ No newline at end of file + name=resource_config.get("name"))) diff --git a/tests/unit/benchmark/test_types.py b/tests/unit/benchmark/test_types.py index ff9bb6b11f..8fd3c32c8d 100644 --- a/tests/unit/benchmark/test_types.py +++ b/tests/unit/benchmark/test_types.py @@ -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) \ No newline at end of file + self.assertEqual({"a": 20, "b": 20}, result)