diff --git a/subunit2sql/db/api.py b/subunit2sql/db/api.py index a0e2226..f17a355 100644 --- a/subunit2sql/db/api.py +++ b/subunit2sql/db/api.py @@ -817,20 +817,34 @@ def get_test_run_time_series(test_id, session=None): return time_series -def get_test_run_series(start_date=None, stop_date=None, session=None): +def get_test_run_series(start_date=None, stop_date=None, session=None, + key='build_queue', value='gate'): """Returns a time series dict of total daily run counts :param str start_date: Optional start date to filter results on :param str stop_date: Optional stop date to filter results on :param session: optional session object if one isn't provided a new session - + :param str key: optional run_metadata key to filter the runs used on. Key + must be specified with value for filtering to occur. + This defaults to 'build_queue' for backwards compatibility + with earlier versions. Note, this default will be removed + in the future. + :param str value: optional run_metadata value to filter the runs used on. + Value must be specified with key for filtering to occur. + This defaults to 'gate' for backwards + compatibility with earlier versions. Note, this default + will be removed in the future. :return dict: A dictionary with the dates as the keys and the values being the total run count for that day. (The sum of success and failures from all runs that started that day) """ session = session or get_session() - full_query = db_utils.model_query(models.Run, session=session).join( - models.RunMetadata).filter_by(key='build_queue', value='gate') + full_query = db_utils.model_query(models.Run, session=session) + if key and value: + full_query = full_query.join( + models.RunMetadata, + models.Run.id == models.RunMetadata.run_id).filter_by( + key=key, value=value) # Process date bounds full_query = _filter_runs_by_date(full_query, start_date, stop_date) diff --git a/subunit2sql/tests/db/test_api.py b/subunit2sql/tests/db/test_api.py index 32ce2f2..c41e6f4 100644 --- a/subunit2sql/tests/db/test_api.py +++ b/subunit2sql/tests/db/test_api.py @@ -360,6 +360,40 @@ class TestDatabaseAPI(base.TestCase): self.assertEqual(sorted(['test_a', 'test_b', 'test_c', 'test_d']), sorted(keys)) + def test_get_test_run_series(self): + timestamp_a = datetime.datetime.utcnow() + timestamp_b = timestamp_a + datetime.timedelta(minutes=2) + api.create_run(passes=5, run_at=timestamp_a) + api.create_run(fails=2, run_at=timestamp_b) + result = api.get_test_run_series(key=None, value=None) + self.assertEqual(2, len(result.keys())) + self.assertIn(timestamp_a.replace(microsecond=0), + [x.replace(microsecond=0) for x in list(result.keys())]) + self.assertIn(timestamp_b.replace(microsecond=0), + [x.replace(microsecond=0) for x in list(result.keys())]) + for timestamp in result: + if timestamp.replace( + microsecond=0) == timestamp_a.replace(microsecond=0): + self.assertEqual(5, result[timestamp]) + else: + self.assertEqual(2, result[timestamp]) + + def test_get_test_run_series_with_meta(self): + timestamp_a = datetime.datetime.utcnow() + timestamp_b = timestamp_a + datetime.timedelta(minutes=2) + run_a = api.create_run(passes=5, run_at=timestamp_a) + api.create_run(fails=2, run_at=timestamp_b) + api.add_run_metadata({'not_a_key': 'not_a_value'}, run_a.id) + result = api.get_test_run_series(key='not_a_key', + value='not_a_value') + self.assertEqual(1, len(result.keys())) + self.assertIn(timestamp_a.replace(microsecond=0), + [x.replace(microsecond=0) for x in list(result.keys())]) + self.assertNotIn(timestamp_b.replace(microsecond=0), + [x.replace(microsecond=0) for x in list( + result.keys())]) + self.assertEqual(5, result[list(result.keys())[0]]) + def test_get_test_run_dict_by_run_meta_key_value(self): timestamp_a = datetime.datetime.utcnow() timestamp_b = timestamp_a + datetime.timedelta(minutes=2)