diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index 3abf65ad04..eecc35709b 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 0000000000..721479484f --- /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 0000000000..2b235e6123 --- /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 4370c34c41..a3c91d11ae 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/samples/tasks/scenarios/ceilometer/create_user_and_get_event.json b/samples/tasks/scenarios/ceilometer/create_user_and_get_event.json new file mode 100644 index 0000000000..9dd0d2ccbc --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_get_event.json @@ -0,0 +1,17 @@ +{ + "CeilometerEvents.create_user_and_get_event": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_get_event.yaml b/samples/tasks/scenarios/ceilometer/create_user_and_get_event.yaml new file mode 100644 index 0000000000..137042b9e9 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_get_event.yaml @@ -0,0 +1,11 @@ +--- + CeilometerEvents.create_user_and_get_event: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_event_types.json b/samples/tasks/scenarios/ceilometer/create_user_and_list_event_types.json new file mode 100644 index 0000000000..74a415ff17 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_event_types.json @@ -0,0 +1,17 @@ +{ + "CeilometerEvents.create_user_and_list_event_types": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_event_types.yaml b/samples/tasks/scenarios/ceilometer/create_user_and_list_event_types.yaml new file mode 100644 index 0000000000..f95bc33cee --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_event_types.yaml @@ -0,0 +1,11 @@ +--- + CeilometerEvents.create_user_and_list_event_types: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_events.json b/samples/tasks/scenarios/ceilometer/create_user_and_list_events.json new file mode 100644 index 0000000000..3b86e60314 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_events.json @@ -0,0 +1,17 @@ +{ + "CeilometerEvents.create_user_and_list_events": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_events.yaml b/samples/tasks/scenarios/ceilometer/create_user_and_list_events.yaml new file mode 100644 index 0000000000..6d6e12acbb --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_events.yaml @@ -0,0 +1,11 @@ +--- + CeilometerEvents.create_user_and_list_events: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_trait_descriptions.json b/samples/tasks/scenarios/ceilometer/create_user_and_list_trait_descriptions.json new file mode 100644 index 0000000000..9862b770f2 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_trait_descriptions.json @@ -0,0 +1,17 @@ +{ + "CeilometerTraits.create_user_and_list_trait_descriptions": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_trait_descriptions.yaml b/samples/tasks/scenarios/ceilometer/create_user_and_list_trait_descriptions.yaml new file mode 100644 index 0000000000..4c02f09def --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_trait_descriptions.yaml @@ -0,0 +1,11 @@ +--- + CeilometerTraits.create_user_and_list_trait_descriptions: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_traits.json b/samples/tasks/scenarios/ceilometer/create_user_and_list_traits.json new file mode 100644 index 0000000000..93f9e44616 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_traits.json @@ -0,0 +1,17 @@ +{ + "CeilometerTraits.create_user_and_list_traits": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 10 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + } + } + } + ] +} \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create_user_and_list_traits.yaml b/samples/tasks/scenarios/ceilometer/create_user_and_list_traits.yaml new file mode 100644 index 0000000000..6e8720a039 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/create_user_and_list_traits.yaml @@ -0,0 +1,11 @@ +--- + CeilometerTraits.create_user_and_list_traits: + - + runner: + type: "constant" + times: 10 + concurrency: 10 + context: + users: + tenants: 2 + users_per_tenant: 2 \ No newline at end of file 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 0000000000..bba48d82e7 --- /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 0000000000..8b787a916e --- /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 21aff9f215..54703a3c41 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)