From 783837041c5a09425b1e9c8c7250990162fa0a97 Mon Sep 17 00:00:00 2001 From: Rajesh Tailor Date: Thu, 3 Sep 2015 04:43:35 -0700 Subject: [PATCH] Add boot-server-from-volume-and-resize for nova benchmark Added boot-server-from-volume-and-resize for nova benchmark. Partially-Implements: blueprint benchmark-scenarios-for-nova Change-Id: Ib24022ff975dc7e02fd4469ed7bf796e16878eb4 --- rally-jobs/nova.yaml | 27 +++++++++ .../openstack/scenarios/nova/servers.py | 57 +++++++++++++++++++ .../nova/boot-from-volume-and-resize.json | 35 ++++++++++++ .../nova/boot-from-volume-and-resize.yaml | 25 ++++++++ .../openstack/scenarios/nova/test_servers.py | 42 ++++++++++++++ 5 files changed, 186 insertions(+) create mode 100644 samples/tasks/scenarios/nova/boot-from-volume-and-resize.json create mode 100644 samples/tasks/scenarios/nova/boot-from-volume-and-resize.yaml diff --git a/rally-jobs/nova.yaml b/rally-jobs/nova.yaml index 471f7027..1b9a24cf 100644 --- a/rally-jobs/nova.yaml +++ b/rally-jobs/nova.yaml @@ -372,6 +372,33 @@ failure_rate: max: 0 + NovaServers.boot_server_from_volume_and_resize: + - + args: + flavor: + name: "m1.tiny" + image: + name: {{image_name}} + to_flavor: + name: "m1.small" + volume_size: 1 + confirm: true + force_delete: false + do_delete: true + boot_server_kwargs: {} + create_volume_kwargs: {} + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 + NovaServers.boot_and_bounce_server: - args: diff --git a/rally/plugins/openstack/scenarios/nova/servers.py b/rally/plugins/openstack/scenarios/nova/servers.py index ef96963d..5bc77a16 100644 --- a/rally/plugins/openstack/scenarios/nova/servers.py +++ b/rally/plugins/openstack/scenarios/nova/servers.py @@ -417,6 +417,63 @@ class NovaServers(utils.NovaScenario, self._delete_volume(volume) self._delete_server(server, force=force_delete) + @types.set(image=types.ImageResourceType, + flavor=types.FlavorResourceType, + to_flavor=types.FlavorResourceType) + @validation.image_valid_on_flavor("flavor", "image") + @validation.required_services(consts.Service.NOVA, consts.Service.CINDER) + @validation.required_openstack(users=True) + @scenario.configure(context={"cleanup": ["nova", "cinder"]}) + def boot_server_from_volume_and_resize( + self, image, flavor, to_flavor, volume_size, min_sleep=0, + max_sleep=0, force_delete=False, confirm=True, do_delete=True, + boot_server_kwargs=None, create_volume_kwargs=None): + """Boot a server from volume, then resize and delete it. + + The scenario first creates a volume and then a server. + Optional 'min_sleep' and 'max_sleep' parameters allow the scenario + to simulate a pause between volume creation and deletion + (of random duration from [min_sleep, max_sleep]). + + This test will confirm the resize by default, + or revert the resize if confirm is set to false. + + :param image: image to be used to boot an instance + :param flavor: flavor to be used to boot an instance + :param to_flavor: flavor to be used to resize the booted instance + :param volume_size: volume size (in GB) + :param min_sleep: Minimum sleep time in seconds (non-negative) + :param max_sleep: Maximum sleep time in seconds (non-negative) + :param force_delete: True if force_delete should be used + :param confirm: True if need to confirm resize else revert resize + :param do_delete: True if resources needs to be deleted explicitly + else use rally cleanup to remove resources + :param boot_server_kwargs: optional arguments for VM creation + :param create_volume_kwargs: optional arguments for volume creation + """ + boot_server_kwargs = boot_server_kwargs or {} + create_volume_kwargs = create_volume_kwargs or {} + + if boot_server_kwargs.get("block_device_mapping"): + LOG.warning("Using already existing volume is not permitted.") + + volume = self._create_volume(volume_size, imageRef=image, + **create_volume_kwargs) + boot_server_kwargs["block_device_mapping"] = { + "vda": "%s:::1" % volume.id} + + server = self._boot_server(image, flavor, **boot_server_kwargs) + self.sleep_between(min_sleep, max_sleep) + self._resize(server, to_flavor) + + if confirm: + self._resize_confirm(server) + else: + self._resize_revert(server) + + if do_delete: + self._delete_server(server, force=force_delete) + @types.set(image=types.ImageResourceType, flavor=types.FlavorResourceType) @validation.image_valid_on_flavor("flavor", "image") diff --git a/samples/tasks/scenarios/nova/boot-from-volume-and-resize.json b/samples/tasks/scenarios/nova/boot-from-volume-and-resize.json new file mode 100644 index 00000000..1d138ad8 --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-from-volume-and-resize.json @@ -0,0 +1,35 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{ + "NovaServers.boot_server_from_volume_and_resize": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "^cirros.*uec$" + }, + "to_flavor": { + "name": "m1.small" + }, + "confirm": true, + "volume_size": 1, + "force_delete": false, + "do_delete": true, + "boot_server_kwargs": {}, + "create_volume_kwargs": {} + }, + "runner": { + "type": "constant", + "times": 10, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/boot-from-volume-and-resize.yaml b/samples/tasks/scenarios/nova/boot-from-volume-and-resize.yaml new file mode 100644 index 00000000..59373de2 --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-from-volume-and-resize.yaml @@ -0,0 +1,25 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +--- + NovaServers.boot_server_from_volume_and_resize: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "^cirros.*uec$" + to_flavor: + name: "m1.small" + confirm: true + volume_size: 1 + force_delete: false + do_delete: true + boot_server_kwargs: {} + create_volume_kwargs: {} + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_servers.py b/tests/unit/plugins/openstack/scenarios/nova/test_servers.py index 3d1badf0..95f275ed 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_servers.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_servers.py @@ -457,6 +457,48 @@ class NovaServersTestCase(test.ScenarioTestCase): scenario._delete_server.assert_called_once_with(fake_server, force=False) + @ddt.data({"confirm": True, "do_delete": True}, + {"confirm": False, "do_delete": True}) + @ddt.unpack + def test_boot_server_from_volume_and_resize(self, confirm=False, + do_delete=False): + fake_server = object() + flavor = mock.MagicMock() + to_flavor = mock.MagicMock() + scenario = servers.NovaServers(self.context) + scenario._boot_server = mock.MagicMock(return_value=fake_server) + scenario.generate_random_name = mock.MagicMock(return_value="name") + scenario._resize_confirm = mock.MagicMock() + scenario._resize_revert = mock.MagicMock() + scenario._resize = mock.MagicMock() + scenario.sleep_between = mock.MagicMock() + scenario._delete_server = mock.MagicMock() + + fake_volume = fakes.FakeVolumeManager().create() + fake_volume.id = "volume_id" + scenario._create_volume = mock.MagicMock(return_value=fake_volume) + + volume_size = 10 + scenario.boot_server_from_volume_and_resize( + "img", flavor, to_flavor, volume_size, min_sleep=10, + max_sleep=20, confirm=confirm, do_delete=do_delete) + + scenario._create_volume.assert_called_once_with(10, imageRef="img") + scenario._boot_server.assert_called_once_with( + "img", flavor, + block_device_mapping={"vda": "volume_id:::1"}) + scenario.sleep_between.assert_called_once_with(10, 20) + scenario._resize.assert_called_once_with(fake_server, to_flavor) + + if confirm: + scenario._resize_confirm.assert_called_once_with(fake_server) + else: + scenario._resize_revert.assert_called_once_with(fake_server) + + if do_delete: + scenario._delete_server.assert_called_once_with(fake_server, + force=False) + def test_boot_and_live_migrate_server(self): fake_server = mock.MagicMock()