From 082a8271c11dcf39668061d4d72567163293b2d0 Mon Sep 17 00:00:00 2001 From: Roman Vasilets Date: Tue, 6 Jan 2015 17:08:06 +0200 Subject: [PATCH] Add murano benchmarks Scenarios: * list-environment * create_and_delete_environment Add murano environment to cleanup resources Add unit tests for scenarios blueprint: Important-for-next-release Co-Authored-By: Roman Vasilets Co-Authored-By: Sergey Murashov Change-Id: Id6888325e77eada2f51ad0bf8af80415c2c8d487 --- rally-jobs/rally-murano.yaml | 28 ++++++ rally/benchmark/context/cleanup/resources.py | 11 +++ rally/benchmark/scenarios/murano/__init__.py | 0 .../scenarios/murano/environments.py | 46 ++++++++++ rally/benchmark/scenarios/murano/utils.py | 66 ++++++++++++++ .../murano/create_and_delete_environment.json | 17 ++++ .../murano/create_and_delete_environment.yaml | 11 +++ .../scenarios/murano/list-environments.json | 17 ++++ .../scenarios/murano/list-environments.yaml | 11 +++ .../benchmark/scenarios/murano/__init__.py | 0 .../scenarios/murano/test_environments.py | 48 ++++++++++ .../benchmark/scenarios/murano/test_utils.py | 88 +++++++++++++++++++ 12 files changed, 343 insertions(+) create mode 100644 rally-jobs/rally-murano.yaml create mode 100644 rally/benchmark/scenarios/murano/__init__.py create mode 100644 rally/benchmark/scenarios/murano/environments.py create mode 100644 rally/benchmark/scenarios/murano/utils.py create mode 100644 samples/tasks/scenarios/murano/create_and_delete_environment.json create mode 100644 samples/tasks/scenarios/murano/create_and_delete_environment.yaml create mode 100644 samples/tasks/scenarios/murano/list-environments.json create mode 100644 samples/tasks/scenarios/murano/list-environments.yaml create mode 100644 tests/unit/benchmark/scenarios/murano/__init__.py create mode 100644 tests/unit/benchmark/scenarios/murano/test_environments.py create mode 100644 tests/unit/benchmark/scenarios/murano/test_utils.py diff --git a/rally-jobs/rally-murano.yaml b/rally-jobs/rally-murano.yaml new file mode 100644 index 0000000000..3d77f234c7 --- /dev/null +++ b/rally-jobs/rally-murano.yaml @@ -0,0 +1,28 @@ +--- + MuranoEnvironments.list_environments: + - + runner: + type: "constant" + times: 30 + concurrency: 4 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + + MuranoEnvironments.create_and_delete_environment: + - + runner: + type: "constant" + times: 20 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 diff --git a/rally/benchmark/context/cleanup/resources.py b/rally/benchmark/context/cleanup/resources.py index 8fa03a31a3..5372ee40eb 100644 --- a/rally/benchmark/context/cleanup/resources.py +++ b/rally/benchmark/context/cleanup/resources.py @@ -353,6 +353,17 @@ class MistralWorkbooks(SynchronizedDeletion, base.ResourceManager): self._manager().delete(self.raw_resource.name) +# MURANO + +_murano_order = get_order(1200) + + +@base.resource("murano", "environments", tenant_resource=True, + order=next(_murano_order)) +class MuranoEnvironments(base.ResourceManager): + pass + + # KEYSTONE _keystone_order = get_order(9000) diff --git a/rally/benchmark/scenarios/murano/__init__.py b/rally/benchmark/scenarios/murano/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rally/benchmark/scenarios/murano/environments.py b/rally/benchmark/scenarios/murano/environments.py new file mode 100644 index 0000000000..33e09c56e9 --- /dev/null +++ b/rally/benchmark/scenarios/murano/environments.py @@ -0,0 +1,46 @@ +# Copyright 2015: Mirantis Inc. +# 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.benchmark.scenarios import base +from rally.benchmark.scenarios.murano import utils +from rally.benchmark.scenarios.vm import utils as vm_utils +from rally.benchmark import validation +from rally.common import log as logging +from rally import consts + +LOG = logging.getLogger(__name__) + + +class MuranoEnvironments(utils.MuranoScenario, vm_utils.VMScenario): + """Benchmark scenarios for Murano environments.""" + @validation.required_clients("murano") + @validation.required_services(consts.Service.MURANO) + @base.scenario(context={"cleanup": ["murano.environments"]}) + def list_environments(self): + """List the murano environments. + + Run murano environment-list for listing all environments. + """ + self._list_environments() + + @validation.required_clients("murano") + @validation.required_services(consts.Service.MURANO) + @base.scenario(context={"cleanup": ["murano.environments"]}) + def create_and_delete_environment(self): + """Create environment, session and delete environment.""" + environment = self._create_environment() + + self._create_session(environment.id) + self._delete_environment(environment) diff --git a/rally/benchmark/scenarios/murano/utils.py b/rally/benchmark/scenarios/murano/utils.py new file mode 100644 index 0000000000..16d8fd2878 --- /dev/null +++ b/rally/benchmark/scenarios/murano/utils.py @@ -0,0 +1,66 @@ +# Copyright 2015: Mirantis Inc. +# 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.benchmark.scenarios import base +from rally.benchmark import utils as bench_utils + + +class MuranoScenario(base.Scenario): + """Base class for Murano scenarios with basic atomic actions.""" + + @base.atomic_action_timer("murano.list_environments") + def _list_environments(self): + """Return user images list.""" + return self.clients("murano").environments.list() + + @base.atomic_action_timer("murano.create_environment") + def _create_environment(self, env_name=None): + """Create environment. + + :param env_name: String used to name environment + + :returns: Environment instance + """ + env_name = env_name or self._generate_random_name() + return self.clients("murano").environments.create({"name": env_name}) + + @base.atomic_action_timer("murano.delete_environment") + def _delete_environment(self, environment, timeout=180, check_interval=2): + """Delete given environment. + + Return when the environment is actually deleted. + + :param environment: Environment instance + :param timeout: Timeout in seconds after which a TimeoutException + will be raised, by default 180 + :param check_interval: Interval in seconds between the two consecutive + readiness checks, by default 2 + """ + self.clients("murano").environments.delete(environment.id) + bench_utils.wait_for_delete( + environment, + update_resource=bench_utils.get_from_manager(), + timeout=timeout, + check_interval=check_interval + ) + + @base.atomic_action_timer("murano.create_session") + def _create_session(self, environment_id): + """Create session for environment with specific id + + :param environment_id: Environment id + :returns: Session instance + """ + return self.clients("murano").sessions.configure(environment_id) diff --git a/samples/tasks/scenarios/murano/create_and_delete_environment.json b/samples/tasks/scenarios/murano/create_and_delete_environment.json new file mode 100644 index 0000000000..d9fa719451 --- /dev/null +++ b/samples/tasks/scenarios/murano/create_and_delete_environment.json @@ -0,0 +1,17 @@ +{ + "MuranoEnvironments.create_and_delete_environment": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/murano/create_and_delete_environment.yaml b/samples/tasks/scenarios/murano/create_and_delete_environment.yaml new file mode 100644 index 0000000000..92e701383c --- /dev/null +++ b/samples/tasks/scenarios/murano/create_and_delete_environment.yaml @@ -0,0 +1,11 @@ +--- + MuranoEnvironments.create_and_delete_environment: + - + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 diff --git a/samples/tasks/scenarios/murano/list-environments.json b/samples/tasks/scenarios/murano/list-environments.json new file mode 100644 index 0000000000..551c7f0641 --- /dev/null +++ b/samples/tasks/scenarios/murano/list-environments.json @@ -0,0 +1,17 @@ +{ + "MuranoEnvironments.list_environments": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/samples/tasks/scenarios/murano/list-environments.yaml b/samples/tasks/scenarios/murano/list-environments.yaml new file mode 100644 index 0000000000..d914ee196c --- /dev/null +++ b/samples/tasks/scenarios/murano/list-environments.yaml @@ -0,0 +1,11 @@ +--- + MuranoEnvironments.list_environments: + - + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 diff --git a/tests/unit/benchmark/scenarios/murano/__init__.py b/tests/unit/benchmark/scenarios/murano/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/benchmark/scenarios/murano/test_environments.py b/tests/unit/benchmark/scenarios/murano/test_environments.py new file mode 100644 index 0000000000..c4f4375914 --- /dev/null +++ b/tests/unit/benchmark/scenarios/murano/test_environments.py @@ -0,0 +1,48 @@ +# Copyright 2015: Mirantis Inc. +# 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.benchmark.scenarios.murano import environments +from tests.unit import test + +CTX = "rally.benchmark.context" +MURANO_SCENARIO = ("rally.benchmark.scenarios.murano." + "environments.MuranoEnvironments") + + +class MuranoEnvironmentsTestCase(test.TestCase): + + @mock.patch(MURANO_SCENARIO + "._list_environments") + def test_list_environments(self, mock_list): + scenario = environments.MuranoEnvironments() + scenario._list_environments() + mock_list.assert_called_once_with() + + @mock.patch(MURANO_SCENARIO + "._create_session") + @mock.patch(MURANO_SCENARIO + "._delete_environment") + @mock.patch(MURANO_SCENARIO + "._create_environment") + @mock.patch(MURANO_SCENARIO + "._generate_random_name") + def test_create_and_delete_environment(self, mock_random_name, + mock_create, mock_delete, + mock_session): + scenario = environments.MuranoEnvironments() + fake_environment = mock.Mock(id="fake_id") + mock_create.return_value = fake_environment + mock_random_name.return_value = "foo" + scenario.create_and_delete_environment() + mock_create.assert_called_once_with() + mock_session.assert_called_once_with(fake_environment.id) + mock_delete.assert_called_once_with(fake_environment) diff --git a/tests/unit/benchmark/scenarios/murano/test_utils.py b/tests/unit/benchmark/scenarios/murano/test_utils.py new file mode 100644 index 0000000000..3bcb996e44 --- /dev/null +++ b/tests/unit/benchmark/scenarios/murano/test_utils.py @@ -0,0 +1,88 @@ +# Copyright 2015: Mirantis Inc. +# 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 oslotest import mockpatch + +from rally.benchmark.scenarios.murano import utils +from tests.unit import test + +BM_UTILS = "rally.benchmark.utils" +MRN_UTILS = "rally.benchmark.scenarios.murano.utils" + + +class MuranoScenarioTestCase(test.TestCase): + + def setUp(self): + super(MuranoScenarioTestCase, self).setUp() + self.res_is = mockpatch.Patch(BM_UTILS + ".resource_is") + self.get_fm = mockpatch.Patch(BM_UTILS + ".get_from_manager") + self.wait_for = mockpatch.Patch(MRN_UTILS + ".bench_utils.wait_for") + self.wait_for_delete = mockpatch.Patch( + MRN_UTILS + ".bench_utils.wait_for_delete") + self.useFixture(self.wait_for) + self.useFixture(self.wait_for_delete) + self.useFixture(self.res_is) + self.useFixture(self.get_fm) + self.gfm = self.get_fm.mock + self.useFixture(mockpatch.Patch("time.sleep")) + + @mock.patch(MRN_UTILS + ".MuranoScenario.clients") + def test_list_environments(self, mock_clients): + + mock_clients("murano").environments.list.return_value = [] + scenario = utils.MuranoScenario() + return_environments_list = scenario._list_environments() + self.assertEqual([], return_environments_list) + self._test_atomic_action_timer(scenario.atomic_actions(), + "murano.list_environments") + + @mock.patch(MRN_UTILS + ".MuranoScenario.clients") + def test_create_environments(self, mock_clients): + mock_create = mock.Mock(return_value="foo_env") + mock_clients("murano").environments.create = mock_create + scenario = utils.MuranoScenario() + create_env = scenario._create_environment("env_name") + self.assertEqual("foo_env", create_env) + mock_create.assert_called_once_with({"name": "env_name"}) + self._test_atomic_action_timer(scenario.atomic_actions(), + "murano.create_environment") + + @mock.patch(MRN_UTILS + ".MuranoScenario.clients") + def test_delete_environment(self, mock_clients): + environment = mock.Mock(id="id") + mock_clients("murano").environments.delete.return_value = "ok" + scenario = utils.MuranoScenario() + scenario._delete_environment(environment) + mock_clients("murano").environments.delete.assert_called_once_with( + environment.id + ) + + self.wait_for_delete.mock.assert_called_once_with( + environment, + update_resource=self.gfm(), + timeout=180, + check_interval=2) + self._test_atomic_action_timer(scenario.atomic_actions(), + "murano.delete_environment") + + @mock.patch(MRN_UTILS + ".MuranoScenario.clients") + def test_create_session(self, mock_clients): + mock_clients("murano").sessions.configure.return_value = "sess" + scenario = utils.MuranoScenario() + create_sess = scenario._create_session("id") + self.assertEqual("sess", create_sess) + self._test_atomic_action_timer(scenario.atomic_actions(), + "murano.create_session")