From 9a4f0a45cd719c9a8c9417d0bff6c4dcf4877175 Mon Sep 17 00:00:00 2001 From: Igor Degtiarov Date: Wed, 11 Nov 2015 10:44:58 +0200 Subject: [PATCH] Extend statistic benchmarks for Ceilometer Existing benchmark scenario for statistics was not benchmark at all it was check that statistic api works, now scenario was changed with using new Ceilometer context and adding new configured query parameters. It allows to find a weak places in requesting Ceilometer data. Change-Id: Iccde7422016e87f20237721b7fc1fb379646adf8 --- rally-jobs/rally.yaml | 56 +++++++++++++------ .../openstack/scenarios/ceilometer/stats.py | 34 ++++++++++- .../openstack/scenarios/ceilometer/utils.py | 15 ++++- .../create-meter-and-get-stats.json | 3 +- .../create-meter-and-get-stats.yaml | 2 +- .../tasks/scenarios/ceilometer/get-stats.json | 42 ++++++++++++++ .../tasks/scenarios/ceilometer/get-stats.yaml | 37 ++++++++++++ .../scenarios/ceilometer/test_stats.py | 29 +++++++--- .../scenarios/ceilometer/test_utils.py | 2 +- 9 files changed, 188 insertions(+), 32 deletions(-) create mode 100644 samples/tasks/scenarios/ceilometer/get-stats.json create mode 100644 samples/tasks/scenarios/ceilometer/get-stats.yaml diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index 3f79186d..4f26b886 100644 --- a/rally-jobs/rally.yaml +++ b/rally-jobs/rally.yaml @@ -717,25 +717,45 @@ failure_rate: max: 0 - CeilometerStats.create_meter_and_get_stats: + CeilometerStats.get_stats: - - args: - user_id: "user-id" - resource_id: "resource-id" - counter_volume: 1.0 - counter_unit: "" - counter_type: "cumulative" - runner: - type: "constant" - times: 20 - concurrency: 10 - context: - users: - tenants: 1 - users_per_tenant: 1 - sla: - failure_rate: - max: 0 + runner: + type: constant + times: 10 + concurrency: 2 + context: + users: + tenants: 2 + users_per_tenant: 2 + ceilometer: + counter_name: "benchmark_meter" + counter_type: "gauge" + counter_unit: "%" + counter_volume: 100 + resources_per_tenant: 100 + samples_per_resource: 100 + timestamp_interval: 10 + metadata_list: + - + status: "active" + name: "rally benchmark on" + deleted: "false" + - + status: "terminated" + name: "rally benchmark off" + deleted: "true" + args: + meter_name: "benchmark_meter" + filter_by_user_id: true + filter_by_project_id: true + filter_by_resource_id: true + metadata_query: + status: "terminated" + period: 300 + groupby: "resource_id" + sla: + failure_rate: + max: 0 CeilometerQueries.create_and_query_alarms: - diff --git a/rally/plugins/openstack/scenarios/ceilometer/stats.py b/rally/plugins/openstack/scenarios/ceilometer/stats.py index 24a7b841..93e549e3 100644 --- a/rally/plugins/openstack/scenarios/ceilometer/stats.py +++ b/rally/plugins/openstack/scenarios/ceilometer/stats.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from rally.common import log from rally import consts from rally.plugins.openstack import scenario from rally.plugins.openstack.scenarios.ceilometer import utils @@ -21,9 +22,11 @@ from rally.task import validation class CeilometerStats(utils.CeilometerScenario): """Benchmark scenarios for Ceilometer Stats API.""" + @log.log_deprecated("Use 'get_stats' method, now samples are created in " + "context", "0.1.2") @validation.required_services(consts.Service.CEILOMETER) @validation.required_openstack(users=True) - @scenario.configure(context={"cleanup": ["ceilometer"]}) + @scenario.configure() def create_meter_and_get_stats(self, **kwargs): """Create a meter and fetch its statistics. @@ -34,3 +37,32 @@ class CeilometerStats(utils.CeilometerScenario): """ meter = self._create_meter(**kwargs) self._get_stats(meter.counter_name) + + @validation.required_services(consts.Service.CEILOMETER) + @validation.required_openstack(users=True) + @scenario.configure() + def get_stats(self, meter_name, filter_by_user_id=False, + filter_by_project_id=False, filter_by_resource_id=False, + metadata_query=None, period=None, groupby=None, + aggregates=None): + """Fetch statistics for certain meter. + + Statistics is fetched for the using + GET /v2/meters/(meter_name)/statistics. + + :param meter_name: meter to take statistic for + :param filter_by_user_id: flag for query by user_id + :param filter_by_project_id: flag for query by project_id + :param filter_by_resource_id: flag for query by resource_id + :param metadata_query: dict with metadata fields and values for query + :param period: the length of the time range covered by these stats + :param groupby: the fields used to group the samples + :param aggregates: name of function for samples aggregation + + :returns: list of statistics data + """ + query = self._make_general_query(filter_by_project_id, + filter_by_user_id, + filter_by_resource_id, + metadata_query) + self._get_stats(meter_name, query, period, groupby, aggregates) diff --git a/rally/plugins/openstack/scenarios/ceilometer/utils.py b/rally/plugins/openstack/scenarios/ceilometer/utils.py index 9839c67a..186a3f95 100644 --- a/rally/plugins/openstack/scenarios/ceilometer/utils.py +++ b/rally/plugins/openstack/scenarios/ceilometer/utils.py @@ -317,12 +317,23 @@ class CeilometerScenario(scenario.OpenStackScenario): return self.clients("ceilometer").resources.get(resource_id) @atomic.action_timer("ceilometer.get_stats") - def _get_stats(self, meter_name): + def _get_stats(self, meter_name, query=None, period=None, groupby=None, + aggregates=None): """Get stats for a specific meter. :param meter_name: Name of ceilometer meter + :param query: list of queries + :param period: the length of the time range covered by these stats + :param groupby: the fields used to group the samples + :param aggregates: function for samples aggregation + + :returns: list of statistics data """ - return self.clients("ceilometer").statistics.list(meter_name) + return self.clients("ceilometer").statistics.list(meter_name, q=query, + period=period, + groupby=groupby, + aggregates=aggregates + ) @atomic.action_timer("ceilometer.create_meter") def _create_meter(self, **kwargs): diff --git a/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.json b/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.json index ec1369c6..b667ded0 100644 --- a/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.json +++ b/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.json @@ -21,5 +21,4 @@ } } ] -} - +} \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.yaml b/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.yaml index f3a5d975..bd53046c 100644 --- a/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.yaml +++ b/samples/tasks/scenarios/ceilometer/create-meter-and-get-stats.yaml @@ -14,4 +14,4 @@ context: users: tenants: 2 - users_per_tenant: 2 + users_per_tenant: 2 \ No newline at end of file diff --git a/samples/tasks/scenarios/ceilometer/get-stats.json b/samples/tasks/scenarios/ceilometer/get-stats.json new file mode 100644 index 00000000..df0c9572 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/get-stats.json @@ -0,0 +1,42 @@ +{ + "CeilometerStats.get_stats": [ + { + "runner": { + "type": "constant", + "times": 10, + "concurrency": 1 + }, + "context": { + "users": { + "tenants": 2, + "users_per_tenant": 2 + }, + "ceilometer": { + "counter_name": "benchmark_meter", + "counter_type": "gauge", + "counter_unit": "%", + "counter_volume": 100, + "resources_per_tenant": 100, + "samples_per_resource": 100, + "timestamp_interval": 10, + "metadata_list": [ + {"status": "active", "name": "rally benchmark on", + "deleted": "false"}, + {"status": "terminated", "name": "rally benchmark off", + "deleted": "true"} + ] + } + }, + "args": { + "meter_name": "benchmark_meter", + "filter_by_user_id": true, + "filter_by_project_id": true, + "filter_by_resource_id": true, + "metadata_query": {"status": "terminated"}, + "period": 300, + "groupby": "resource_id" + } + } + ] +} + diff --git a/samples/tasks/scenarios/ceilometer/get-stats.yaml b/samples/tasks/scenarios/ceilometer/get-stats.yaml new file mode 100644 index 00000000..83692943 --- /dev/null +++ b/samples/tasks/scenarios/ceilometer/get-stats.yaml @@ -0,0 +1,37 @@ +--- + CeilometerStats.get_stats: + - + runner: + type: constant + times: 10 + concurrency: 1 + context: + users: + tenants: 2 + users_per_tenant: 2 + ceilometer: + counter_name: "benchmark_meter" + counter_type: "gauge" + counter_unit: "%" + counter_volume: 100 + resources_per_tenant: 100 + samples_per_resource: 100 + timestamp_interval: 10 + metadata_list: + - + status: "active" + name: "rally benchmark on" + deleted: "false" + - + status: "terminated" + name: "rally benchmark off" + deleted: "true" + args: + meter_name: "benchmark_meter" + filter_by_user_id: true + filter_by_project_id: true + filter_by_resource_id: true + metadata_query: + status: "terminated" + period: 300 + groupby: "resource_id" diff --git a/tests/unit/plugins/openstack/scenarios/ceilometer/test_stats.py b/tests/unit/plugins/openstack/scenarios/ceilometer/test_stats.py index d9470e1f..41a235d8 100644 --- a/tests/unit/plugins/openstack/scenarios/ceilometer/test_stats.py +++ b/tests/unit/plugins/openstack/scenarios/ceilometer/test_stats.py @@ -19,12 +19,27 @@ from tests.unit import test class CeilometerStatsTestCase(test.ScenarioTestCase): - def test_create_meter_and_get_stats(self): - fake_meter = mock.MagicMock() - kwargs = mock.MagicMock() + + def test_get_stats(self): scenario = stats.CeilometerStats(self.context) - scenario._create_meter = mock.MagicMock(return_value=fake_meter) scenario._get_stats = mock.MagicMock() - scenario.create_meter_and_get_stats(**kwargs) - scenario._create_meter.assert_called_once_with(**kwargs) - scenario._get_stats.assert_called_once_with(fake_meter.counter_name) + context = {"user": {"tenant_id": "fake", "id": "fake_id"}, + "tenant": {"id": "fake_id", + "resources": ["fake_resource"]}} + metadata_query = {"a": "test"} + period = 10 + groupby = "user_id" + aggregates = "sum" + scenario.context = context + scenario.get_stats("fake_meter", True, True, True, metadata_query, + period, groupby, aggregates) + scenario._get_stats.assert_called_once_with( + "fake_meter", + [{"field": "user_id", "value": "fake_id", "op": "eq"}, + {"field": "project_id", "value": "fake_id", "op": "eq"}, + {"field": "resource_id", "value": "fake_resource", "op": "eq"}, + {"field": "metadata.a", "value": "test", "op": "eq"}], + 10, + "user_id", + "sum" + ) diff --git a/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py b/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py index eeaab407..a8f1ae0c 100644 --- a/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py @@ -239,7 +239,7 @@ class CeilometerScenarioTestCase(test.ScenarioTestCase): self.scenario._get_stats("fake-meter"), self.clients("ceilometer").statistics.list.return_value) self.clients("ceilometer").statistics.list.assert_called_once_with( - "fake-meter") + "fake-meter", q=None, period=None, groupby=None, aggregates=None) self._test_atomic_action_timer(self.scenario.atomic_actions(), "ceilometer.get_stats")