From 6764787aa84039fc20c41edf8b145918554db489 Mon Sep 17 00:00:00 2001 From: Sirisha Areti Date: Tue, 20 Oct 2015 22:41:12 -0700 Subject: [PATCH] Adds nova show and nova console output plugins Nova provides show and console output functionalities for a server. Currently, there isn't a benchmark provided by rally that does the above. This commit adds plugins that call nova client's get and get console output methods for a given server, allowing to use those for benchmarking. This patch also includes functional and unit tests for newly added plugins. Co-Authored-By: Michal Stolarczyk Change-Id: Ica8642ca8463b1bcba936e3c1d392b4588a56dc2 --- rally-jobs/nova.yaml | 38 ++++++++++++++++ .../openstack/scenarios/nova/servers.py | 43 +++++++++++++++++++ .../plugins/openstack/scenarios/nova/utils.py | 22 ++++++++++ .../nova/boot-and-get-console-server.json | 27 ++++++++++++ .../nova/boot-and-get-console-server.yaml | 18 ++++++++ .../scenarios/nova/boot-and-show-server.json | 27 ++++++++++++ .../scenarios/nova/boot-and-show-server.yaml | 18 ++++++++ .../openstack/scenarios/nova/test_servers.py | 36 ++++++++++++++++ .../openstack/scenarios/nova/test_utils.py | 18 ++++++++ 9 files changed, 247 insertions(+) create mode 100644 samples/tasks/scenarios/nova/boot-and-get-console-server.json create mode 100644 samples/tasks/scenarios/nova/boot-and-get-console-server.yaml create mode 100644 samples/tasks/scenarios/nova/boot-and-show-server.json create mode 100644 samples/tasks/scenarios/nova/boot-and-show-server.yaml diff --git a/rally-jobs/nova.yaml b/rally-jobs/nova.yaml index 1963ff9b6c..471f70272a 100644 --- a/rally-jobs/nova.yaml +++ b/rally-jobs/nova.yaml @@ -285,6 +285,44 @@ failure_rate: max: 0 + NovaServers.boot_and_show_server: + - + args: + image: + name: {{image_name}} + flavor: + name: "m1.tiny" + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 + + NovaServers.boot_and_get_console_output: + - + args: + image: + name: {{image_name}} + flavor: + name: "m1.tiny" + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 + NovaServers.resize_server: - args: diff --git a/rally/plugins/openstack/scenarios/nova/servers.py b/rally/plugins/openstack/scenarios/nova/servers.py index 9628a075cf..ef96963da5 100644 --- a/rally/plugins/openstack/scenarios/nova/servers.py +++ b/rally/plugins/openstack/scenarios/nova/servers.py @@ -693,3 +693,46 @@ class NovaServers(utils.NovaScenario, self.clients, self.task).create_floating_ip( tenant_id=server.tenant_id) self._associate_floating_ip(server, address["ip"]) + + @types.set(image=types.ImageResourceType, + flavor=types.FlavorResourceType) + @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_show_server(self, image, flavor, **kwargs): + """Show server details. + + This simple scenario tests the nova show command by retrieving + the server details. + :param image: image to be used to boot an instance + :param flavor: flavor to be used to boot an instance + :param kwargs: Optional additional arguments for server creation + + :returns: Server details + """ + server = self._boot_server(image, flavor, **kwargs) + self._show_server(server) + + @types.set(image=types.ImageResourceType, + flavor=types.FlavorResourceType) + @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_get_console_output(self, image, flavor, + length=None, **kwargs): + """Get text console output from server. + + This simple scenario tests the nova console-log command by retrieving + the text console log output. + :param image: image to be used to boot an instance + :param flavor: flavor to be used to boot an instance + :param length: The number of tail log lines you would like to retrieve. + None (default value) or -1 means unlimited length. + :param kwargs: Optional additional arguments for server creation + + :returns: Text console log output for server + """ + server = self._boot_server(image, flavor, **kwargs) + self._get_server_console_output(server, length) diff --git a/rally/plugins/openstack/scenarios/nova/utils.py b/rally/plugins/openstack/scenarios/nova/utils.py index 06f4deaf4b..4e51873652 100644 --- a/rally/plugins/openstack/scenarios/nova/utils.py +++ b/rally/plugins/openstack/scenarios/nova/utils.py @@ -169,6 +169,28 @@ class NovaScenario(scenario.OpenStackScenario): """ self._do_server_reboot(server, "SOFT") + @atomic.action_timer("nova.show_server") + def _show_server(self, server): + """Show server details. + + :param server: The server to get details for. + + :returns: Server details + """ + return self.clients("nova").servers.get(server) + + @atomic.action_timer("nova.get_console_output_server") + def _get_server_console_output(self, server, length=None): + """Get text of a console log output from a server. + + :param server: The server whose console output to retrieve + :param length: The number of tail log lines you would like to retrieve. + + :returns: Text console output from server + """ + return self.clients("nova").servers.get_console_output(server, + length=length) + @atomic.action_timer("nova.reboot_server") def _reboot_server(self, server): """Reboot a server with hard reboot. diff --git a/samples/tasks/scenarios/nova/boot-and-get-console-server.json b/samples/tasks/scenarios/nova/boot-and-get-console-server.json new file mode 100644 index 0000000000..f7fa99153e --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-and-get-console-server.json @@ -0,0 +1,27 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{% set image_name = image_name or "^cirros.*uec$" %} +{ + "NovaServers.boot_and_get_console_output": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "{{image_name}}" + } + }, + "runner": { + "type": "constant", + "times": 1, + "concurrency": 1 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/boot-and-get-console-server.yaml b/samples/tasks/scenarios/nova/boot-and-get-console-server.yaml new file mode 100644 index 0000000000..251a58447e --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-and-get-console-server.yaml @@ -0,0 +1,18 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{% set image_name = image_name or "^cirros.*uec$" %} +--- + NovaServers.boot_and_get_console_output: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "{{image_name}}" + runner: + type: "constant" + times: 1 + concurrency: 1 + context: + users: + tenants: 1 + users_per_tenant: 1 diff --git a/samples/tasks/scenarios/nova/boot-and-show-server.json b/samples/tasks/scenarios/nova/boot-and-show-server.json new file mode 100644 index 0000000000..d837b1588e --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-and-show-server.json @@ -0,0 +1,27 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{% set image_name = image_name or "^cirros.*uec$" %} +{ + "NovaServers.boot_and_show_server": [ + { + "args": { + "flavor": { + "name": "{{flavor_name}}" + }, + "image": { + "name": "{{image_name}}" + } + }, + "runner": { + "type": "constant", + "times": 1, + "concurrency": 1 + }, + "context": { + "users": { + "tenants": 1, + "users_per_tenant": 1 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/boot-and-show-server.yaml b/samples/tasks/scenarios/nova/boot-and-show-server.yaml new file mode 100644 index 0000000000..b76abd2baf --- /dev/null +++ b/samples/tasks/scenarios/nova/boot-and-show-server.yaml @@ -0,0 +1,18 @@ +{% set flavor_name = flavor_name or "m1.tiny" %} +{% set image_name = image_name or "^cirros.*uec$" %} +--- + NovaServers.boot_and_show_server: + - + args: + flavor: + name: "{{flavor_name}}" + image: + name: "{{image_name}}" + runner: + type: "constant" + times: 1 + concurrency: 1 + context: + users: + tenants: 1 + users_per_tenant: 1 diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_servers.py b/tests/unit/plugins/openstack/scenarios/nova/test_servers.py index 1eda9ab748..3d1badf01f 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_servers.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_servers.py @@ -621,6 +621,42 @@ class NovaServersTestCase(test.ScenarioTestCase): scenario._rebuild_server.assert_called_once_with(server, to_image) scenario._delete_server.assert_called_once_with(server) + def test_boot_and_show_server(self): + server = fakes.FakeServer() + image = fakes.FakeImage() + flavor = fakes.FakeFlavor() + + scenario = servers.NovaServers(self.context) + scenario._boot_server = mock.MagicMock(return_value=server) + scenario._show_server = mock.MagicMock() + + scenario.boot_and_show_server(image, flavor, fakearg="fakearg") + + scenario._boot_server.assert_called_once_with(image, flavor, + fakearg="fakearg") + scenario._show_server.assert_called_once_with(server) + + @ddt.data({"length": None}, + {"length": 10}) + @ddt.unpack + def test_boot_and_get_console_server(self, length): + server = fakes.FakeServer() + image = fakes.FakeImage() + flavor = fakes.FakeFlavor() + kwargs = {"fakearg": "fakearg"} + + scenario = servers.NovaServers(self.context) + scenario._boot_server = mock.MagicMock(return_value=server) + scenario._get_server_console_output = mock.MagicMock() + + scenario.boot_and_get_console_output(image, flavor, length, + **kwargs) + + scenario._boot_server.assert_called_once_with(image, flavor, + **kwargs) + scenario._get_server_console_output.assert_called_once_with(server, + length) + @mock.patch(NOVA_SERVERS_MODULE + ".network_wrapper.wrap") def test_boot_and_associate_floating_ip(self, mock_wrap): scenario = servers.NovaServers(self.context) diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py index 1c651d6ad7..b47a43e6b7 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py @@ -489,6 +489,24 @@ class NovaScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(scenario.atomic_actions(), "nova.boot_servers") + def test__show_server(self): + nova_scenario = utils.NovaScenario(context=self.context) + nova_scenario._show_server(self.server) + self.clients("nova").servers.get.assert_called_once_with( + self.server + ) + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.show_server") + + def test__get_console_server(self): + nova_scenario = utils.NovaScenario(context=self.context) + nova_scenario._get_server_console_output(self.server) + self.clients( + "nova").servers.get_console_output.assert_called_once_with( + self.server, length=None) + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.get_console_output_server") + def test__associate_floating_ip(self): nova_scenario = utils.NovaScenario(context=self.context) nova_scenario._associate_floating_ip(self.server, self.floating_ip)