jadmanski | 430dca9 | 2008-12-16 20:56:53 +0000 | [diff] [blame] | 1 | import os, pickle, datetime, itertools, operator |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 2 | from django.db import models as dbmodels |
| 3 | from autotest_lib.frontend import thread_local |
| 4 | from autotest_lib.frontend.afe import rpc_utils, model_logic |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 5 | from autotest_lib.frontend.afe import readonly_connection |
showard | 250d84d | 2010-01-12 21:59:48 +0000 | [diff] [blame^] | 6 | from autotest_lib.frontend.tko import models, tko_rpc_utils, graphing_utils |
| 7 | from autotest_lib.frontend.tko import preconfigs |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 8 | |
| 9 | # table/spreadsheet view support |
| 10 | |
| 11 | def get_test_views(**filter_data): |
| 12 | return rpc_utils.prepare_for_serialization( |
| 13 | models.TestView.list_objects(filter_data)) |
| 14 | |
| 15 | |
| 16 | def get_num_test_views(**filter_data): |
| 17 | return models.TestView.query_count(filter_data) |
| 18 | |
| 19 | |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 20 | def get_group_counts(group_by, header_groups=None, fixed_headers=None, |
showard | 8b0ea22 | 2009-12-23 19:23:03 +0000 | [diff] [blame] | 21 | extra_select_fields=None, **filter_data): |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 22 | """ |
| 23 | Queries against TestView grouping by the specified fields and computings |
| 24 | counts for each group. |
| 25 | * group_by should be a list of field names. |
| 26 | * extra_select_fields can be used to specify additional fields to select |
| 27 | (usually for aggregate functions). |
| 28 | * header_groups can be used to get lists of unique combinations of group |
| 29 | fields. It should be a list of tuples of fields from group_by. It's |
| 30 | primarily for use by the spreadsheet view. |
showard | f248952 | 2008-10-23 23:08:00 +0000 | [diff] [blame] | 31 | * fixed_headers can map header fields to lists of values. the header will |
| 32 | guaranteed to return exactly those value. this does not work together |
| 33 | with header_groups. |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 34 | |
| 35 | Returns a dictionary with two keys: |
| 36 | * header_values contains a list of lists, one for each header group in |
| 37 | header_groups. Each list contains all the values for the corresponding |
| 38 | header group as tuples. |
| 39 | * groups contains a list of dicts, one for each row. Each dict contains |
| 40 | keys for each of the group_by fields, plus a 'group_count' key for the |
| 41 | total count in the group, plus keys for each of the extra_select_fields. |
| 42 | The keys for the extra_select_fields are determined by the "AS" alias of |
| 43 | the field. |
| 44 | """ |
showard | 8b0ea22 | 2009-12-23 19:23:03 +0000 | [diff] [blame] | 45 | query = models.TestView.objects.get_query_set_with_joins(filter_data) |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 46 | # don't apply presentation yet, since we have extra selects to apply |
| 47 | query = models.TestView.query_objects(filter_data, initial_query=query, |
| 48 | apply_presentation=False) |
showard | 7c199df | 2008-10-03 10:17:15 +0000 | [diff] [blame] | 49 | count_alias, count_sql = models.TestView.objects.get_count_sql(query) |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 50 | query = query.extra(select={count_alias: count_sql}) |
| 51 | if extra_select_fields: |
| 52 | query = query.extra(select=extra_select_fields) |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 53 | query = models.TestView.apply_presentation(query, filter_data) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 54 | |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 55 | group_processor = tko_rpc_utils.GroupDataProcessor(query, group_by, |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 56 | header_groups or [], |
| 57 | fixed_headers or {}) |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 58 | group_processor.process_group_dicts() |
| 59 | return rpc_utils.prepare_for_serialization(group_processor.get_info_dict()) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 60 | |
| 61 | |
| 62 | def get_num_groups(group_by, **filter_data): |
| 63 | """ |
| 64 | Gets the count of unique groups with the given grouping fields. |
| 65 | """ |
showard | d2b0c88 | 2009-10-19 18:34:11 +0000 | [diff] [blame] | 66 | query = models.TestView.objects.get_query_set_with_joins(filter_data) |
| 67 | query = models.TestView.query_objects(filter_data, initial_query=query) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 68 | return models.TestView.objects.get_num_groups(query, group_by) |
| 69 | |
| 70 | |
showard | 8c9b839 | 2008-09-30 10:38:21 +0000 | [diff] [blame] | 71 | def get_status_counts(group_by, header_groups=[], fixed_headers={}, |
showard | 8b0ea22 | 2009-12-23 19:23:03 +0000 | [diff] [blame] | 72 | **filter_data): |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 73 | """ |
| 74 | Like get_group_counts, but also computes counts of passed, complete (and |
| 75 | valid), and incomplete tests, stored in keys "pass_count', 'complete_count', |
| 76 | and 'incomplete_count', respectively. |
| 77 | """ |
showard | 8c9b839 | 2008-09-30 10:38:21 +0000 | [diff] [blame] | 78 | return get_group_counts(group_by, header_groups=header_groups, |
| 79 | fixed_headers=fixed_headers, |
showard | 7c199df | 2008-10-03 10:17:15 +0000 | [diff] [blame] | 80 | extra_select_fields=tko_rpc_utils.STATUS_FIELDS, |
| 81 | **filter_data) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 82 | |
| 83 | |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 84 | def get_latest_tests(group_by, header_groups=[], fixed_headers={}, |
showard | 8b0ea22 | 2009-12-23 19:23:03 +0000 | [diff] [blame] | 85 | extra_info=[], **filter_data): |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 86 | """ |
| 87 | Similar to get_status_counts, but return only the latest test result per |
| 88 | group. It still returns the same information (i.e. with pass count etc.) |
| 89 | for compatibility. |
showard | 77401f3 | 2009-05-26 19:34:05 +0000 | [diff] [blame] | 90 | @param extra_info a list containing the field names that should be returned |
| 91 | with each cell. The fields are returned in the extra_info |
| 92 | field of the return dictionary. |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 93 | """ |
| 94 | # find latest test per group |
showard | 8b0ea22 | 2009-12-23 19:23:03 +0000 | [diff] [blame] | 95 | query = models.TestView.objects.get_query_set_with_joins(filter_data) |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 96 | query = models.TestView.query_objects(filter_data, initial_query=query, |
| 97 | apply_presentation=False) |
showard | 763fd24 | 2009-12-10 21:40:16 +0000 | [diff] [blame] | 98 | query = query.exclude(status__in=tko_rpc_utils._INVALID_STATUSES) |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 99 | query = query.extra( |
| 100 | select={'latest_test_idx' : 'MAX(%s)' % |
| 101 | models.TestView.objects.get_key_on_this_table('test_idx')}) |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 102 | query = models.TestView.apply_presentation(query, filter_data) |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 103 | |
| 104 | group_processor = tko_rpc_utils.GroupDataProcessor(query, group_by, |
| 105 | header_groups, |
showard | 8bfb5cb | 2009-10-07 20:49:15 +0000 | [diff] [blame] | 106 | fixed_headers) |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 107 | group_processor.process_group_dicts() |
| 108 | info = group_processor.get_info_dict() |
| 109 | |
| 110 | # fetch full info for these tests so we can access their statuses |
| 111 | all_test_ids = [group['latest_test_idx'] for group in info['groups']] |
| 112 | test_views = models.TestView.objects.in_bulk(all_test_ids) |
| 113 | |
| 114 | for group_dict in info['groups']: |
| 115 | test_idx = group_dict.pop('latest_test_idx') |
| 116 | group_dict['test_idx'] = test_idx |
showard | 77401f3 | 2009-05-26 19:34:05 +0000 | [diff] [blame] | 117 | test_view = test_views[test_idx] |
| 118 | |
| 119 | tko_rpc_utils.add_status_counts(group_dict, test_view.status) |
| 120 | group_dict['extra_info'] = [] |
| 121 | for field in extra_info: |
| 122 | group_dict['extra_info'].append(getattr(test_view, field)) |
| 123 | |
| 124 | return rpc_utils.prepare_for_serialization(info) |
showard | 8a6eb0c | 2008-10-01 11:38:59 +0000 | [diff] [blame] | 125 | |
| 126 | |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 127 | def get_job_ids(**filter_data): |
| 128 | """ |
| 129 | Returns AFE job IDs for all tests matching the filters. |
| 130 | """ |
| 131 | query = models.TestView.query_objects(filter_data) |
| 132 | job_ids = set() |
| 133 | for test_view in query.values('job_tag').distinct(): |
| 134 | # extract job ID from tag |
showard | ec28156 | 2009-02-07 02:10:27 +0000 | [diff] [blame] | 135 | first_tag_component = test_view['job_tag'].split('-')[0] |
| 136 | try: |
| 137 | job_id = int(first_tag_component) |
| 138 | job_ids.add(job_id) |
| 139 | except ValueError: |
| 140 | # a nonstandard job tag, i.e. from contributed results |
| 141 | pass |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 142 | return list(job_ids) |
| 143 | |
| 144 | |
showard | e732ee7 | 2008-09-23 19:15:43 +0000 | [diff] [blame] | 145 | # test detail view |
| 146 | |
jadmanski | 430dca9 | 2008-12-16 20:56:53 +0000 | [diff] [blame] | 147 | def _attributes_to_dict(attribute_list): |
showard | f8b1904 | 2009-05-12 17:22:49 +0000 | [diff] [blame] | 148 | return dict((attribute.attribute, attribute.value) |
| 149 | for attribute in attribute_list) |
jadmanski | 430dca9 | 2008-12-16 20:56:53 +0000 | [diff] [blame] | 150 | |
| 151 | |
| 152 | def _iteration_attributes_to_dict(attribute_list): |
showard | f8b1904 | 2009-05-12 17:22:49 +0000 | [diff] [blame] | 153 | iter_keyfunc = operator.attrgetter('iteration') |
jadmanski | 430dca9 | 2008-12-16 20:56:53 +0000 | [diff] [blame] | 154 | attribute_list.sort(key=iter_keyfunc) |
| 155 | iterations = {} |
| 156 | for key, group in itertools.groupby(attribute_list, iter_keyfunc): |
| 157 | iterations[key] = _attributes_to_dict(group) |
| 158 | return iterations |
| 159 | |
| 160 | |
showard | f8b1904 | 2009-05-12 17:22:49 +0000 | [diff] [blame] | 161 | def _format_iteration_keyvals(test): |
| 162 | iteration_attr = _iteration_attributes_to_dict(test.iteration_attributes) |
| 163 | iteration_perf = _iteration_attributes_to_dict(test.iteration_results) |
| 164 | |
| 165 | all_iterations = iteration_attr.keys() + iteration_perf.keys() |
| 166 | max_iterations = max(all_iterations + [0]) |
| 167 | |
| 168 | # merge the iterations into a single list of attr & perf dicts |
| 169 | return [{'attr': iteration_attr.get(index, {}), |
| 170 | 'perf': iteration_perf.get(index, {})} |
| 171 | for index in xrange(1, max_iterations + 1)] |
| 172 | |
| 173 | |
showard | e732ee7 | 2008-09-23 19:15:43 +0000 | [diff] [blame] | 174 | def get_detailed_test_views(**filter_data): |
| 175 | test_views = models.TestView.list_objects(filter_data) |
showard | f8b1904 | 2009-05-12 17:22:49 +0000 | [diff] [blame] | 176 | tests_by_id = models.Test.objects.in_bulk([test_view['test_idx'] |
| 177 | for test_view in test_views]) |
| 178 | tests = tests_by_id.values() |
| 179 | models.Test.objects.populate_relationships(tests, models.TestAttribute, |
| 180 | 'attributes') |
| 181 | models.Test.objects.populate_relationships(tests, models.IterationAttribute, |
| 182 | 'iteration_attributes') |
| 183 | models.Test.objects.populate_relationships(tests, models.IterationResult, |
| 184 | 'iteration_results') |
| 185 | models.Test.objects.populate_relationships(tests, models.TestLabel, |
| 186 | 'labels') |
showard | e732ee7 | 2008-09-23 19:15:43 +0000 | [diff] [blame] | 187 | for test_view in test_views: |
showard | f8b1904 | 2009-05-12 17:22:49 +0000 | [diff] [blame] | 188 | test = tests_by_id[test_view['test_idx']] |
| 189 | test_view['attributes'] = _attributes_to_dict(test.attributes) |
| 190 | test_view['iterations'] = _format_iteration_keyvals(test) |
| 191 | test_view['labels'] = [label.name for label in test.labels] |
showard | e732ee7 | 2008-09-23 19:15:43 +0000 | [diff] [blame] | 192 | return rpc_utils.prepare_for_serialization(test_views) |
| 193 | |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 194 | # graphing view support |
| 195 | |
| 196 | def get_hosts_and_tests(): |
| 197 | """\ |
| 198 | Gets every host that has had a benchmark run on it. Additionally, also |
| 199 | gets a dictionary mapping the host names to the benchmarks. |
| 200 | """ |
| 201 | |
| 202 | host_info = {} |
| 203 | q = (dbmodels.Q(test_name__startswith='kernbench') | |
| 204 | dbmodels.Q(test_name__startswith='dbench') | |
| 205 | dbmodels.Q(test_name__startswith='tbench') | |
| 206 | dbmodels.Q(test_name__startswith='unixbench') | |
| 207 | dbmodels.Q(test_name__startswith='iozone')) |
| 208 | test_query = models.TestView.objects.filter(q).values( |
| 209 | 'test_name', 'hostname', 'machine_idx').distinct() |
| 210 | for result_dict in test_query: |
| 211 | hostname = result_dict['hostname'] |
| 212 | test = result_dict['test_name'] |
| 213 | machine_idx = result_dict['machine_idx'] |
| 214 | host_info.setdefault(hostname, {}) |
| 215 | host_info[hostname].setdefault('tests', []) |
| 216 | host_info[hostname]['tests'].append(test) |
| 217 | host_info[hostname]['id'] = machine_idx |
| 218 | return rpc_utils.prepare_for_serialization(host_info) |
| 219 | |
| 220 | |
showard | fbdab0b | 2009-04-29 19:49:50 +0000 | [diff] [blame] | 221 | def create_metrics_plot(queries, plot, invert, drilldown_callback, |
| 222 | normalize=None): |
| 223 | return graphing_utils.create_metrics_plot( |
| 224 | queries, plot, invert, normalize, drilldown_callback=drilldown_callback) |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 225 | |
| 226 | |
showard | fbdab0b | 2009-04-29 19:49:50 +0000 | [diff] [blame] | 227 | def create_qual_histogram(query, filter_string, interval, drilldown_callback): |
| 228 | return graphing_utils.create_qual_histogram( |
| 229 | query, filter_string, interval, drilldown_callback=drilldown_callback) |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 230 | |
| 231 | |
showard | e5ae165 | 2009-02-11 23:37:20 +0000 | [diff] [blame] | 232 | # TODO(showard) - this extremely generic RPC is used only by one place in the |
| 233 | # client. We should come up with a more opaque RPC for that place to call and |
| 234 | # get rid of this. |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 235 | def execute_query_with_param(query, param): |
showard | 56e9377 | 2008-10-06 10:06:22 +0000 | [diff] [blame] | 236 | cursor = readonly_connection.connection().cursor() |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 237 | cursor.execute(query, param) |
| 238 | return cursor.fetchall() |
| 239 | |
| 240 | |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 241 | def get_preconfig(name, type): |
showard | e5ae165 | 2009-02-11 23:37:20 +0000 | [diff] [blame] | 242 | return preconfigs.manager.get_preconfig(name, type) |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 243 | |
| 244 | |
| 245 | def get_embedding_id(url_token, graph_type, params): |
| 246 | try: |
| 247 | model = models.EmbeddedGraphingQuery.objects.get(url_token=url_token) |
| 248 | except models.EmbeddedGraphingQuery.DoesNotExist: |
| 249 | params_str = pickle.dumps(params) |
| 250 | now = datetime.datetime.now() |
| 251 | model = models.EmbeddedGraphingQuery(url_token=url_token, |
| 252 | graph_type=graph_type, |
| 253 | params=params_str, |
| 254 | last_updated=now) |
| 255 | model.cached_png = graphing_utils.create_embedded_plot(model, |
| 256 | now.ctime()) |
| 257 | model.save() |
| 258 | |
| 259 | return model.id |
| 260 | |
| 261 | |
| 262 | def get_embedded_query_url_token(id): |
| 263 | model = models.EmbeddedGraphingQuery.objects.get(id=id) |
| 264 | return model.url_token |
| 265 | |
| 266 | |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 267 | # test label management |
| 268 | |
| 269 | def add_test_label(name, description=None): |
| 270 | return models.TestLabel.add_object(name=name, description=description).id |
| 271 | |
| 272 | |
| 273 | def modify_test_label(label_id, **data): |
| 274 | models.TestLabel.smart_get(label_id).update_object(data) |
| 275 | |
| 276 | |
| 277 | def delete_test_label(label_id): |
| 278 | models.TestLabel.smart_get(label_id).delete() |
| 279 | |
| 280 | |
| 281 | def get_test_labels(**filter_data): |
| 282 | return rpc_utils.prepare_for_serialization( |
| 283 | models.TestLabel.list_objects(filter_data)) |
| 284 | |
| 285 | |
| 286 | def get_test_labels_for_tests(**test_filter_data): |
showard | 0281350 | 2008-08-20 20:52:56 +0000 | [diff] [blame] | 287 | label_ids = models.TestView.objects.query_test_label_ids(test_filter_data) |
| 288 | labels = models.TestLabel.list_objects({'id__in' : label_ids}) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 289 | return rpc_utils.prepare_for_serialization(labels) |
| 290 | |
| 291 | |
| 292 | def test_label_add_tests(label_id, **test_filter_data): |
showard | 0281350 | 2008-08-20 20:52:56 +0000 | [diff] [blame] | 293 | test_ids = models.TestView.objects.query_test_ids(test_filter_data) |
| 294 | models.TestLabel.smart_get(label_id).tests.add(*test_ids) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 295 | |
| 296 | |
| 297 | def test_label_remove_tests(label_id, **test_filter_data): |
showard | 0281350 | 2008-08-20 20:52:56 +0000 | [diff] [blame] | 298 | label = models.TestLabel.smart_get(label_id) |
| 299 | |
| 300 | # only include tests that actually have this label |
| 301 | extra_where = test_filter_data.get('extra_where', '') |
| 302 | if extra_where: |
| 303 | extra_where = '(' + extra_where + ') AND ' |
showard | eab66ce | 2009-12-23 00:03:56 +0000 | [diff] [blame] | 304 | extra_where += 'tko_test_labels.id = %s' % label.id |
showard | 0281350 | 2008-08-20 20:52:56 +0000 | [diff] [blame] | 305 | test_filter_data['extra_where'] = extra_where |
| 306 | test_ids = models.TestView.objects.query_test_ids(test_filter_data) |
| 307 | |
| 308 | label.tests.remove(*test_ids) |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 309 | |
| 310 | |
showard | f8b1904 | 2009-05-12 17:22:49 +0000 | [diff] [blame] | 311 | # user-created test attributes |
| 312 | |
| 313 | def set_test_attribute(attribute, value, **test_filter_data): |
| 314 | """ |
| 315 | * attribute - string name of attribute |
| 316 | * value - string, or None to delete an attribute |
| 317 | * test_filter_data - filter data to apply to TestView to choose tests to act |
| 318 | upon |
| 319 | """ |
| 320 | assert test_filter_data # disallow accidental actions on all hosts |
| 321 | test_ids = models.TestView.objects.query_test_ids(test_filter_data) |
| 322 | tests = models.Test.objects.in_bulk(test_ids) |
| 323 | |
| 324 | for test in tests.itervalues(): |
| 325 | test.set_or_delete_attribute(attribute, value) |
| 326 | |
| 327 | |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 328 | # saved queries |
| 329 | |
| 330 | def get_saved_queries(**filter_data): |
| 331 | return rpc_utils.prepare_for_serialization( |
| 332 | models.SavedQuery.list_objects(filter_data)) |
| 333 | |
| 334 | |
| 335 | def add_saved_query(name, url_token): |
| 336 | name = name.strip() |
| 337 | owner = thread_local.get_user() |
| 338 | existing_list = list(models.SavedQuery.objects.filter(owner=owner, |
| 339 | name=name)) |
| 340 | if existing_list: |
| 341 | query_object = existing_list[0] |
| 342 | query_object.url_token = url_token |
| 343 | query_object.save() |
| 344 | return query_object.id |
| 345 | |
| 346 | return models.SavedQuery.add_object(owner=owner, name=name, |
| 347 | url_token=url_token).id |
| 348 | |
| 349 | |
| 350 | def delete_saved_queries(id_list): |
| 351 | user = thread_local.get_user() |
| 352 | query = models.SavedQuery.objects.filter(id__in=id_list, owner=user) |
| 353 | if query.count() == 0: |
| 354 | raise model_logic.ValidationError('No such queries found for this user') |
| 355 | query.delete() |
| 356 | |
| 357 | |
| 358 | # other |
showard | b7a52fd | 2009-04-27 20:10:56 +0000 | [diff] [blame] | 359 | def get_motd(): |
| 360 | return rpc_utils.get_motd() |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 361 | |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 362 | |
| 363 | def get_static_data(): |
| 364 | result = {} |
| 365 | group_fields = [] |
| 366 | for field in models.TestView.group_fields: |
| 367 | if field in models.TestView.extra_fields: |
| 368 | name = models.TestView.extra_fields[field] |
| 369 | else: |
| 370 | name = models.TestView.get_field_dict()[field].verbose_name |
| 371 | group_fields.append((name.capitalize(), field)) |
| 372 | model_fields = [(field.verbose_name.capitalize(), field.column) |
| 373 | for field in models.TestView._meta.fields] |
| 374 | extra_fields = [(field_name.capitalize(), field_sql) |
| 375 | for field_sql, field_name |
| 376 | in models.TestView.extra_fields.iteritems()] |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 377 | |
| 378 | benchmark_key = { |
| 379 | 'kernbench' : 'elapsed', |
| 380 | 'dbench' : 'throughput', |
| 381 | 'tbench' : 'throughput', |
| 382 | 'unixbench' : 'score', |
| 383 | 'iozone' : '32768-4096-fwrite' |
| 384 | } |
| 385 | |
showard | eab66ce | 2009-12-23 00:03:56 +0000 | [diff] [blame] | 386 | tko_perf_view = [ |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 387 | ['Test Index', 'test_idx'], |
| 388 | ['Job Index', 'job_idx'], |
| 389 | ['Test Name', 'test_name'], |
| 390 | ['Subdirectory', 'subdir'], |
| 391 | ['Kernel Index', 'kernel_idx'], |
| 392 | ['Status Index', 'status_idx'], |
| 393 | ['Reason', 'reason'], |
| 394 | ['Host Index', 'machine_idx'], |
| 395 | ['Test Started Time', 'test_started_time'], |
| 396 | ['Test Finished Time', 'test_finished_time'], |
| 397 | ['Job Tag', 'job_tag'], |
| 398 | ['Job Name', 'job_name'], |
| 399 | ['Owner', 'job_owner'], |
| 400 | ['Job Queued Time', 'job_queued_time'], |
| 401 | ['Job Started Time', 'job_started_time'], |
| 402 | ['Job Finished Time', 'job_finished_time'], |
| 403 | ['Hostname', 'hostname'], |
| 404 | ['Platform', 'platform'], |
| 405 | ['Machine Owner', 'machine_owner'], |
| 406 | ['Kernel Hash', 'kernel_hash'], |
| 407 | ['Kernel Base', 'kernel_base'], |
| 408 | ['Kernel', 'kernel'], |
| 409 | ['Status', 'status'], |
| 410 | ['Iteration Number', 'iteration'], |
| 411 | ['Performance Keyval (Key)', 'iteration_key'], |
| 412 | ['Performance Keyval (Value)', 'iteration_value'], |
| 413 | ] |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 414 | |
| 415 | result['group_fields'] = sorted(group_fields) |
| 416 | result['all_fields'] = sorted(model_fields + extra_fields) |
| 417 | result['test_labels'] = get_test_labels(sort_by=['name']) |
showard | 250d84d | 2010-01-12 21:59:48 +0000 | [diff] [blame^] | 418 | result['current_user'] = rpc_utils.prepare_for_serialization( |
| 419 | thread_local.get_user().get_object_dict()) |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 420 | result['benchmark_key'] = benchmark_key |
showard | eab66ce | 2009-12-23 00:03:56 +0000 | [diff] [blame] | 421 | result['tko_perf_view'] = tko_perf_view |
| 422 | result['tko_test_view'] = model_fields |
showard | e5ae165 | 2009-02-11 23:37:20 +0000 | [diff] [blame] | 423 | result['preconfigs'] = preconfigs.manager.all_preconfigs() |
showard | edd5897 | 2009-04-16 03:08:27 +0000 | [diff] [blame] | 424 | result['motd'] = rpc_utils.get_motd() |
showard | ce12f55 | 2008-09-19 00:48:59 +0000 | [diff] [blame] | 425 | |
showard | 3544486 | 2008-08-07 22:35:30 +0000 | [diff] [blame] | 426 | return result |