| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 rowspan: Rowspan HTML attribute. | 71 rowspan: Rowspan HTML attribute. |
| 72 """ | 72 """ |
| 73 return { | 73 return { |
| 74 'cell_type': 'links', | 74 'cell_type': 'links', |
| 75 'class': html_class, | 75 'class': html_class, |
| 76 'links': links, | 76 'links': links, |
| 77 'rowspan': rowspan, | 77 'rowspan': rowspan, |
| 78 } | 78 } |
| 79 | 79 |
| 80 | 80 |
| 81 def action_cell(action, data, html_class): |
| 82 """Formats table cell with javascript actions. |
| 83 |
| 84 Args: |
| 85 action: Javscript action. |
| 86 data: Data in cell. |
| 87 class: Class for table cell. |
| 88 """ |
| 89 return { |
| 90 'cell_type': 'action', |
| 91 'action': action, |
| 92 'data': data, |
| 93 'class': html_class, |
| 94 } |
| 95 |
| 96 |
| 81 def logs_cell(result): | 97 def logs_cell(result): |
| 82 """Formats result logs data for processing in jinja template.""" | 98 """Formats result logs data for processing in jinja template.""" |
| 83 link_list = [] | 99 link_list = [] |
| 84 for name, href in result.get('links', {}).iteritems(): | 100 for name, href in result.get('links', {}).iteritems(): |
| 85 link_list.append(link( | 101 link_list.append(link( |
| 86 data=name, | 102 data=name, |
| 87 href=href, | 103 href=href, |
| 88 target=LinkTarget.NEW_TAB)) | 104 target=LinkTarget.NEW_TAB)) |
| 89 | 105 |
| 90 if link_list: | 106 if link_list: |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 174 |
| 159 header_row = [ | 175 header_row = [ |
| 160 cell(data='suite_name', html_class='text'), | 176 cell(data='suite_name', html_class='text'), |
| 161 cell(data='number_success_tests', html_class='number'), | 177 cell(data='number_success_tests', html_class='number'), |
| 162 cell(data='number_fail_tests', html_class='number'), | 178 cell(data='number_fail_tests', html_class='number'), |
| 163 cell(data='all_tests', html_class='number'), | 179 cell(data='all_tests', html_class='number'), |
| 164 cell(data='elapsed_time_ms', html_class='number'), | 180 cell(data='elapsed_time_ms', html_class='number'), |
| 165 ] | 181 ] |
| 166 | 182 |
| 167 footer_row = [ | 183 footer_row = [ |
| 168 links_cell( | 184 action_cell( |
| 169 links=[ | 185 'showTestsOfOneSuiteOnlyWithNewState("TOTAL")', |
| 170 link(href=('?suite=%s' % 'TOTAL'), | 186 'TOTAL', |
| 171 target=LinkTarget.CURRENT_TAB, | 187 'center' |
| 172 data='TOTAL') | 188 ), # TOTAL |
| 173 ], | |
| 174 ), # suite_name | |
| 175 cell(data=0), # number_success_tests | 189 cell(data=0), # number_success_tests |
| 176 cell(data=0), # number_fail_tests | 190 cell(data=0), # number_fail_tests |
| 177 cell(data=0), # all_tests | 191 cell(data=0), # all_tests |
| 178 cell(data=0), # elapsed_time_ms | 192 cell(data=0), # elapsed_time_ms |
| 179 ] | 193 ] |
| 180 | 194 |
| 181 suite_row_dict = {} | 195 suite_row_dict = {} |
| 182 for test_name, test_results in results_dict.iteritems(): | 196 for test_name, test_results in results_dict.iteritems(): |
| 183 # TODO(mikecase): This logic doesn't work if there are multiple test runs. | 197 # TODO(mikecase): This logic doesn't work if there are multiple test runs. |
| 184 # That is, if 'per_iteration_data' has multiple entries. | 198 # That is, if 'per_iteration_data' has multiple entries. |
| 185 # Since we only care about the result of the last test run. | 199 # Since we only care about the result of the last test run. |
| 186 result = test_results[-1] | 200 result = test_results[-1] |
| 187 | 201 |
| 188 suite_name = (test_name.split('#')[0] if '#' in test_name | 202 suite_name = (test_name.split('#')[0] if '#' in test_name |
| 189 else test_name.split('.')[0]) | 203 else test_name.split('.')[0]) |
| 190 if suite_name in suite_row_dict: | 204 if suite_name in suite_row_dict: |
| 191 suite_row = suite_row_dict[suite_name] | 205 suite_row = suite_row_dict[suite_name] |
| 192 else: | 206 else: |
| 193 suite_row = [ | 207 suite_row = [ |
| 194 links_cell( | 208 action_cell( |
| 195 links=[ | 209 'showTestsOfOneSuiteOnlyWithNewState("%s")' % suite_name, |
| 196 link(href=('?suite=%s' % suite_name), | 210 suite_name, |
| 197 target=LinkTarget.CURRENT_TAB, | 211 'left' |
| 198 data=suite_name)], | |
| 199 html_class='left' | |
| 200 ), # suite_name | 212 ), # suite_name |
| 201 cell(data=0), # number_success_tests | 213 cell(data=0), # number_success_tests |
| 202 cell(data=0), # number_fail_tests | 214 cell(data=0), # number_fail_tests |
| 203 cell(data=0), # all_tests | 215 cell(data=0), # all_tests |
| 204 cell(data=0), # elapsed_time_ms | 216 cell(data=0), # elapsed_time_ms |
| 205 ] | 217 ] |
| 206 | 218 |
| 207 suite_row_dict[suite_name] = suite_row | 219 suite_row_dict[suite_name] = suite_row |
| 208 | 220 |
| 209 suite_row[ALL_COUNT_INDEX]['data'] += 1 | 221 suite_row[ALL_COUNT_INDEX]['data'] += 1 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 sys.executable, gsutil_path, '-h', "Content-Type:%s" % content_type, | 304 sys.executable, gsutil_path, '-h', "Content-Type:%s" % content_type, |
| 293 'cp', temp_file.name, 'gs://%s/%s' % (bucket, dest)]) | 305 'cp', temp_file.name, 'gs://%s/%s' % (bucket, dest)]) |
| 294 | 306 |
| 295 return '%s/%s/%s' % (server_url, bucket, dest) | 307 return '%s/%s/%s' % (server_url, bucket, dest) |
| 296 | 308 |
| 297 def main(): | 309 def main(): |
| 298 parser = argparse.ArgumentParser() | 310 parser = argparse.ArgumentParser() |
| 299 parser.add_argument('--json-file', help='Path of json file.', required=True) | 311 parser.add_argument('--json-file', help='Path of json file.', required=True) |
| 300 parser.add_argument('--cs-base-url', help='Base url for code search.', | 312 parser.add_argument('--cs-base-url', help='Base url for code search.', |
| 301 default='http://cs.chromium.org') | 313 default='http://cs.chromium.org') |
| 302 parser.add_argument('--bucket', default='chromium-result-details') | 314 parser.add_argument('--bucket', help='Google storage bucket.', required=True) |
| 303 parser.add_argument('--builder-name', help='Builder name.', required=True) | 315 parser.add_argument('--builder-name', help='Builder name.', required=True) |
| 304 parser.add_argument('--build-number', help='Build number.', required=True) | 316 parser.add_argument('--build-number', help='Build number.', required=True) |
| 305 parser.add_argument('--test-name', help='The name of the test.', | 317 parser.add_argument('--test-name', help='The name of the test.', |
| 306 required=True) | 318 required=True) |
| 307 parser.add_argument('--server-url', help='The url of the server.', | 319 parser.add_argument('--server-url', help='The url of the server.', |
| 308 default='https://storage.googleapis.com') | 320 default='https://storage.cloud.google.com') |
| 309 parser.add_argument( | 321 parser.add_argument( |
| 310 '--content-type', | 322 '--content-type', |
| 311 help=('Content type, which is used to determine ' | 323 help=('Content type, which is used to determine ' |
| 312 'whether to download the file, or view in browser.'), | 324 'whether to download the file, or view in browser.'), |
| 313 default='text/html', | 325 default='text/html', |
| 314 choices=['text/html', 'application/octet-stream']) | 326 choices=['text/html', 'application/octet-stream']) |
| 315 | 327 |
| 316 args = parser.parse_args() | 328 args = parser.parse_args() |
| 317 if os.path.exists(args.json_file): | 329 if os.path.exists(args.json_file): |
| 318 result_html_string = result_details(args.json_file, args.cs_base_url, | 330 result_html_string = result_details(args.json_file, args.cs_base_url, |
| 319 args.bucket, args.server_url) | 331 args.bucket, args.server_url) |
| 320 print upload_to_google_bucket(result_html_string.encode('UTF-8'), | 332 print upload_to_google_bucket(result_html_string.encode('UTF-8'), |
| 321 args.test_name, args.builder_name, | 333 args.test_name, args.builder_name, |
| 322 args.build_number, args.bucket, | 334 args.build_number, args.bucket, |
| 323 args.server_url, args.content_type) | 335 args.server_url, args.content_type) |
| 324 else: | 336 else: |
| 325 raise IOError('--json-file %s not found.' % args.json_file) | 337 raise IOError('--json-file %s not found.' % args.json_file) |
| 326 | 338 |
| 327 | 339 |
| 328 if __name__ == '__main__': | 340 if __name__ == '__main__': |
| 329 sys.exit(main()) | 341 sys.exit(main()) |
| OLD | NEW |