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
This commit is contained in:
Igor Degtiarov 2015-11-11 10:44:58 +02:00
parent 402e1316ba
commit 9a4f0a45cd
9 changed files with 188 additions and 32 deletions

View File

@ -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:
-

View File

@ -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)

View File

@ -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):

View File

@ -14,4 +14,4 @@
context:
users:
tenants: 2
users_per_tenant: 2
users_per_tenant: 2

View File

@ -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"
}
}
]
}

View File

@ -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"

View File

@ -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"
)

View File

@ -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")