diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index 3abf65ad..eecc3570 100644 --- a/rally-jobs/rally.yaml +++ b/rally-jobs/rally.yaml @@ -305,6 +305,76 @@ failure_rate: max: 0 + CeilometerEvents.create_user_and_get_event: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + + CeilometerEvents.create_user_and_list_event_types: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + + CeilometerEvents.create_user_and_list_events: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + + CeilometerTraits.create_user_and_list_trait_descriptions: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + + CeilometerTraits.create_user_and_list_traits: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 + sla: + failure_rate: + max: 0 + CeilometerMeters.list_meters: - runner: diff --git a/rally/plugins/openstack/scenarios/ceilometer/events.py b/rally/plugins/openstack/scenarios/ceilometer/events.py new file mode 100644 index 00000000..72147948 --- /dev/null +++ b/rally/plugins/openstack/scenarios/ceilometer/events.py @@ -0,0 +1,70 @@ +# 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 validation +from rally import consts +from rally.plugins.openstack.scenarios.ceilometer import utils as cutils +from rally.plugins.openstack.scenarios.keystone import utils as kutils + + +class CeilometerEvents(cutils.CeilometerScenario, kutils.KeystoneScenario): + """Benchmark scenarios for Ceilometer Events API.""" + + # NOTE(idegtiarov): to work with event we need to create it, there are + # no other way except emit suitable notification from one of services, + # for example create new user in keystone. + + @validation.required_services(consts.Service.CEILOMETER, + consts.Service.KEYSTONE) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["keystone"], + "cleanup": ["ceilometer"]}) + def create_user_and_list_events(self): + """Fetch all events. + + This scenario creates user to store new event and + fetches list of all events using GET /v2/events. + """ + self._user_create() + self._list_events() + + @validation.required_services(consts.Service.CEILOMETER, + consts.Service.KEYSTONE) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["keystone"], + "cleanup": ["ceilometer"]}) + def create_user_and_list_event_types(self): + """Fetch all event types. + + This scenario creates user to store new event and + fetches list of all events types using GET /v2/event_types. + """ + self._user_create() + self._list_event_types() + + @validation.required_services(consts.Service.CEILOMETER, + consts.Service.KEYSTONE) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["keystone"], + "cleanup": ["ceilometer"]}) + def create_user_and_get_event(self): + """Get event. + + This scenario creates user to store new event and + fetches one event using GET /v2/events/. + """ + self._user_create() + event = self._list_events()[0] + self._get_event(event_id=event.message_id) diff --git a/rally/plugins/openstack/scenarios/ceilometer/traits.py b/rally/plugins/openstack/scenarios/ceilometer/traits.py new file mode 100644 index 00000000..2b235e61 --- /dev/null +++ b/rally/plugins/openstack/scenarios/ceilometer/traits.py @@ -0,0 +1,61 @@ +# 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 validation +from rally import consts +from rally.plugins.openstack.scenarios.ceilometer import utils as cutils +from rally.plugins.openstack.scenarios.keystone import utils as kutils + + +class CeilometerTraits(cutils.CeilometerScenario, kutils.KeystoneScenario): + """Benchmark scenarios for Ceilometer Events API.""" + + # NOTE(idegtiarov): to work with traits we need to create event firstly, + # there are no other way except emit suitable notification from one of + # services, for example create new user in keystone. + + @validation.required_services(consts.Service.CEILOMETER, + consts.Service.KEYSTONE) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["keystone"], + "cleanup": ["ceilometer"]}) + def create_user_and_list_traits(self): + """Fetch all events traits. + + This scenario creates user to store new event and + fetches list of all traits for certain event type and + trait name using GET /v2/event_types//traits/. + """ + self._user_create() + event = self._list_events()[0] + trait_name = event.traits[0]["name"] + self._list_event_traits(event_type=event.event_type, + trait_name=trait_name) + + @validation.required_services(consts.Service.CEILOMETER, + consts.Service.KEYSTONE) + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["keystone"], + "cleanup": ["ceilometer"]}) + def create_user_and_list_trait_descriptions(self): + """Fetch all trait descriptions. + + This scenario creates user to store new event and + fetches list of all traits for certain event type using + GET /v2/event_types//traits. + """ + self._user_create() + event = self._list_events()[0] + self._list_event_trait_descriptions(event_type=event.event_type) diff --git a/rally/plugins/openstack/scenarios/ceilometer/utils.py b/rally/plugins/openstack/scenarios/ceilometer/utils.py index 4370c34c..a3c91d11 100644 --- a/rally/plugins/openstack/scenarios/ceilometer/utils.py +++ b/rally/plugins/openstack/scenarios/ceilometer/utils.py @@ -117,6 +117,55 @@ class CeilometerScenario(base.Scenario): .get_from_manager(), timeout=timeout, check_interval=1) + @base.atomic_action_timer("ceilometer.list_events") + def _list_events(self): + """Get list of user's events. + + It fetches all events. + :returns: list of events + """ + return self.admin_clients("ceilometer").events.list() + + @base.atomic_action_timer("ceilometer.get_event") + def _get_event(self, event_id): + """Get event with specific id. + + Get event matching event_id. + + :param event_id: specifies id of the event + :returns: event + """ + return self.admin_clients("ceilometer").events.get(event_id) + + @base.atomic_action_timer("ceilometer.list_event_types") + def _list_event_types(self): + """Get list of all event types. + + :returns: list of event types + """ + return self.admin_clients("ceilometer").event_types.list() + + @base.atomic_action_timer("ceilometer.list_event_traits") + def _list_event_traits(self, event_type, trait_name): + """Get list of event traits. + + :param event_type: specifies the type of event + :param trait_name: specifies trait name + :returns: list of event traits + """ + return self.admin_clients("ceilometer").traits.list(event_type, + trait_name) + + @base.atomic_action_timer("ceilometer.list_event_trait_descriptions") + def _list_event_trait_descriptions(self, event_type): + """Get list of event trait descriptions. + + :param event_type: specifies the type of event + :returns: list of event trait descriptions + """ + return self.admin_clients("ceilometer").trait_descriptions.list( + event_type) + @base.atomic_action_timer("ceilometer.list_meters") def _list_meters(self): """Get list of user's meters.""" diff --git a/tests/unit/plugins/openstack/scenarios/ceilometer/test_events.py b/tests/unit/plugins/openstack/scenarios/ceilometer/test_events.py new file mode 100644 index 00000000..bba48d82 --- /dev/null +++ b/tests/unit/plugins/openstack/scenarios/ceilometer/test_events.py @@ -0,0 +1,51 @@ +# 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.ceilometer import events +from tests.unit import test + + +class CeilometerEventsTestCase(test.TestCase): + + def test_list_events(self): + scenario = events.CeilometerEvents() + + scenario._user_create = mock.MagicMock() + scenario._list_events = mock.MagicMock() + scenario.create_user_and_list_events() + scenario._user_create.assert_called_once_with() + scenario._list_events.assert_called_once_with() + + def test_list_event_types(self): + scenario = events.CeilometerEvents() + + scenario._list_event_types = mock.MagicMock() + scenario._user_create = mock.MagicMock() + scenario.create_user_and_list_event_types() + scenario._user_create.assert_called_once_with() + scenario._list_event_types.assert_called_once_with() + + def test_get_event(self): + scenario = events.CeilometerEvents() + + scenario._user_create = mock.MagicMock() + scenario._list_events = mock.MagicMock() + scenario._get_event = mock.MagicMock() + scenario._list_events.return_value = [mock.Mock(message_id="fake_id")] + scenario.create_user_and_get_event() + scenario._user_create.assert_called_once_with() + scenario._list_events.assert_called_with() + scenario._get_event.assert_called_with(event_id="fake_id") diff --git a/tests/unit/plugins/openstack/scenarios/ceilometer/test_traits.py b/tests/unit/plugins/openstack/scenarios/ceilometer/test_traits.py new file mode 100644 index 00000000..8b787a91 --- /dev/null +++ b/tests/unit/plugins/openstack/scenarios/ceilometer/test_traits.py @@ -0,0 +1,52 @@ +# 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.ceilometer import traits +from tests.unit import test + + +class CeilometerTraitsTestCase(test.TestCase): + + def test_list_traits(self): + scenario = traits.CeilometerTraits() + + scenario._user_create = mock.MagicMock() + scenario._list_events = mock.MagicMock() + scenario._list_event_traits = mock.MagicMock() + scenario._list_events.return_value = [mock.Mock( + event_type="fake_event_type", + traits=[{"name": "fake_trait_name"}]) + ] + scenario.create_user_and_list_traits() + scenario._user_create.assert_called_once_with() + scenario._list_events.assert_called_with() + scenario._list_event_traits.assert_called_once_with( + event_type="fake_event_type", trait_name="fake_trait_name") + + def test_list_trait_descriptions(self): + scenario = traits.CeilometerTraits() + + scenario._user_create = mock.MagicMock() + scenario._list_events = mock.MagicMock() + scenario._list_event_trait_descriptions = mock.MagicMock() + scenario._list_events.return_value = [mock.Mock( + event_type="fake_event_type") + ] + scenario.create_user_and_list_trait_descriptions() + scenario._user_create.assert_called_once_with() + scenario._list_events.assert_called_with() + scenario._list_event_trait_descriptions.assert_called_once_with( + event_type="fake_event_type") diff --git a/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py b/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py index 21aff9f2..54703a3c 100644 --- a/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py @@ -122,6 +122,51 @@ class CeilometerScenarioTestCase(test.ClientsTestCase): self._test_atomic_action_timer(self.scenario.atomic_actions(), "ceilometer.set_alarm_state") + def test__list_events(self): + self.assertEqual( + self.scenario._list_events(), + self.admin_clients("ceilometer").events.list.return_value + ) + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "ceilometer.list_events") + + def test__get_events(self): + self.assertEqual( + self.scenario._get_event(event_id="fake_id"), + self.admin_clients("ceilometer").events.get.return_value + ) + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "ceilometer.get_event") + + def test__list_event_types(self): + self.assertEqual( + self.scenario._list_event_types(), + self.admin_clients("ceilometer").event_types.list.return_value + ) + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "ceilometer.list_event_types") + + def test__list_event_traits(self): + self.assertEqual( + self.scenario._list_event_traits( + event_type="fake_event_type", trait_name="fake_trait_name"), + self.admin_clients("ceilometer").traits.list.return_value + ) + self._test_atomic_action_timer(self.scenario.atomic_actions(), + "ceilometer.list_event_traits") + + def test__list_event_trait_descriptions(self): + self.assertEqual( + self.scenario._list_event_trait_descriptions( + event_type="fake_event_type" + ), + self.admin_clients("ceilometer").trait_descriptions.list. + return_value + ) + self._test_atomic_action_timer( + self.scenario.atomic_actions(), + "ceilometer.list_event_trait_descriptions") + def test__list_meters(self): self.assertEqual(self.scenario._list_meters(), self.clients("ceilometer").meters.list.return_value)