From a1c8e313bc597b83613cd44fe55c5d458ea43daf Mon Sep 17 00:00:00 2001 From: Anton Arefiev Date: Mon, 12 Jan 2015 16:55:24 +0200 Subject: [PATCH] Add image arg for creating volume from image This change adds image arg to next scenarios: create_volume, create_and_delete_volume, create_and_list_volume. Add nullable arg to image_exists for specify image require. Change-Id: Idb2f80efa24d6f721bbdafc4644afc68d59552ac --- rally-jobs/rally-neutron.yaml | 49 +++++++++++++++++++ rally/benchmark/scenarios/cinder/volumes.py | 26 ++++++++-- rally/benchmark/validation.py | 6 ++- .../create-from-image-and-delete-volume.json | 23 +++++++++ .../create-from-image-and-delete-volume.yaml | 15 ++++++ .../scenarios/cinder/test_volumes.py | 35 ++++++++++++- tests/unit/benchmark/test_validation.py | 6 +++ 7 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.json create mode 100644 samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.yaml diff --git a/rally-jobs/rally-neutron.yaml b/rally-jobs/rally-neutron.yaml index 1e80dd0f5e..88b510b493 100644 --- a/rally-jobs/rally-neutron.yaml +++ b/rally-jobs/rally-neutron.yaml @@ -503,6 +503,22 @@ sla: failure_rate: max: 0 + - + args: + size: 1 + image: + name: {{image_name}} + runner: + type: "constant" + times: 3 + concurrency: 3 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 CinderVolumes.create_and_list_volume: - @@ -520,6 +536,23 @@ sla: failure_rate: max: 0 + - + args: + size: 1 + detailed: True + image: + name: {{image_name}} + runner: + type: "constant" + times: 3 + concurrency: 3 + context: + users: + tenants: 1 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 CinderVolumes.list_volumes: - @@ -555,6 +588,22 @@ sla: failure_rate: max: 0 + - + args: + size: 1 + image: + name: {{image_name}} + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 CinderVolumes.create_and_extend_volume: - diff --git a/rally/benchmark/scenarios/cinder/volumes.py b/rally/benchmark/scenarios/cinder/volumes.py index f2a448a0a6..b2f7e86149 100755 --- a/rally/benchmark/scenarios/cinder/volumes.py +++ b/rally/benchmark/scenarios/cinder/volumes.py @@ -30,10 +30,13 @@ class CinderVolumes(utils.CinderScenario, nova_utils.NovaScenario): """Benchmark scenarios for Cinder Volumes.""" + @types.set(image=types.ImageResourceType) + @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @base.scenario(context={"cleanup": ["cinder"]}) - def create_and_list_volume(self, size, detailed=True, **kwargs): + def create_and_list_volume(self, size, detailed=True, + image=None, **kwargs): """Create a volume and list all volumes. Measure the "cinder volume-list" command performance. @@ -47,8 +50,12 @@ class CinderVolumes(utils.CinderScenario, :param size: volume size (in GB) :param detailed: determines whether the volume listing should contain detailed information about all of them + :param image: image to be used to create volume :param kwargs: optional args to create a volume """ + if image: + kwargs["imageRef"] = image + self._create_volume(size, **kwargs) self._list_volumes(detailed) @@ -67,10 +74,13 @@ class CinderVolumes(utils.CinderScenario, self._list_volumes(detailed) + @types.set(image=types.ImageResourceType) + @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @base.scenario(context={"cleanup": ["cinder"]}) - def create_and_delete_volume(self, size, min_sleep=0, max_sleep=0, + def create_and_delete_volume(self, size, image=None, + min_sleep=0, max_sleep=0, **kwargs): """Create and then delete a volume. @@ -80,28 +90,38 @@ class CinderVolumes(utils.CinderScenario, [min_sleep, max_sleep]). :param size: volume size (in GB) + :param image: image to be used to create volume :param min_sleep: minimum sleep time between volume creation and deletion (in seconds) :param max_sleep: maximum sleep time between volume creation and deletion (in seconds) :param kwargs: optional args to create a volume """ + if image: + kwargs["imageRef"] = image + volume = self._create_volume(size, **kwargs) self.sleep_between(min_sleep, max_sleep) self._delete_volume(volume) + @types.set(image=types.ImageResourceType) + @validation.image_exists("image", nullable=True) @validation.required_services(consts.Service.CINDER) @validation.required_openstack(users=True) @base.scenario(context={"cleanup": ["cinder"]}) - def create_volume(self, size, **kwargs): + def create_volume(self, size, image=None, **kwargs): """Create a volume. Good test to check how influence amount of active volumes on performance of creating new. :param size: volume size (in GB) + :param image: image to be used to create volume :param kwargs: optional args to create a volume """ + if image: + kwargs["imageRef"] = image + self._create_volume(size, **kwargs) @validation.required_services(consts.Service.CINDER) diff --git a/rally/benchmark/validation.py b/rally/benchmark/validation.py index 6084dc56fb..a543675d5b 100644 --- a/rally/benchmark/validation.py +++ b/rally/benchmark/validation.py @@ -198,12 +198,16 @@ def _get_validated_flavor(config, clients, param_name): @validator -def image_exists(config, clients, deployment, param_name): +def image_exists(config, clients, deployment, param_name, nullable=False): """Returns validator for image_id :param param_name: defines which variable should be used to get image id value. + :param nullable: defines image id param is required """ + image_value = config.get("args", {}).get(param_name) + if not image_value and nullable: + return ValidationResult(True) return _get_validated_image(config, clients, param_name)[0] diff --git a/samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.json b/samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.json new file mode 100644 index 0000000000..25f6081b9d --- /dev/null +++ b/samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.json @@ -0,0 +1,23 @@ +{ + "CinderVolumes.create_and_delete_volume": [ + { + "args": { + "size": 1, + "image": { + "name": "^cirros.*uec$" + } + }, + "runner": { + "type": "constant", + "times": 2, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.yaml b/samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.yaml new file mode 100644 index 0000000000..7458ebfcd8 --- /dev/null +++ b/samples/tasks/scenarios/cinder/create-from-image-and-delete-volume.yaml @@ -0,0 +1,15 @@ +--- + CinderVolumes.create_and_delete_volume: + - + args: + size: 1 + image: + name: "^cirros.*uec$" + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 \ No newline at end of file diff --git a/tests/unit/benchmark/scenarios/cinder/test_volumes.py b/tests/unit/benchmark/scenarios/cinder/test_volumes.py index 4c1430d4dc..791fed67a7 100644 --- a/tests/unit/benchmark/scenarios/cinder/test_volumes.py +++ b/tests/unit/benchmark/scenarios/cinder/test_volumes.py @@ -50,7 +50,8 @@ class CinderServersTestCase(test.TestCase): scenario.sleep_between = mock.MagicMock() scenario._delete_volume = mock.MagicMock() - scenario.create_and_delete_volume(1, 10, 20, fakearg="f") + scenario.create_and_delete_volume(size=1, min_sleep=10, max_sleep=20, + fakearg="f") scenario._create_volume.assert_called_once_with(1, fakearg="f") scenario.sleep_between.assert_called_once_with(10, 20) @@ -79,6 +80,38 @@ class CinderServersTestCase(test.TestCase): scenario.sleep_between.assert_called_once_with(10, 20) scenario._delete_volume.assert_called_once_with(fake_volume) + def test_create_from_image_and_delete_volume(self): + fake_volume = mock.MagicMock() + scenario = volumes.CinderVolumes() + scenario._create_volume = mock.MagicMock(return_value=fake_volume) + scenario._delete_volume = mock.MagicMock() + + scenario.create_and_delete_volume(1, image="fake_image") + scenario._create_volume.assert_called_once_with(1, + imageRef="fake_image") + + scenario._delete_volume.assert_called_once_with(fake_volume) + + def test_create_volume_from_image(self): + fake_volume = mock.MagicMock() + scenario = volumes.CinderVolumes() + scenario._create_volume = mock.MagicMock(return_value=fake_volume) + + scenario.create_volume(1, image="fake_image") + scenario._create_volume.assert_called_once_with(1, + imageRef="fake_image") + + def test_create_volume_from_image_and_list(self): + fake_volume = mock.MagicMock() + scenario = volumes.CinderVolumes() + scenario._create_volume = mock.MagicMock(return_value=fake_volume) + scenario._list_volumes = mock.MagicMock() + + scenario.create_and_list_volume(1, True, "fake_image") + scenario._create_volume.assert_called_once_with(1, + imageRef="fake_image") + scenario._list_volumes.assert_called_once_with(True) + def test_create_and_delete_snapshot(self): fake_snapshot = mock.MagicMock() scenario = volumes.CinderVolumes( diff --git a/tests/unit/benchmark/test_validation.py b/tests/unit/benchmark/test_validation.py index a0c9e8df5b..0051307a40 100644 --- a/tests/unit/benchmark/test_validation.py +++ b/tests/unit/benchmark/test_validation.py @@ -230,6 +230,12 @@ class ValidatorsTestCase(test.TestCase): result = validator({}, "clients", "deployment") self.assertFalse(result.is_valid, result.msg) + def test_image_exists_nullable(self): + validator = self._unwrap_validator(validation.image_exists, + "param", nullable=True) + result = validator({}, "clients", "deployment") + self.assertTrue(result.is_valid, result.msg) + def test_flavor_exists(self): validator = self._unwrap_validator(validation.flavor_exists, "param") result = validator({}, "clients", "deployment")