def get_group_counts(group_by, header_groups=[], fixed_headers={}, machine_label_headers={}, extra_select_fields={}, **filter_data): """ Queries against TestView grouping by the specified fields and computings counts for each group. * group_by should be a list of field names. * extra_select_fields can be used to specify additional fields to select (usually for aggregate functions). * header_groups can be used to get lists of unique combinations of group fields. It should be a list of tuples of fields from group_by. It's primarily for use by the spreadsheet view. * fixed_headers can map header fields to lists of values. the header will guaranteed to return exactly those value. this does not work together with header_groups. * machine_label_headers can specify special headers to be constructed from machine labels. It should map arbitrary names to lists of machine labels. a field will be created with the given name containing a comma-separated list indicating which of the given machine labels are on each test. this field can then be grouped on. Returns a dictionary with two keys: * header_values contains a list of lists, one for each header group in header_groups. Each list contains all the values for the corresponding header group as tuples. * groups contains a list of dicts, one for each row. Each dict contains keys for each of the group_by fields, plus a 'group_count' key for the total count in the group, plus keys for each of the extra_select_fields. The keys for the extra_select_fields are determined by the "AS" alias of the field. """ extra_select_fields = dict(extra_select_fields) query = models.TestView.objects.get_query_set_with_joins( filter_data, include_host_labels=bool(machine_label_headers)) query = models.TestView.query_objects(filter_data, initial_query=query) count_alias, count_sql = models.TestView.objects.get_count_sql(query) extra_select_fields[count_alias] = count_sql if 'test_idx' not in group_by: extra_select_fields['test_idx'] = 'test_idx' tko_rpc_utils.add_machine_label_headers(machine_label_headers, extra_select_fields) group_processor = tko_rpc_utils.GroupDataProcessor(query, group_by, header_groups, fixed_headers, extra_select_fields) group_processor.process_group_dicts() return rpc_utils.prepare_for_serialization(group_processor.get_info_dict())
def get_latest_tests(group_by, header_groups=[], fixed_headers={}, machine_label_headers={}, extra_info=[], **filter_data): """ Similar to get_status_counts, but return only the latest test result per group. It still returns the same information (i.e. with pass count etc.) for compatibility. @param extra_info a list containing the field names that should be returned with each cell. The fields are returned in the extra_info field of the return dictionary. """ # find latest test per group query = models.TestView.objects.get_query_set_with_joins( filter_data, include_host_labels=bool(machine_label_headers)) query = models.TestView.query_objects(filter_data, initial_query=query) query.exclude(status__in=tko_rpc_utils._INVALID_STATUSES) extra_fields = {'latest_test_idx' : 'MAX(%s)' % models.TestView.objects.get_key_on_this_table('test_idx')} tko_rpc_utils.add_machine_label_headers(machine_label_headers, extra_fields) group_processor = tko_rpc_utils.GroupDataProcessor(query, group_by, header_groups, fixed_headers, extra_fields) group_processor.process_group_dicts() info = group_processor.get_info_dict() # fetch full info for these tests so we can access their statuses all_test_ids = [group['latest_test_idx'] for group in info['groups']] test_views = models.TestView.objects.in_bulk(all_test_ids) for group_dict in info['groups']: test_idx = group_dict.pop('latest_test_idx') group_dict['test_idx'] = test_idx test_view = test_views[test_idx] tko_rpc_utils.add_status_counts(group_dict, test_view.status) group_dict['extra_info'] = [] for field in extra_info: group_dict['extra_info'].append(getattr(test_view, field)) return rpc_utils.prepare_for_serialization(info)