def get_runs_by_run_metadata_key(run_metadata_key, value): run_metadata_key = parse.unquote(run_metadata_key) value = parse.unquote(value) start_date = _parse_datetimes(flask.request.args.get('start_date', None)) stop_date = _parse_datetimes(flask.request.args.get('stop_date', None)) datetime_resolution = flask.request.args.get('datetime_resolution', 'day') if datetime_resolution not in ['sec', 'min', 'hour', 'day']: message = ('Datetime resolution: %s, is not a valid' ' choice' % datetime_resolution) status_code = 400 return abort(make_response(message, status_code)) with session_scope() as session: runs = (api.get_time_series_runs_by_key_value(run_metadata_key, value, start_date, stop_date, session)) # Groups runs by metadata group_by = "build_name" runs_by_build_name = _group_runs_by_key(runs, group_by) # Group runs by the chosen data_range. # That does not apply when you choose 'sec' since runs are already # grouped by it. aggregated_runs = \ RunAggregator(runs_by_build_name).aggregate(datetime_resolution) return jsonify(_aggregate_runs(aggregated_runs))
def test_get_time_series_runs_by_key_value(self): runs = [] run_at = datetime.datetime.utcnow() for run_num in moves.range(15): run = api.create_run(run_num, run_num + 1, run_num + 2, 3, run_at=run_at) runs.append(run) run_meta = {'test_key': 'fun', 'non_test': 'value-%s' % run_num} if run_num >= 3: run_meta = { 'test_key': 'no-fun', 'non_test': 'value-%s' % run_num } api.add_run_metadata(run_meta, run.id) runs_time_series = api.get_time_series_runs_by_key_value( 'test_key', 'fun') self.assertEqual(1, len(runs_time_series)) timestamp = list(runs_time_series.keys())[0] self.assertEqual(3, len(runs_time_series[timestamp])) for run_num in moves.range(3): run_dict = { 'skip': run_num, 'fail': run_num + 1, 'pass': run_num + 2, 'id': runs[run_num].uuid, 'run_time': 3.0, 'metadata': { u'test_key': u'fun', u'non_test': u'value-%s' % run_num } } self.assertIn(run_dict, runs_time_series[timestamp]) for run_num in moves.range(3, 14): missing_run_dict = { 'skip': run_num, 'fail': run_num + 1, 'pass': run_num + 2, 'id': runs[run_num].id, 'run_time': 3.0, 'metadata': { u'test_key': u'fun', u'non_test': u'value-%s' % run_num } } self.assertNotIn(missing_run_dict, runs_time_series[timestamp])
def get_runs_by_run_metadata_key(run_metadata_key, value): run_metadata_key = parse.unquote(run_metadata_key) value = parse.unquote(value) start_date = _parse_datetimes(flask.request.args.get('start_date', None)) stop_date = _parse_datetimes(flask.request.args.get('stop_date', None)) datetime_resolution = flask.request.args.get('datetime_resolution', 'day') if datetime_resolution not in ['sec', 'min', 'hour', 'day']: message = ('Datetime resolution: %s, is not a valid' ' choice' % datetime_resolution) status_code = 400 return abort(make_response(message, status_code)) with session_scope() as session: runs = (api.get_time_series_runs_by_key_value(run_metadata_key, value, start_date, stop_date, session)) # prepare run_times to be consumed for producing 'numeric' data. run_times = {} for run_at, run_data in runs.items(): for run in run_data: if run['fail'] > 0 or run['pass'] == 0: continue build_name = run['metadata']['build_name'] if run_at in run_times: if build_name in run_times[run_at]: run_times[run_at][build_name].append(run['run_time']) else: run_times[run_at][build_name] = [run['run_time']] else: run_times[run_at] = {build_name: [run['run_time']]} # if there is more than one run with the same run_at time # and build_name just average the results. for run_at, run_time_data in run_times.items(): for build_name, times in run_time_data.items(): run_times[run_at][build_name] = numpy.mean(times) numeric = run_aggregator.get_numeric_data(run_times, datetime_resolution) # Groups runs by metadata group_by = "build_name" runs_by_build_name = _group_runs_by_key(runs, group_by) # Group runs by the chosen data_range. # That does not apply when you choose 'sec' since runs are already # grouped by it. aggregated_runs = run_aggregator.RunAggregator( runs_by_build_name).aggregate(datetime_resolution) data = _aggregate_runs(aggregated_runs) return jsonify({'numeric': numeric, 'data': data})
def test_get_time_series_runs_by_key_value(self): runs = [] run_at = datetime.datetime.utcnow() for run_num in moves.range(15): run = api.create_run(run_num, run_num + 1, run_num + 2, 3, run_at=run_at) runs.append(run) run_meta = {'test_key': 'fun', 'non_test': 'value-%s' % run_num} if run_num >= 3: run_meta = {'test_key': 'no-fun', 'non_test': 'value-%s' % run_num} api.add_run_metadata(run_meta, run.id) runs_time_series = api.get_time_series_runs_by_key_value('test_key', 'fun') self.assertEqual(1, len(runs_time_series)) timestamp = list(runs_time_series.keys())[0] self.assertEqual(3, len(runs_time_series[timestamp])) for run_num in moves.range(3): run_dict = { 'skip': run_num, 'fail': run_num + 1, 'pass': run_num + 2, 'id': runs[run_num].uuid, 'run_time': 3.0, 'metadata': { u'test_key': u'fun', u'non_test': u'value-%s' % run_num } } self.assertIn(run_dict, runs_time_series[timestamp]) for run_num in moves.range(3, 14): missing_run_dict = { 'skip': run_num, 'fail': run_num + 1, 'pass': run_num + 2, 'id': runs[run_num].id, 'run_time': 3.0, 'metadata': { u'test_key': u'fun', u'non_test': u'value-%s' % run_num } } self.assertNotIn(missing_run_dict, runs_time_series[timestamp])