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

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: add assertion to check links 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
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
11 import os 11 import os
12 import sys 12 import sys
13 import urllib
13 14
14 CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) 15 CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
15 BASE_DIR = os.path.abspath(os.path.join( 16 BASE_DIR = os.path.abspath(os.path.join(
16 CURRENT_DIR, '..', '..', '..', '..', '..')) 17 CURRENT_DIR, '..', '..', '..', '..', '..'))
17 18
18 sys.path.append(os.path.join(BASE_DIR, 'build', 'android')) 19 sys.path.append(os.path.join(BASE_DIR, 'build', 'android'))
19 from pylib.utils import google_storage_helper # pylint: disable=import-error 20 from pylib.utils import google_storage_helper # pylint: disable=import-error
20 21
21 sys.path.append(os.path.join(BASE_DIR, 'third_party')) 22 sys.path.append(os.path.join(BASE_DIR, 'third_party'))
22 import jinja2 # pylint: disable=import-error 23 import jinja2 # pylint: disable=import-error
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if footer_row[FAIL_COUNT_INDEX]['data'] > 0: 246 if footer_row[FAIL_COUNT_INDEX]['data'] > 0:
246 footer_row[FAIL_COUNT_INDEX]['class'] += ' failure' 247 footer_row[FAIL_COUNT_INDEX]['class'] += ' failure'
247 else: 248 else:
248 footer_row[FAIL_COUNT_INDEX]['class'] += ' success' 249 footer_row[FAIL_COUNT_INDEX]['class'] += ' success'
249 250
250 return (header_row, 251 return (header_row,
251 [[suite_row] for suite_row in suite_row_dict.values()], 252 [[suite_row] for suite_row in suite_row_dict.values()],
252 footer_row) 253 footer_row)
253 254
254 255
255 def results_to_html(results_dict, cs_base_url): 256 def feedback_url(result_details_link):
257 url_args = urllib.urlencode([
258 ('labels', 'Pri-2,Type-Bug,Restrict-View-Google'),
259 ('summary', 'Result Details Feedback:'),
260 ('components', 'Test>Android'),
261 ('comment', 'Please check out: %s' % result_details_link)])
262 return 'https://bugs.chromium.org/p/chromium/issues/entry?%s' % url_args
263
264
265 def results_to_html(results_dict, cs_base_url, bucket, test_name,
266 builder_name, build_number):
256 """Convert list of test results into html format.""" 267 """Convert list of test results into html format."""
257 268
258 test_rows_header, test_rows = create_test_table(results_dict, cs_base_url) 269 test_rows_header, test_rows = create_test_table(results_dict, cs_base_url)
259 suite_rows_header, suite_rows, suite_row_footer = create_suite_table( 270 suite_rows_header, suite_rows, suite_row_footer = create_suite_table(
260 results_dict) 271 results_dict)
261 272
262 suite_table_values = { 273 suite_table_values = {
263 'table_id': 'suite-table', 274 'table_id': 'suite-table',
264 'table_headers': suite_rows_header, 275 'table_headers': suite_rows_header,
265 'table_row_blocks': suite_rows, 276 'table_row_blocks': suite_rows,
266 'table_footer': suite_row_footer, 277 'table_footer': suite_row_footer,
267 } 278 }
268 279
269 test_table_values = { 280 test_table_values = {
270 'table_id': 'test-table', 281 'table_id': 'test-table',
271 'table_headers': test_rows_header, 282 'table_headers': test_rows_header,
272 'table_row_blocks': test_rows, 283 'table_row_blocks': test_rows,
273 } 284 }
274 285
275 main_template = JINJA_ENVIRONMENT.get_template( 286 main_template = JINJA_ENVIRONMENT.get_template(
276 os.path.join('template', 'main.html')) 287 os.path.join('template', 'main.html'))
277 return main_template.render( # pylint: disable=no-member 288 dest = google_storage_helper.unique_name(
278 {'tb_values': [suite_table_values, test_table_values]}) 289 '%s_%s_%s' % (test_name, builder_name, build_number))
290
291 result_details_link = google_storage_helper.get_url_link(
292 dest, '%s/html' % bucket)
293
294 return (main_template.render( # pylint: disable=no-member
295 {'tb_values': [suite_table_values, test_table_values],
296 'feedback_url': feedback_url(result_details_link)
297 }), dest, result_details_link)
279 298
280 299
281 def result_details(json_path, cs_base_url): 300 def result_details(json_path, cs_base_url, bucket, test_name,
301 builder_name, build_number):
282 """Get result details from json path and then convert results to html.""" 302 """Get result details from json path and then convert results to html."""
283 303
284 with open(json_path) as json_file: 304 with open(json_path) as json_file:
285 json_object = json.loads(json_file.read()) 305 json_object = json.loads(json_file.read())
286 306
287 if not 'per_iteration_data' in json_object: 307 if not 'per_iteration_data' in json_object:
288 return 'Error: json file missing per_iteration_data.' 308 return 'Error: json file missing per_iteration_data.'
289 309
290 results_dict = collections.defaultdict(list) 310 results_dict = collections.defaultdict(list)
291 for testsuite_run in json_object['per_iteration_data']: 311 for testsuite_run in json_object['per_iteration_data']:
292 for test, test_runs in testsuite_run.iteritems(): 312 for test, test_runs in testsuite_run.iteritems():
293 results_dict[test].extend(test_runs) 313 results_dict[test].extend(test_runs)
294 return results_to_html(results_dict, cs_base_url) 314 return results_to_html(results_dict, cs_base_url, bucket,
315 test_name, builder_name, build_number)
295 316
296 317
297 def upload_to_google_bucket(html, test_name, builder_name, build_number, 318 def upload_to_google_bucket(html, bucket, dest):
298 bucket):
299 with tempfile.NamedTemporaryFile(suffix='.html') as temp_file: 319 with tempfile.NamedTemporaryFile(suffix='.html') as temp_file:
300 temp_file.write(html) 320 temp_file.write(html)
301 temp_file.flush() 321 temp_file.flush()
302
303 return google_storage_helper.upload( 322 return google_storage_helper.upload(
304 name=google_storage_helper.unique_name( 323 name=dest,
305 '%s_%s_%s' % (test_name, builder_name, build_number),
306 suffix='.html'),
307 filepath=temp_file.name, 324 filepath=temp_file.name,
308 bucket='%s/html' % bucket, 325 bucket='%s/html' % bucket,
309 content_type='text/html', 326 content_type='text/html',
310 authenticated_link=True) 327 authenticated_link=True)
311 328
312 329
313 def main(): 330 def main():
314 parser = argparse.ArgumentParser() 331 parser = argparse.ArgumentParser()
315 parser.add_argument('--json-file', help='Path of json file.') 332 parser.add_argument('--json-file', help='Path of json file.')
316 parser.add_argument('--cs-base-url', help='Base url for code search.', 333 parser.add_argument('--cs-base-url', help='Base url for code search.',
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 if args.positional: 390 if args.positional:
374 if not len(args.positional) == 1: 391 if not len(args.positional) == 1:
375 raise parser.error('More than 1 json file specified.') 392 raise parser.error('More than 1 json file specified.')
376 json_file = args.positional[0] 393 json_file = args.positional[0]
377 elif args.json_file: 394 elif args.json_file:
378 json_file = args.json_file 395 json_file = args.json_file
379 396
380 if not os.path.exists(json_file): 397 if not os.path.exists(json_file):
381 raise IOError('--json-file %s not found.' % json_file) 398 raise IOError('--json-file %s not found.' % json_file)
382 399
383 result_html_string = result_details(json_file, args.cs_base_url) 400 # Link to result details presentation page is a part of the page.
384 result_details_link = upload_to_google_bucket( 401 result_html_string, dest, result_details_link = result_details(
402 json_file, args.cs_base_url, args.bucket,
403 args.test_name, builder_name, build_number)
404
405 result_details_link_2 = upload_to_google_bucket(
385 result_html_string.encode('UTF-8'), 406 result_html_string.encode('UTF-8'),
386 args.test_name, builder_name, 407 args.bucket, dest)
387 build_number, args.bucket) 408
409 assert result_details_link == result_details_link_2, (
410 'Result details link do not match. The link returned by get_url_link'
411 ' should be the same as that returned by upload.')
388 412
389 if args.output_json: 413 if args.output_json:
390 with open(json_file) as original_json_file: 414 with open(json_file) as original_json_file:
391 json_object = json.load(original_json_file) 415 json_object = json.load(original_json_file)
392 json_object['links'] = {'result_details': result_details_link} 416 json_object['links'] = {'result_details': result_details_link}
393 with open(args.output_json, 'w') as f: 417 with open(args.output_json, 'w') as f:
394 json.dump(json_object, f) 418 json.dump(json_object, f)
395 else: 419 else:
396 print result_details_link 420 print result_details_link
397 421
398 if __name__ == '__main__': 422 if __name__ == '__main__':
399 sys.exit(main()) 423 sys.exit(main())
OLDNEW
« no previous file with comments | « build/android/pylib/results/presentation/template/main.html ('k') | build/android/pylib/utils/google_storage_helper.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698