Add new DB API function to get grouped run_time time series

This commit adds a new db API function,
get_run_times_time_series_grouped_by_run_metadata_key(), that will
return a time series dict of run_times grouped by a particular
run_metadata key.

Change-Id: I565aef69af1969bc0fb58a7c9459c9937658a19b
This commit is contained in:
Matthew Treinish 2016-09-14 12:36:30 -04:00
parent d1672a2a56
commit e6b5cab438
No known key found for this signature in database
GPG Key ID: FD12A0F214C9E177
3 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,7 @@
---
features:
- A new DB API function,
get_run_times_time_series_grouped_by_run_metadata_key(), similar to the
existing get_run_times_grouped_by_run_metadata_key() function except that
the output is a time series dict.

View File

@ -1258,6 +1258,65 @@ def get_run_times_grouped_by_run_metadata_key(key, start_date=None,
return result
def get_run_times_time_series_grouped_by_run_metadata_key(key, start_date=None,
stop_date=None,
session=None,
match_key=None,
match_value=None):
"""Get a times series dict of aggregate run times grouped by a metadata key
The results of the output can be limited to runs with a different matching
key value run_metadata pair using the match_key and match_value parameters.
:param key: The run_metadata key to use for grouping runs
:param session: Optional session object if one isn't provided a new session
will be acquired for the duration of this operation
:param str match_key: An optional key as part of a key value run_metadata
pair to filter the runs used to. This can not be the
same as the key parameter. If match_value is not also
specified this does nothing
:param str match_value: An optional value as part of a key value
run_metadata pair to filter the runs used to. If
match_key is not also specified this does nothing.
:return: A dictionary where keys are the time stamp and the value is a dict
with the key being the value of the provided metadata key
and the values are run times for the successful runs
:rtype: dict
"""
if key == match_key:
raise ValueError('match_key cannot have the same value as key')
session = session or get_session()
run_times_query = db_utils.model_query(models.Run, session).filter(
models.Run.fails == 0, models.Run.passes > 0).join(
models.RunMetadata,
models.Run.id == models.RunMetadata.run_id).filter(
models.RunMetadata.key == key)
if match_key and match_value:
subquery = session.query(models.RunMetadata.run_id).filter(
models.RunMetadata.key == match_key,
models.RunMetadata.value == match_value).subquery()
run_times_query = run_times_query.filter(models.Run.id.in_(subquery))
run_times_query = _filter_runs_by_date(run_times_query, start_date,
stop_date)
run_times = run_times_query.values(models.Run.run_at, models.Run.run_time,
models.RunMetadata.value)
result = {}
for run in run_times:
if run.run_at in result:
if run.value not in result[run.run_at]:
result[run.run_at][run.value] = run.run_time
# NOTE(mtreinish) if there is more than one run with the metadata
# value and the same start time, just average the results.
else:
old = result[run.run_at][run.value]
result[run.run_at][run.value] = float(old + run.run_time) / 2.0
else:
result[run.run_at] = {run.value: run.run_time}
return result
def get_test_counts_in_date_range(test_id, start_date=None, stop_date=None,
session=None):
"""Return the number of successes, failures, and skips for a single test.

View File

@ -461,6 +461,35 @@ class TestDatabaseAPI(base.TestCase):
expected_res = {'value_a': [2.2], 'value_b': [3.5]}
self.assertEqual(expected_res, res)
def test_get_run_time_series_grouped_by_run_metadata_key(self):
run_at_a = datetime.datetime(1914, 11, 11, 11, 11, 11)
run_a = api.create_run(run_time=2.2, passes=2, run_at=run_at_a)
run_at_b = datetime.datetime.utcnow().replace(microsecond=0)
run_b = api.create_run(run_time=3.5, passes=3, run_at=run_at_b)
api.add_run_metadata({'key': 'value_a'}, run_a.id)
api.add_run_metadata({'key': 'value_b'}, run_b.id)
res = api.get_run_times_time_series_grouped_by_run_metadata_key('key')
expected_res = {run_at_a: {'value_a': 2.2},
run_at_b: {'value_b': 3.5}}
self.assertEqual(expected_res, res)
def test_get_run_ts_grouped_by_run_meta_key_with_match_filter(self):
run_at_a = datetime.datetime(1914, 11, 11, 11, 11, 11)
run_a = api.create_run(run_time=2.2, passes=2, run_at=run_at_a)
run_at_b = datetime.datetime.utcnow().replace(microsecond=0)
run_b = api.create_run(run_time=3.5, passes=3, run_at=run_at_b)
run_c = api.create_run(run_time=75.432, passes=11)
api.add_run_metadata({'key': 'value_a'}, run_a.id)
api.add_run_metadata({'match_key': 'value_c'}, run_a.id)
api.add_run_metadata({'key': 'value_b'}, run_b.id)
api.add_run_metadata({'match_key': 'value_c'}, run_b.id)
api.add_run_metadata({'key': 'value_b'}, run_c.id)
res = api.get_run_times_time_series_grouped_by_run_metadata_key(
'key', match_key='match_key', match_value='value_c')
expected_res = {run_at_a: {'value_a': 2.2},
run_at_b: {'value_b': 3.5}}
self.assertEqual(expected_res, res)
def test_get_test_run_dict_by_run_meta_key_value(self):
timestamp_a = datetime.datetime.utcnow().replace(microsecond=0)
timestamp_b = timestamp_a + datetime.timedelta(minutes=2)