From 243a26240b8efd25a3063be3177526148946ad94 Mon Sep 17 00:00:00 2001 From: zhangzhang Date: Tue, 18 Oct 2016 07:54:38 -0400 Subject: [PATCH] Add cinder.CreateVolumeType scenario Create and delete a volume type Change-Id: I546c657e41924fcad1a9d84f7b6109ad890642d3 --- rally-jobs/cinder.yaml | 15 ++++++++ rally/plugins/openstack/cleanup/resources.py | 10 +++++ .../openstack/scenarios/cinder/utils.py | 22 +++++++++++ .../scenarios/cinder/volume_types.py | 37 +++++++++++++++++++ .../cinder/create-and-delete-volume-type.json | 23 ++++++++++++ .../cinder/create-and-delete-volume-type.yaml | 15 ++++++++ .../openstack/cleanup/test_resources.py | 17 +++++++++ .../openstack/scenarios/cinder/test_utils.py | 25 +++++++++++++ .../scenarios/cinder/test_volume_types.py | 35 ++++++++++++++++++ 9 files changed, 199 insertions(+) create mode 100644 rally/plugins/openstack/scenarios/cinder/volume_types.py create mode 100644 samples/tasks/scenarios/cinder/create-and-delete-volume-type.json create mode 100644 samples/tasks/scenarios/cinder/create-and-delete-volume-type.yaml create mode 100644 tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py diff --git a/rally-jobs/cinder.yaml b/rally-jobs/cinder.yaml index 68552f5b..33bef6a1 100755 --- a/rally-jobs/cinder.yaml +++ b/rally-jobs/cinder.yaml @@ -754,6 +754,21 @@ failure_rate: max: 0 + CinderVolumeTypes.create_and_delete_volume_type: + - + args: {} + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + CinderVolumes.list_transfers: - args: diff --git a/rally/plugins/openstack/cleanup/resources.py b/rally/plugins/openstack/cleanup/resources.py index ff517e34..4f0f3fe5 100644 --- a/rally/plugins/openstack/cleanup/resources.py +++ b/rally/plugins/openstack/cleanup/resources.py @@ -23,6 +23,7 @@ from rally.common import logging from rally.common.plugin import discover from rally.common import utils from rally.plugins.openstack.cleanup import base +from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils from rally.plugins.openstack.scenarios.fuel import utils as futils from rally.plugins.openstack.scenarios.keystone import utils as kutils from rally.plugins.openstack.scenarios.nova import utils as nova_utils @@ -446,6 +447,15 @@ class CinderVolumeBackup(base.ResourceManager): pass +@base.resource("cinder", "volume_types", order=next(_cinder_order), + admin_required=True) +class CinderVolumeType(base.ResourceManager): + def list(self): + return [r for r in self._manager().list() + if utils.name_matches_object(r.name, + cinder_utils.CinderScenario)] + + @base.resource("cinder", "volume_snapshots", order=next(_cinder_order), tenant_resource=True) class CinderVolumeSnapshot(base.ResourceManager): diff --git a/rally/plugins/openstack/scenarios/cinder/utils.py b/rally/plugins/openstack/scenarios/cinder/utils.py index 740cb936..1290d184 100644 --- a/rally/plugins/openstack/scenarios/cinder/utils.py +++ b/rally/plugins/openstack/scenarios/cinder/utils.py @@ -391,3 +391,25 @@ class CinderScenario(scenario.OpenStackScenario): :returns: list of :class:`VolumeTransfer` """ return self.clients("cinder").transfers.list(detailed, search_opts) + + @atomic.action_timer("cinder.create_volume_type") + def _create_volume_type(self, **kwargs): + """create volume type. + + :param kwargs: Optional additional arguments for volume type creation + :returns: VolumeType object + """ + kwargs["name"] = self.generate_random_name() + return self.admin_clients("cinder").volume_types.create(**kwargs) + + @atomic.action_timer("cinder.delete_volume_type") + def _delete_volume_type(self, volume_type): + """delete a volume type. + + :param volume_type: Name or Id of the volume type + :returns: base on client response return True if the request + has been accepted or not + """ + tuple_res = self.admin_clients("cinder").volume_types.delete( + volume_type) + return (tuple_res[0].status_code == 202) diff --git a/rally/plugins/openstack/scenarios/cinder/volume_types.py b/rally/plugins/openstack/scenarios/cinder/volume_types.py new file mode 100644 index 00000000..0d6a3204 --- /dev/null +++ b/rally/plugins/openstack/scenarios/cinder/volume_types.py @@ -0,0 +1,37 @@ +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from rally import consts +from rally.plugins.openstack import scenario +from rally.plugins.openstack.scenarios.cinder import utils as cinder_utils +from rally.task import validation + + +"""Scenarios for Cinder Volume Type.""" + + +@validation.required_services(consts.Service.CINDER) +@validation.required_openstack(admin=True) +@scenario.configure(context={"admin_cleanup": ["cinder"]}, + name="CinderVolumeTypes.create_and_delete_volume_type") +class CreateAndDeleteVolumeType(cinder_utils.CinderScenario): + + def run(self, **kwargs): + """Create and delete a volume Type. + + :param kwargs: Optional parameters used during volume + type creation. + """ + volume_type = self._create_volume_type(**kwargs) + self._delete_volume_type(volume_type) diff --git a/samples/tasks/scenarios/cinder/create-and-delete-volume-type.json b/samples/tasks/scenarios/cinder/create-and-delete-volume-type.json new file mode 100644 index 00000000..7d45f2aa --- /dev/null +++ b/samples/tasks/scenarios/cinder/create-and-delete-volume-type.json @@ -0,0 +1,23 @@ +{ + "CinderVolumeTypes.create_and_delete_volume_type": [ + { + "args": {}, + "runner": { + "type": "constant", + "times": 5, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + }, + "sla": { + "failure_rate": { + "max": 0 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/cinder/create-and-delete-volume-type.yaml b/samples/tasks/scenarios/cinder/create-and-delete-volume-type.yaml new file mode 100644 index 00000000..0dff7c51 --- /dev/null +++ b/samples/tasks/scenarios/cinder/create-and-delete-volume-type.yaml @@ -0,0 +1,15 @@ +--- + CinderVolumeTypes.create_and_delete_volume_type: + - + args: {} + runner: + type: "constant" + times: 5 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/tests/unit/plugins/openstack/cleanup/test_resources.py b/tests/unit/plugins/openstack/cleanup/test_resources.py index ab8fd14e..2f72d0af 100644 --- a/tests/unit/plugins/openstack/cleanup/test_resources.py +++ b/tests/unit/plugins/openstack/cleanup/test_resources.py @@ -22,6 +22,7 @@ from watcherclient.common.apiclient import exceptions as watcher_exceptions from rally.common import utils from rally.plugins.openstack.cleanup import resources +from rally.plugins.openstack.scenarios.cinder import utils as cutils from rally.plugins.openstack.scenarios.keystone import utils as kutils from rally.plugins.openstack.scenarios.nova import utils as nutils from tests.unit import test @@ -949,3 +950,19 @@ class WatcherActionPlanTestCase(test.TestCase): self.assertEqual("action_plan", watcher._resource) watcher._manager().list.assert_called_once_with(limit=0) + + +class CinderVolumeTypeTestCase(test.TestCase): + + @mock.patch("%s.base.ResourceManager._manager" % BASE) + @mock.patch("rally.common.utils.name_matches_object") + def test_list(self, mock_name_matches_object, + mock_resource_manager__manager): + volume_types = [mock.MagicMock(name="foo1"), + mock.MagicMock(name="rally_foo2"), + mock.MagicMock(name="rally_foo3")] + mock_name_matches_object.side_effect = [False, True, True] + mock_resource_manager__manager().list.return_value = volume_types + self.assertEqual(volume_types[1:], resources.CinderVolumeType().list()) + mock_name_matches_object.assert_has_calls( + [mock.call(r.name, cutils.CinderScenario) for r in volume_types]) diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py b/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py index 76e90fef..fdbaa5b8 100644 --- a/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_utils.py @@ -357,3 +357,28 @@ class CinderScenarioTestCase(test.ScenarioTestCase): server_id = self.scenario.get_random_server() self.assertIn(server_id, servers) + + def test__create_volume_type(self, **kwargs): + random_name = "random_name" + self.scenario.generate_random_name = mock.Mock( + return_value=random_name) + + result = self.scenario._create_volume_type() + + self.assertEqual( + self.admin_clients("cinder").volume_types.create.return_value, + result) + admin_clients = self.admin_clients("cinder") + admin_clients.volume_types.create.assert_called_once_with( + name="random_name") + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "cinder.create_volume_type") + + def test__delete_volume_type(self): + volume_type = mock.Mock() + self.scenario._delete_volume_type(volume_type) + admin_clients = self.admin_clients("cinder") + admin_clients.volume_types.delete.assert_called_once_with( + volume_type) + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "cinder.delete_volume_type") diff --git a/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py b/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py new file mode 100644 index 00000000..dcb13462 --- /dev/null +++ b/tests/unit/plugins/openstack/scenarios/cinder/test_volume_types.py @@ -0,0 +1,35 @@ +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from rally.plugins.openstack.scenarios.cinder import volume_types +from tests.unit import test + + +class fake_type(object): + name = "fake" + + +class CinderVolumeTypesTestCase(test.ScenarioTestCase): + + def test_create_and_delete_volume_type(self): + scenario = volume_types.CreateAndDeleteVolumeType(self.context) + scenario._create_volume_type = mock.Mock() + scenario._delete_volume_type = mock.Mock() + scenario.run(fakeargs="fakeargs") + scenario._create_volume_type.assert_called_once_with( + fakeargs="fakeargs") + scenario._delete_volume_type.assert_called_once_with( + scenario._create_volume_type.return_value)