diff --git a/releasenotes/notes/add_key_value_metadata_filter_to_get_run_times-04af21788275df24.yaml b/releasenotes/notes/add_key_value_metadata_filter_to_get_run_times-04af21788275df24.yaml new file mode 100644 index 0000000..d961ee0 --- /dev/null +++ b/releasenotes/notes/add_key_value_metadata_filter_to_get_run_times-04af21788275df24.yaml @@ -0,0 +1,5 @@ +--- +features: + - A new set of options, *match_key* and *match_value* to filter the results + to a key value runs with a particular key value metadata pair was added to + the DB API function get_run_times_grouped_by_run_metadata_key(). diff --git a/subunit2sql/db/api.py b/subunit2sql/db/api.py index 626d17c..be1958c 100644 --- a/subunit2sql/db/api.py +++ b/subunit2sql/db/api.py @@ -1207,24 +1207,43 @@ def get_ids_for_all_tests(session=None): def get_run_times_grouped_by_run_metadata_key(key, start_date=None, - stop_date=None, session=None): + stop_date=None, session=None, + match_key=None, + match_value=None): """Return the aggregate run times for all runs 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 value of the provided metadata key and the values are a list of run_times for successful runs with that metadata value :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) diff --git a/subunit2sql/tests/db/test_api.py b/subunit2sql/tests/db/test_api.py index cf6524a..097ca74 100644 --- a/subunit2sql/tests/db/test_api.py +++ b/subunit2sql/tests/db/test_api.py @@ -447,6 +447,20 @@ class TestDatabaseAPI(base.TestCase): expected_res = {'value_a': [2.2], 'value_b': [3.5]} self.assertEqual(expected_res, res) + def test_get_run_times_grouped_by_run_metadata_key_with_match_filter(self): + run_a = api.create_run(run_time=2.2, passes=2) + run_b = api.create_run(run_time=3.5, passes=3) + 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_grouped_by_run_metadata_key( + 'key', match_key='match_key', match_value='value_c') + expected_res = {'value_a': [2.2], '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)