Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1924)

Side by Side Diff: build/android/pylib/results/presentation/test_results_presentation.py

Issue 2854083004: Fix feedback to populate the right content in issue creation page. (Closed)
Patch Set: sync Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/pylib/results/presentation/template/main.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 if footer_row[FAIL_COUNT_INDEX]['data'] > 0: 243 if footer_row[FAIL_COUNT_INDEX]['data'] > 0:
244 footer_row[FAIL_COUNT_INDEX]['class'] += ' failure' 244 footer_row[FAIL_COUNT_INDEX]['class'] += ' failure'
245 else: 245 else:
246 footer_row[FAIL_COUNT_INDEX]['class'] += ' success' 246 footer_row[FAIL_COUNT_INDEX]['class'] += ' success'
247 247
248 return (header_row, 248 return (header_row,
249 [[suite_row] for suite_row in suite_row_dict.values()], 249 [[suite_row] for suite_row in suite_row_dict.values()],
250 footer_row) 250 footer_row)
251 251
252 252
253 def results_to_html(results_dict, cs_base_url, bucket, server_url): 253 def feedback_url(result_details_link):
254 return ('https://bugs.chromium.org/p/chromium/issues/entry?'
jbudorick 2017/05/04 18:09:27 nit: this might be a bit more readable if you hand
BigBossZhiling 2017/05/05 21:57:57 Done.
255 'labels=Pri-2,Type-Bug,Restrict-View-Google&'
256 'summary=Result Details Feedback:'
257 '&components=Test%3EAndroid&'
258 'comment=Please check out: ') + result_details_link
259
260
261 def results_to_html(results_dict, cs_base_url, bucket, server_url, test_name,
262 builder_name, build_number):
254 """Convert list of test results into html format.""" 263 """Convert list of test results into html format."""
255 264
256 test_rows_header, test_rows = create_test_table(results_dict, cs_base_url) 265 test_rows_header, test_rows = create_test_table(results_dict, cs_base_url)
257 suite_rows_header, suite_rows, suite_row_footer = create_suite_table( 266 suite_rows_header, suite_rows, suite_row_footer = create_suite_table(
258 results_dict) 267 results_dict)
259 268
260 suite_table_values = { 269 suite_table_values = {
261 'table_id': 'suite-table', 270 'table_id': 'suite-table',
262 'table_headers': suite_rows_header, 271 'table_headers': suite_rows_header,
263 'table_row_blocks': suite_rows, 272 'table_row_blocks': suite_rows,
264 'table_footer': suite_row_footer, 273 'table_footer': suite_row_footer,
265 } 274 }
266 275
267 test_table_values = { 276 test_table_values = {
268 'table_id': 'test-table', 277 'table_id': 'test-table',
269 'table_headers': test_rows_header, 278 'table_headers': test_rows_header,
270 'table_row_blocks': test_rows, 279 'table_row_blocks': test_rows,
271 } 280 }
272 281
273 main_template = JINJA_ENVIRONMENT.get_template( 282 main_template = JINJA_ENVIRONMENT.get_template(
274 os.path.join('template', 'main.html')) 283 os.path.join('template', 'main.html'))
275 return main_template.render( # pylint: disable=no-member 284
285 dest = 'html/%s_%s_%s_%s.html' % (
286 test_name, builder_name, build_number,
287 time.strftime('%Y_%m_%d_T%H_%M_%S'))
288
289 result_details_link = '%s/%s/%s' % (server_url, bucket, dest)
290
291 return (main_template.render( # pylint: disable=no-member
276 {'tb_values': [suite_table_values, test_table_values], 292 {'tb_values': [suite_table_values, test_table_values],
277 'bucket': bucket, 'server_url': server_url}) 293 'bucket': bucket, 'server_url': server_url,
294 'feedback_url': feedback_url(result_details_link)}),
295 dest, result_details_link)
278 296
279 297
280 def result_details(json_path, cs_base_url, bucket, server_url): 298 def result_details(json_path, cs_base_url, bucket, server_url, test_name,
299 builder_name, build_number):
281 """Get result details from json path and then convert results to html.""" 300 """Get result details from json path and then convert results to html."""
282 301
283 with open(json_path) as json_file: 302 with open(json_path) as json_file:
284 json_object = json.loads(json_file.read()) 303 json_object = json.loads(json_file.read())
285 304
286 if not 'per_iteration_data' in json_object: 305 if not 'per_iteration_data' in json_object:
287 return 'Error: json file missing per_iteration_data.' 306 return 'Error: json file missing per_iteration_data.'
288 307
289 results_dict = collections.defaultdict(list) 308 results_dict = collections.defaultdict(list)
290 for testsuite_run in json_object['per_iteration_data']: 309 for testsuite_run in json_object['per_iteration_data']:
291 for test, test_runs in testsuite_run.iteritems(): 310 for test, test_runs in testsuite_run.iteritems():
292 results_dict[test].extend(test_runs) 311 results_dict[test].extend(test_runs)
293 return results_to_html(results_dict, cs_base_url, bucket, server_url) 312
313 return results_to_html(results_dict, cs_base_url, bucket, server_url,
314 test_name, builder_name, build_number)
294 315
295 316
296 def upload_to_google_bucket(html, test_name, builder_name, build_number, 317 def upload_to_google_bucket(html, bucket, dest, content_type):
297 bucket, server_url, content_type):
298 with tempfile.NamedTemporaryFile(suffix='.html') as temp_file: 318 with tempfile.NamedTemporaryFile(suffix='.html') as temp_file:
299 temp_file.write(html) 319 temp_file.write(html)
300 temp_file.flush() 320 temp_file.flush()
301 dest = 'html/%s_%s_%s_%s.html' % (
302 test_name, builder_name, build_number,
303 time.strftime('%Y_%m_%d_T%H_%M_%S'))
304 gsutil_path = os.path.join(BASE_DIR, 'third_party', 'catapult', 321 gsutil_path = os.path.join(BASE_DIR, 'third_party', 'catapult',
305 'third_party', 'gsutil', 'gsutil.py') 322 'third_party', 'gsutil', 'gsutil.py')
306 subprocess.check_call([ 323 subprocess.check_call([
307 sys.executable, gsutil_path, '-h', "Content-Type:%s" % content_type, 324 sys.executable, gsutil_path, '-h', "Content-Type:%s" % content_type,
308 'cp', temp_file.name, 'gs://%s/%s' % (bucket, dest)]) 325 'cp', temp_file.name, 'gs://%s/%s' % (bucket, dest)])
309 326
310 return '%s/%s/%s' % (server_url, bucket, dest)
311
312 327
313 def main(): 328 def main():
314 parser = argparse.ArgumentParser() 329 parser = argparse.ArgumentParser()
315 parser.add_argument('--json-file', help='Path of json file.') 330 parser.add_argument('--json-file', help='Path of json file.')
316 parser.add_argument('--cs-base-url', help='Base url for code search.', 331 parser.add_argument('--cs-base-url', help='Base url for code search.',
317 default='http://cs.chromium.org') 332 default='http://cs.chromium.org')
318 parser.add_argument('--bucket', help='Google storage bucket.', required=True) 333 parser.add_argument('--bucket', help='Google storage bucket.', required=True)
319 parser.add_argument('--builder-name', help='Builder name.') 334 parser.add_argument('--builder-name', help='Builder name.')
320 parser.add_argument('--build-number', help='Build number.') 335 parser.add_argument('--build-number', help='Build number.')
321 parser.add_argument('--test-name', help='The name of the test.', 336 parser.add_argument('--test-name', help='The name of the test.',
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 if args.positional: 396 if args.positional:
382 if not len(args.positional) == 1: 397 if not len(args.positional) == 1:
383 raise parser.error('More than 1 json file specified.') 398 raise parser.error('More than 1 json file specified.')
384 json_file = args.positional[0] 399 json_file = args.positional[0]
385 elif args.json_file: 400 elif args.json_file:
386 json_file = args.json_file 401 json_file = args.json_file
387 402
388 if not os.path.exists(json_file): 403 if not os.path.exists(json_file):
389 raise IOError('--json-file %s not found.' % json_file) 404 raise IOError('--json-file %s not found.' % json_file)
390 405
391 result_html_string = result_details(json_file, args.cs_base_url, 406 # Link to result details presentation page is a part of the page.
392 args.bucket, args.server_url) 407 result_html_string, dest, result_details_link = result_details(
393 result_details_link = upload_to_google_bucket( 408 json_file, args.cs_base_url, args.bucket, args.server_url,
409 args.test_name, builder_name, build_number)
410
411 upload_to_google_bucket(
394 result_html_string.encode('UTF-8'), 412 result_html_string.encode('UTF-8'),
395 args.test_name, builder_name, 413 args.bucket, dest, args.content_type)
396 build_number, args.bucket,
397 args.server_url, args.content_type)
398 414
399 if args.output_json: 415 if args.output_json:
400 with open(json_file) as original_json_file: 416 with open(json_file) as original_json_file:
401 json_object = json.load(original_json_file) 417 json_object = json.load(original_json_file)
402 json_object['links'] = {'result_details': result_details_link} 418 json_object['links'] = {'result_details': result_details_link}
403 with open(args.output_json, 'w') as f: 419 with open(args.output_json, 'w') as f:
404 json.dump(json_object, f) 420 json.dump(json_object, f)
405 else: 421 else:
406 print result_details_link 422 print result_details_link
407 423
408 if __name__ == '__main__': 424 if __name__ == '__main__':
409 sys.exit(main()) 425 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/pylib/results/presentation/template/main.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698