OLD | NEW |
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 # | 2 # |
3 # Copyright 2017 The Chromium Authors. All rights reserved. | 3 # Copyright 2017 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 import argparse | 7 import argparse |
8 import collections | 8 import collections |
9 import json | 9 import json |
10 import tempfile | 10 import tempfile |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 class: Class for table cell. | 90 class: Class for table cell. |
91 """ | 91 """ |
92 return { | 92 return { |
93 'cell_type': 'action', | 93 'cell_type': 'action', |
94 'action': action, | 94 'action': action, |
95 'data': data, | 95 'data': data, |
96 'class': html_class, | 96 'class': html_class, |
97 } | 97 } |
98 | 98 |
99 | 99 |
100 def logs_cell(result): | 100 def flakiness_dashbord_link(test_name, suite_name): |
| 101 url_args = urllib.urlencode([ |
| 102 ('testType', suite_name), |
| 103 ('tests', test_name)]) |
| 104 return ('https://test-results.appspot.com/' |
| 105 'dashboards/flakiness_dashboard.html#%s' % url_args) |
| 106 |
| 107 |
| 108 def logs_cell(result, test_name, suite_name): |
101 """Formats result logs data for processing in jinja template.""" | 109 """Formats result logs data for processing in jinja template.""" |
102 link_list = [] | 110 link_list = [] |
103 for name, href in result.get('links', {}).iteritems(): | 111 for name, href in result.get('links', {}).iteritems(): |
104 link_list.append(link( | 112 link_list.append(link( |
105 data=name, | 113 data=name, |
106 href=href, | 114 href=href, |
107 target=LinkTarget.NEW_TAB)) | 115 target=LinkTarget.NEW_TAB)) |
108 | 116 link_list.append(link( |
| 117 data='flakiness', |
| 118 href=flakiness_dashbord_link(test_name, suite_name), |
| 119 target=LinkTarget.NEW_TAB)) |
109 if link_list: | 120 if link_list: |
110 return links_cell(link_list) | 121 return links_cell(link_list) |
111 else: | 122 else: |
112 return cell('(no logs)') | 123 return cell('(no logs)') |
113 | 124 |
114 | 125 |
115 def code_search(test, cs_base_url): | 126 def code_search(test, cs_base_url): |
116 """Returns URL for test on codesearch.""" | 127 """Returns URL for test on codesearch.""" |
117 search = test.replace('#', '.') | 128 search = test.replace('#', '.') |
118 return '%s/?q=%s&type=cs' % (cs_base_url, search) | 129 return '%s/?q=%s&type=cs' % (cs_base_url, search) |
119 | 130 |
120 | 131 |
121 def status_class(status): | 132 def status_class(status): |
122 """Returns HTML class for test status.""" | 133 """Returns HTML class for test status.""" |
123 if not status: | 134 if not status: |
124 return 'failure unknwon' | 135 return 'failure unknwon' |
125 status = status.lower() | 136 status = status.lower() |
126 if status not in ('success', 'skipped'): | 137 if status not in ('success', 'skipped'): |
127 return 'failure %s' % status | 138 return 'failure %s' % status |
128 return status | 139 return status |
129 | 140 |
130 | 141 |
131 def create_test_table(results_dict, cs_base_url): | 142 def create_test_table(results_dict, cs_base_url, suite_name): |
132 """Format test data for injecting into HTML table.""" | 143 """Format test data for injecting into HTML table.""" |
133 | 144 |
134 header_row = [ | 145 header_row = [ |
135 cell(data='test_name', html_class='text'), | 146 cell(data='test_name', html_class='text'), |
136 cell(data='status', html_class='flaky'), | 147 cell(data='status', html_class='flaky'), |
137 cell(data='elapsed_time_ms', html_class='number'), | 148 cell(data='elapsed_time_ms', html_class='number'), |
138 cell(data='logs', html_class='text'), | 149 cell(data='logs', html_class='text'), |
139 cell(data='output_snippet', html_class='text'), | 150 cell(data='output_snippet', html_class='text'), |
140 ] | 151 ] |
141 | 152 |
142 test_row_blocks = [] | 153 test_row_blocks = [] |
143 for test_name, test_results in results_dict.iteritems(): | 154 for test_name, test_results in results_dict.iteritems(): |
144 test_runs = [] | 155 test_runs = [] |
145 for index, result in enumerate(test_results): | 156 for index, result in enumerate(test_results): |
146 if index == 0: | 157 if index == 0: |
147 test_run = [links_cell( | 158 test_run = [links_cell( |
148 links=[ | 159 links=[ |
149 link(href=code_search(test_name, cs_base_url), | 160 link(href=code_search(test_name, cs_base_url), |
150 target=LinkTarget.NEW_TAB, | 161 target=LinkTarget.NEW_TAB, |
151 data=test_name)], | 162 data=test_name)], |
152 rowspan=len(test_results), | 163 rowspan=len(test_results), |
153 html_class='left %s' % test_name | 164 html_class='left %s' % test_name |
154 )] # test_name | 165 )] # test_name |
155 else: | 166 else: |
156 test_run = [] | 167 test_run = [] |
157 | 168 |
158 test_run.extend([ | 169 test_run.extend([ |
159 cell(data=result['status'] or 'UNKNOWN', | 170 cell(data=result['status'] or 'UNKNOWN', |
160 # status | 171 # status |
161 html_class=('center %s' % | 172 html_class=('center %s' % |
162 status_class(result['status']))), | 173 status_class(result['status']))), |
163 cell(data=result['elapsed_time_ms']), # elapsed_time_ms | 174 cell(data=result['elapsed_time_ms']), # elapsed_time_ms |
164 logs_cell(result), # logs | 175 logs_cell(result, test_name, suite_name), # logs |
165 pre_cell(data=result['output_snippet'], # output_snippet | 176 pre_cell(data=result['output_snippet'], # output_snippet |
166 html_class='left'), | 177 html_class='left'), |
167 ]) | 178 ]) |
168 test_runs.append(test_run) | 179 test_runs.append(test_run) |
169 test_row_blocks.append(test_runs) | 180 test_row_blocks.append(test_runs) |
170 return header_row, test_row_blocks | 181 return header_row, test_row_blocks |
171 | 182 |
172 | 183 |
173 def create_suite_table(results_dict): | 184 def create_suite_table(results_dict): |
174 """Format test suite data for injecting into HTML table.""" | 185 """Format test suite data for injecting into HTML table.""" |
175 | 186 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 ('summary', 'Result Details Feedback:'), | 270 ('summary', 'Result Details Feedback:'), |
260 ('components', 'Test>Android'), | 271 ('components', 'Test>Android'), |
261 ('comment', 'Please check out: %s' % result_details_link)]) | 272 ('comment', 'Please check out: %s' % result_details_link)]) |
262 return 'https://bugs.chromium.org/p/chromium/issues/entry?%s' % url_args | 273 return 'https://bugs.chromium.org/p/chromium/issues/entry?%s' % url_args |
263 | 274 |
264 | 275 |
265 def results_to_html(results_dict, cs_base_url, bucket, test_name, | 276 def results_to_html(results_dict, cs_base_url, bucket, test_name, |
266 builder_name, build_number): | 277 builder_name, build_number): |
267 """Convert list of test results into html format.""" | 278 """Convert list of test results into html format.""" |
268 | 279 |
269 test_rows_header, test_rows = create_test_table(results_dict, cs_base_url) | 280 test_rows_header, test_rows = create_test_table(results_dict, cs_base_url, |
| 281 test_name) |
270 suite_rows_header, suite_rows, suite_row_footer = create_suite_table( | 282 suite_rows_header, suite_rows, suite_row_footer = create_suite_table( |
271 results_dict) | 283 results_dict) |
272 | 284 |
273 suite_table_values = { | 285 suite_table_values = { |
274 'table_id': 'suite-table', | 286 'table_id': 'suite-table', |
275 'table_headers': suite_rows_header, | 287 'table_headers': suite_rows_header, |
276 'table_row_blocks': suite_rows, | 288 'table_row_blocks': suite_rows, |
277 'table_footer': suite_row_footer, | 289 'table_footer': suite_row_footer, |
278 } | 290 } |
279 | 291 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 with open(json_file) as original_json_file: | 426 with open(json_file) as original_json_file: |
415 json_object = json.load(original_json_file) | 427 json_object = json.load(original_json_file) |
416 json_object['links'] = {'result_details': result_details_link} | 428 json_object['links'] = {'result_details': result_details_link} |
417 with open(args.output_json, 'w') as f: | 429 with open(args.output_json, 'w') as f: |
418 json.dump(json_object, f) | 430 json.dump(json_object, f) |
419 else: | 431 else: |
420 print result_details_link | 432 print result_details_link |
421 | 433 |
422 if __name__ == '__main__': | 434 if __name__ == '__main__': |
423 sys.exit(main()) | 435 sys.exit(main()) |
OLD | NEW |