diff --git a/rally-jobs/nova.yaml b/rally-jobs/nova.yaml index 5e656ed7..7253fcf4 100644 --- a/rally-jobs/nova.yaml +++ b/rally-jobs/nova.yaml @@ -1035,3 +1035,22 @@ sla: failure_rate: max: 0 + + NovaServers.boot_and_update_server: + - + args: + flavor: + name: {{flavor_name}} + image: + name: {{image_name}} + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/rally/plugins/openstack/scenarios/nova/servers.py b/rally/plugins/openstack/scenarios/nova/servers.py old mode 100644 new mode 100755 index 18a861d2..4982de08 --- a/rally/plugins/openstack/scenarios/nova/servers.py +++ b/rally/plugins/openstack/scenarios/nova/servers.py @@ -861,3 +861,24 @@ class NovaServers(utils.NovaScenario, """ server = self._boot_server(image, flavor, **kwargs) self._get_server_console_output(server, length) + + @types.convert(image={"type": "glance_image"}, + flavor={"type": "nova_flavor"}) + @validation.image_valid_on_flavor("flavor", "image") + @validation.required_services(consts.Service.NOVA) + @validation.required_openstack(users=True) + @scenario.configure(context={"cleanup": ["nova"]}) + def boot_and_update_server(self, image, flavor, description=None, + **kwargs): + """Boot a server, then update its name and description. + + The scenario first creates a server, then update it. + Assumes that cleanup is done elsewhere. + + :param image: image to be used to boot an instance + :param flavor: flavor to be used to boot an instance + :param description: update the server description + :param kwargs: Optional additional arguments for server creation + """ + server = self._boot_server(image, flavor, **kwargs) + self._update_server(server, description) diff --git a/rally/plugins/openstack/scenarios/nova/utils.py b/rally/plugins/openstack/scenarios/nova/utils.py old mode 100644 new mode 100755 index b43f5403..b6a4438f --- a/rally/plugins/openstack/scenarios/nova/utils.py +++ b/rally/plugins/openstack/scenarios/nova/utils.py @@ -969,3 +969,18 @@ class NovaScenario(scenario.OpenStackScenario): :param flavor: List access rules for flavor instance or flavor ID """ return self.admin_clients("nova").flavor_access.list(flavor=flavor) + + @atomic.action_timer("nova.update_server") + def _update_server(self, server, description=None): + """update the server's name and description. + + :param server: Server object + :param description: update the server description + :returns: The updated server + """ + new_name = self.generate_random_name() + if description: + return server.update(name=new_name, + description=description) + else: + return server.update(name=new_name) diff --git a/samples/tasks/scenarios/nova/boot-and-update-server.json b/samples/tasks/scenarios/nova/boot-and-update-server.json new file mode 100644 index 00000000..1c7727d6 --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-and-update-server.json @@ -0,0 +1,26 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{ + "NovaServers.boot_and_update_server": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "^cirros.*uec$" + } + }, + "runner": { + "type": "constant", + "times": 10, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/boot-and-update-server.yaml b/samples/tasks/scenarios/nova/boot-and-update-server.yaml new file mode 100644 index 00000000..6692e6de --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-and-update-server.yaml @@ -0,0 +1,17 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +--- + NovaServers.boot_and_update_server: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "^cirros.*uec$" + 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 old mode 100644 new mode 100755 index 8004429d..8451145f --- a/tests/unit/plugins/openstack/scenarios/nova/test_servers.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_servers.py @@ -761,3 +761,16 @@ class NovaServersTestCase(test.ScenarioTestCase): tenant_id=server.tenant_id) scenario._associate_floating_ip.assert_called_once_with( server, net_wrap.create_floating_ip.return_value["ip"]) + + def test_boot_and_update_server(self): + scenario = servers.NovaServers(self.context) + scenario._boot_server = mock.Mock() + scenario._update_server = mock.Mock() + + scenario.boot_and_update_server("img", "flavor", + "desp", + fakearg="fakearg") + scenario._boot_server.assert_called_once_with("img", "flavor", + fakearg="fakearg") + scenario._update_server.assert_called_once_with( + scenario._boot_server.return_value, "desp") diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py old mode 100644 new mode 100755 index 62802d61..76553407 --- a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py @@ -976,3 +976,28 @@ class NovaScenarioTestCase(test.ScenarioTestCase): random_name, 500, 1, 1, fakearg="fakearg") self._test_atomic_action_timer(nova_scenario.atomic_actions(), "nova.create_flavor") + + def test__update_server(self): + server = mock.Mock() + nova_scenario = utils.NovaScenario() + nova_scenario.generate_random_name = mock.Mock( + return_value="new_name") + server.update = mock.Mock() + + result = nova_scenario._update_server(server) + self.assertEqual(result, server.update.return_value) + nova_scenario.generate_random_name.assert_called_once_with() + server.update.assert_called_once_with(name="new_name") + + nova_scenario.generate_random_name.reset_mock() + server.update.reset_mock() + + result = nova_scenario._update_server(server, + description="desp") + self.assertEqual(result, server.update.return_value) + nova_scenario.generate_random_name.assert_called_once_with() + server.update.assert_called_once_with(name="new_name", + description="desp") + + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.update_server")