From 0127c51f6b3c8d969972576b0c4472e6376f0766 Mon Sep 17 00:00:00 2001 From: maxinjian Date: Tue, 21 Feb 2017 15:09:03 -0500 Subject: [PATCH] Add NovaServerGroups.create_and_delete_server_group Create a server group, then delete it. Measure the "nova server-group-create" and "nova server-group-delete" command performance. Change-Id: I47cea5651f68dfb3d0b3e8bcb7889700d5087657 --- rally-jobs/nova.yaml | 24 +++- .../openstack/scenarios/nova/server_groups.py | 66 +++++++++- .../plugins/openstack/scenarios/nova/utils.py | 16 ++- .../nova/create-and-delete-server-group.json | 27 ++++ .../nova/create-and-delete-server-group.yaml | 15 +++ .../nova/create-and-get-server-group.json | 8 +- .../nova/create-and-get-server-group.yaml | 3 +- .../nova/create-and-list-server-groups.json | 8 +- .../nova/create-and-list-server-groups.yaml | 3 +- .../scenarios/nova/test_server_groups.py | 116 ++++++++++++------ .../openstack/scenarios/nova/test_utils.py | 16 ++- 11 files changed, 239 insertions(+), 63 deletions(-) create mode 100644 samples/tasks/scenarios/nova/create-and-delete-server-group.json create mode 100644 samples/tasks/scenarios/nova/create-and-delete-server-group.yaml diff --git a/rally-jobs/nova.yaml b/rally-jobs/nova.yaml index 78bbbfe6..8e28bd87 100755 --- a/rally-jobs/nova.yaml +++ b/rally-jobs/nova.yaml @@ -185,8 +185,7 @@ {% for s in (["affinity"], ["anti-affinity"]) %} - args: - kwargs: - policies: {{s}} + policies: {{s}} runner: type: "constant" times: 4 @@ -204,8 +203,7 @@ {% for s in (["affinity"], ["anti-affinity"]) %} - args: - kwargs: - policies: {{s}} + policies: {{s}} all_projects: false runner: type: "constant" @@ -220,6 +218,24 @@ max: 0 {% endfor %} + NovaServerGroups.create_and_delete_server_group: + {% for s in (["affinity"], ["anti-affinity"]) %} + - + args: + policies: {{s}} + runner: + type: "constant" + times: 4 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + {% endfor %} + NovaServers.suspend_and_resume_server: - args: diff --git a/rally/plugins/openstack/scenarios/nova/server_groups.py b/rally/plugins/openstack/scenarios/nova/server_groups.py index 19174741..45d7ad39 100755 --- a/rally/plugins/openstack/scenarios/nova/server_groups.py +++ b/rally/plugins/openstack/scenarios/nova/server_groups.py @@ -13,12 +13,16 @@ # License for the specific language governing permissions and limitations # under the License. +from rally.common import logging from rally import consts from rally.plugins.openstack import scenario from rally.plugins.openstack.scenarios.nova import utils from rally.task import validation +LOG = logging.getLogger(__name__) + + """Scenarios for Nova Group servers.""" @@ -29,17 +33,26 @@ from rally.task import validation platform="openstack") class CreateAndListServerGroups(utils.NovaScenario): - def run(self, all_projects=False, kwargs=None): + def run(self, policies=None, all_projects=False, kwargs=None): """Create a server group, then list all server groups. Measure the "nova server-group-create" and "nova server-group-list" command performance. + :param policies: Server group policy :param all_projects: If True, display server groups from all projects(Admin only) - :param kwargs: Server group name and policy + :param kwargs: The server group specifications to add. + DEPRECATED, specify arguments explicitly. """ - kwargs["name"] = self.generate_random_name() + if kwargs is None: + kwargs = { + "policies": policies + } + else: + LOG.warning("The argument `kwargs` is deprecated since" + " Rally 0.10.0. Specify all arguments from it" + " explicitly.") server_group = self._create_server_group(**kwargs) msg = ("Server Groups isn't created") self.assertTrue(server_group, err_msg=msg) @@ -59,18 +72,59 @@ class CreateAndListServerGroups(utils.NovaScenario): platform="openstack") class CreateAndGetServerGroup(utils.NovaScenario): - def run(self, kwargs=None): + def run(self, policies=None, kwargs=None): """Create a server group, then get its detailed information. Measure the "nova server-group-create" and "nova server-group-get" command performance. - :param kwargs: Server group name and policy + :param policies: Server group policy + :param kwargs: The server group specifications to add. + DEPRECATED, specify arguments explicitly. """ - kwargs["name"] = self.generate_random_name() + if kwargs is None: + kwargs = { + "policies": policies + } + else: + LOG.warning("The argument `kwargs` is deprecated since" + " Rally 0.10.0. Specify all arguments from it" + " explicitly.") server_group = self._create_server_group(**kwargs) msg = ("Server Groups isn't created") self.assertTrue(server_group, err_msg=msg) server_group_info = self._get_server_group(server_group.id) self.assertEqual(server_group.id, server_group_info.id) + + +@validation.add("required_services", services=[consts.Service.NOVA]) +@validation.add("required_platform", platform="openstack", users=True) +@scenario.configure(context={"cleanup": ["nova"]}, + name="NovaServerGroups.create_and_delete_server_group", + platform="openstack") +class CreateAndDeleteServerGroup(utils.NovaScenario): + + def run(self, policies=None, kwargs=None): + """Create a server group, then delete it. + + Measure the "nova server-group-create" and "nova server-group-delete" + command performance. + + :param policies: Server group policy + :param kwargs: The server group specifications to add. + DEPRECATED, specify arguments explicitly. + """ + if kwargs is None: + kwargs = { + "policies": policies + } + else: + LOG.warning("The argument `kwargs` is deprecated since" + " Rally 0.10.0. Specify all arguments from it" + " explicitly.") + server_group = self._create_server_group(**kwargs) + msg = ("Server Group isn't created") + self.assertTrue(server_group, err_msg=msg) + + self._delete_server_group(server_group.id) diff --git a/rally/plugins/openstack/scenarios/nova/utils.py b/rally/plugins/openstack/scenarios/nova/utils.py index c80477a8..eb0a7768 100644 --- a/rally/plugins/openstack/scenarios/nova/utils.py +++ b/rally/plugins/openstack/scenarios/nova/utils.py @@ -418,11 +418,13 @@ class NovaScenario(scenario.OpenStackScenario): def _create_server_group(self, **kwargs): """Create (allocate) a server group. - :param kwargs: Server group name and policy + :param kwargs: Optional additional arguments for Server group creating :returns: Nova server group """ - return self.clients("nova").server_groups.create(**kwargs) + group_name = self.generate_random_name() + return self.clients("nova").server_groups.create(name=group_name, + **kwargs) @atomic.action_timer("nova.get_server_group") def _get_server_group(self, id): @@ -448,6 +450,16 @@ class NovaScenario(scenario.OpenStackScenario): else: return self.clients("nova").server_groups.list(all_projects) + @atomic.action_timer("nova.delete_server_group") + def _delete_server_group(self, group_id): + """Delete a specific server group. + + :param id: The ID of the :class:`ServerGroup` to delete + + :returns: An instance of novaclient.base.TupleWithMeta + """ + return self.clients("nova").server_groups.delete(group_id) + @atomic.action_timer("nova.delete_image") def _delete_image(self, image): """Delete the given image. diff --git a/samples/tasks/scenarios/nova/create-and-delete-server-group.json b/samples/tasks/scenarios/nova/create-and-delete-server-group.json new file mode 100644 index 00000000..7f8211ec --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-delete-server-group.json @@ -0,0 +1,27 @@ +{ + "NovaServerGroups.create_and_delete_server_group": [ + { + "args": { + "policies": [ + "affinity" + ] + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + }, + "runner": { + "concurrency": 2, + "times": 4, + "type": "constant" + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/nova/create-and-delete-server-group.yaml b/samples/tasks/scenarios/nova/create-and-delete-server-group.yaml new file mode 100644 index 00000000..47fd7112 --- /dev/null +++ b/samples/tasks/scenarios/nova/create-and-delete-server-group.yaml @@ -0,0 +1,15 @@ + NovaServerGroups.create_and_delete_server_group: + - + args: + policies: ["affinity"] + runner: + type: "constant" + times: 4 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/samples/tasks/scenarios/nova/create-and-get-server-group.json b/samples/tasks/scenarios/nova/create-and-get-server-group.json index 46fb5296..b0b9faf7 100644 --- a/samples/tasks/scenarios/nova/create-and-get-server-group.json +++ b/samples/tasks/scenarios/nova/create-and-get-server-group.json @@ -2,11 +2,9 @@ "NovaServerGroups.create_and_get_server_group": [ { "args": { - "kwargs": { - "policies": [ - "affinity" - ] - } + "policies": [ + "affinity" + ] }, "runner": { "type": "constant", diff --git a/samples/tasks/scenarios/nova/create-and-get-server-group.yaml b/samples/tasks/scenarios/nova/create-and-get-server-group.yaml index e1d2d2e1..02dee1fc 100644 --- a/samples/tasks/scenarios/nova/create-and-get-server-group.yaml +++ b/samples/tasks/scenarios/nova/create-and-get-server-group.yaml @@ -1,8 +1,7 @@ NovaServerGroups.create_and_get_server_group: - args: - kwargs: - policies: ["affinity"] + policies: ["affinity"] runner: type: "constant" times: 4 diff --git a/samples/tasks/scenarios/nova/create-and-list-server-groups.json b/samples/tasks/scenarios/nova/create-and-list-server-groups.json index bdf06335..545c33cb 100644 --- a/samples/tasks/scenarios/nova/create-and-list-server-groups.json +++ b/samples/tasks/scenarios/nova/create-and-list-server-groups.json @@ -2,11 +2,9 @@ "NovaServerGroups.create_and_list_server_groups": [ { "args": { - "kwargs": { - "policies": [ - "affinity" - ] - }, + "policies": [ + "affinity" + ], "all_projects": false }, "runner": { diff --git a/samples/tasks/scenarios/nova/create-and-list-server-groups.yaml b/samples/tasks/scenarios/nova/create-and-list-server-groups.yaml index cc4dbe59..247bab07 100644 --- a/samples/tasks/scenarios/nova/create-and-list-server-groups.yaml +++ b/samples/tasks/scenarios/nova/create-and-list-server-groups.yaml @@ -1,8 +1,7 @@ NovaServerGroups.create_and_list_server_groups: - args: - kwargs: - policies: ["affinity"] + policies: ["affinity"] all_projects: false runner: type: "constant" diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py b/tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py index 06c9b7ae..d4dc7798 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_server_groups.py @@ -29,92 +29,136 @@ class NovaServerGroupsTestCase(test.ScenarioTestCase): def test_create_and_list_server_groups(self): scenario = server_groups.CreateAndListServerGroups(self.context) - gen_name = mock.MagicMock() - scenario.generate_random_name = gen_name - all_projects = False - create_args = {"policies": ["fake_policy"]} fake_server_group = mock.MagicMock() + all_projects = False scenario._create_server_group = mock.MagicMock() scenario._list_server_groups = mock.MagicMock() scenario._list_server_groups.return_value = [mock.MagicMock(), fake_server_group, mock.MagicMock()] - # Positive case + # Positive case and kwargs is None scenario._create_server_group.return_value = fake_server_group - scenario.run(kwargs=create_args) - scenario._create_server_group.assert_called_once_with(**create_args) + scenario.run(policies="fake_policy", all_projects=False, kwargs=None) + kwargs = { + "policies": "fake_policy" + } + scenario._create_server_group.assert_called_once_with(**kwargs) scenario._list_server_groups.assert_called_once_with(all_projects) + # Positive case and kwargs is not None + foo_kwargs = { + "policies": "fake_policy" + } + scenario._create_server_group.return_value = fake_server_group + scenario.run(policies=None, all_projects=False, + kwargs=foo_kwargs) + scenario._create_server_group.assert_called_with(**foo_kwargs) + scenario._list_server_groups.assert_called_with(all_projects) + # Negative case1: server group isn't created scenario._create_server_group.return_value = None self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, - kwargs=create_args) - scenario._create_server_group.assert_called_with(**create_args) + **kwargs) + scenario._create_server_group.assert_called_with(**kwargs) # Negative case2: server group not in the list of available server # groups scenario._create_server_group.return_value = mock.MagicMock() self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, - kwargs=create_args) - scenario._create_server_group.assert_called_with(**create_args) + **kwargs) + scenario._create_server_group.assert_called_with(**kwargs) scenario._list_server_groups.assert_called_with(all_projects) - @ddt.data( - {}, - {"create_args": {"policies": ["fake_policy"]}} - ) - @ddt.unpack - def test_create_and_get_server_group_positive(self, create_args=None): + def test_create_and_get_server_group_positive(self): scenario = server_groups.CreateAndGetServerGroup(self.context) - gen_name = mock.MagicMock() - scenario.generate_random_name = gen_name fake_server_group = mock.MagicMock() fake_server_group_info = mock.MagicMock() fake_server_group.id = 123 fake_server_group_info.id = 123 scenario._create_server_group = mock.MagicMock() scenario._get_server_group = mock.MagicMock() - create_args = create_args or {} - # Positive case + # Positive case and kwargs is None + kwargs = { + "policies": "fake_policy" + } scenario._create_server_group.return_value = fake_server_group scenario._get_server_group.return_value = fake_server_group_info - scenario.run(create_args) - scenario._create_server_group.assert_called_once_with(**create_args) + scenario.run(policies="fake_policy", kwargs=None) + scenario._create_server_group.assert_called_once_with(**kwargs) scenario._get_server_group.assert_called_once_with( fake_server_group.id) - @ddt.data( - {}, - {"create_args": {"policies": ["fake_policy"]}} - ) - @ddt.unpack - def test_create_and_get_server_group_negative(self, create_args=None): + # Positive case and kwargs is not None + scenario._create_server_group.return_value = fake_server_group + scenario._get_server_group.return_value = fake_server_group_info + foo_kwargs = { + "policies": "fake_policy" + } + scenario.run(policies=None, kwargs=foo_kwargs) + scenario._create_server_group.assert_called_with(**foo_kwargs) + scenario._get_server_group.assert_called_with( + fake_server_group.id) + + def test_create_and_get_server_group_negative(self): scenario = server_groups.CreateAndGetServerGroup(self.context) - gen_name = mock.MagicMock() - scenario.generate_random_name = gen_name fake_server_group = mock.MagicMock() fake_server_group_info = mock.MagicMock() fake_server_group.id = 123 fake_server_group_info.id = 123 + kwargs = { + "policies": "fake_policy" + } scenario._create_server_group = mock.MagicMock() scenario._get_server_group = mock.MagicMock() - create_args = create_args or {} # Negative case1: server group isn't created scenario._create_server_group.return_value = None self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, - create_args) - scenario._create_server_group.assert_called_with(**create_args) + **kwargs) + scenario._create_server_group.assert_called_with(**kwargs) # Negative case2: server group to get information not the created one fake_server_group_info.id = 456 scenario._create_server_group.return_value = fake_server_group self.assertRaises(rally_exceptions.RallyAssertionError, scenario.run, - create_args) - scenario._create_server_group.assert_called_with(**create_args) + **kwargs) + scenario._create_server_group.assert_called_with(**kwargs) scenario._get_server_group.assert_called_with( fake_server_group.id) + + def test_create_and_delete_server_group(self): + scenario = server_groups.CreateAndDeleteServerGroup(self.context) + fake_server_group = mock.MagicMock() + scenario._create_server_group = mock.MagicMock() + scenario._delete_server_group = mock.MagicMock() + + # Positive case and kwargs is None + kwargs = { + "policies": "fake_policy" + } + scenario._create_server_group.return_value = fake_server_group + scenario.run(policies="fake_policy", kwargs=None) + scenario._create_server_group.assert_called_once_with(**kwargs) + scenario._delete_server_group.assert_called_once_with( + fake_server_group.id) + + # Positive case and kwargs is not None + scenario._create_server_group.return_value = fake_server_group + foo_kwargs = { + "policies": "fake_policy" + } + scenario.run(policies=None, kwargs=foo_kwargs) + scenario._create_server_group.assert_called_with(**foo_kwargs) + scenario._delete_server_group.assert_called_with( + fake_server_group.id) + + # Negative case: server group isn't created + scenario._create_server_group.return_value = None + self.assertRaises(rally_exceptions.RallyAssertionError, + scenario.run, + **kwargs) + scenario._create_server_group.assert_called_with(**kwargs) diff --git a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py index 49f29b83..807d63fe 100644 --- a/tests/unit/plugins/openstack/scenarios/nova/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/nova/test_utils.py @@ -767,15 +767,29 @@ class NovaScenarioTestCase(test.ScenarioTestCase): def test__create_server_group(self): nova_scenario = utils.NovaScenario() + nova_scenario.generate_random_name = mock.Mock( + return_value="random_name") result = nova_scenario._create_server_group(fakeargs="fakeargs") self.assertEqual( self.clients("nova").server_groups.create.return_value, result) self.clients("nova").server_groups.create.assert_called_once_with( - fakeargs="fakeargs") + name="random_name", fakeargs="fakeargs") self._test_atomic_action_timer(nova_scenario.atomic_actions(), "nova.create_server_group") + def test__delete_server_group(self): + nova_scenario = utils.NovaScenario() + fakeid = 12345 + result = nova_scenario._delete_server_group(fakeid) + self.assertEqual( + self.clients("nova").server_groups.delete.return_value, + result) + self.clients("nova").server_groups.delete.assert_called_once_with( + fakeid) + self._test_atomic_action_timer(nova_scenario.atomic_actions(), + "nova.delete_server_group") + def test__list_server_groups(self): nova_scenario = utils.NovaScenario() result1 = nova_scenario._list_server_groups(all_projects=False)