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

Side by Side Diff: appengine/findit/util_scripts/remote_queries/try_job_data_metrics.py

Issue 2107623002: [Findit] Adding support for splitting try job data by trybot (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 4 years, 5 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 | « no previous file | 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 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Pulls historical try job metadata from Findit and prints a report.""" 5 """Pulls historical try job metadata from Findit and prints a report."""
6 6
7 import argparse 7 import argparse
8 from collections import defaultdict 8 from collections import defaultdict
9 import datetime 9 import datetime
10 import json
10 import numpy 11 import numpy
11 import os 12 import os
12 import sys 13 import sys
13 14
14 _REMOTE_API_DIR = os.path.join(os.path.dirname(__file__), os.path.pardir) 15 _REMOTE_API_DIR = os.path.join(os.path.dirname(__file__), os.path.pardir)
15 sys.path.insert(1, _REMOTE_API_DIR) 16 sys.path.insert(1, _REMOTE_API_DIR)
16 17
17 import remote_api 18 import remote_api
18 19
19 from model.wf_try_job_data import WfTryJobData 20 from model.wf_try_job_data import WfTryJobData
(...skipping 26 matching lines...) Expand all
46 'mac': 'mac', 47 'mac': 'mac',
47 'ios': 'ios', 48 'ios': 'ios',
48 } 49 }
49 50
50 for os_name, platform in os_map.iteritems(): 51 for os_name, platform in os_map.iteritems():
51 if os_name in builder_name: 52 if os_name in builder_name:
52 return platform 53 return platform
53 54
54 return 'unknown' 55 return 'unknown'
55 56
57 def _GetTrybotName(buildbucket_response):
58 # First try parameters_json.
59 parameters = json.loads(buildbucket_response.get('parameters_json', '{}'))
60 trybot = parameters.get('builder_name')
61
62 if not trybot:
63 # Fallback to response_details_json.
64 response_details = json.loads(
65 buildbucket_response.get('response_details_json', '{}'))
66 properties = response_details.get('properties', {})
67 trybot = properties.get('buildername')
68
69 if not trybot:
70 trybot = 'unknown'
71
72 return trybot
56 73
57 def _GetAverageOfNumbersInList(numbers): 74 def _GetAverageOfNumbersInList(numbers):
58 """Returns a float average of numbers or NOT_AVAILABLE if numbers is empty.""" 75 """Returns a float average of numbers or NOT_AVAILABLE if numbers is empty."""
59 return (float(sum(numbers)) / len(numbers)) if numbers else NOT_AVAILABLE 76 return (float(sum(numbers)) / len(numbers)) if numbers else NOT_AVAILABLE
60 77
61 78
62 def _FormatDigits(number): 79 def _FormatDigits(number):
63 """Formats number into a 2-digit float, or NOT_AVAILABLE.""" 80 """Formats number into a 2-digit float, or NOT_AVAILABLE."""
64 if isinstance(number, float): 81 if isinstance(number, float):
65 return float('%.2f' % number) 82 return float('%.2f' % number)
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 415
399 if not master_name or not builder_name: 416 if not master_name or not builder_name:
400 continue 417 continue
401 418
402 platform = _GetOSPlatformName(master_name, builder_name) 419 platform = _GetOSPlatformName(master_name, builder_name)
403 categorized_data_dict[platform].append(try_job_data) 420 categorized_data_dict[platform].append(try_job_data)
404 421
405 return categorized_data_dict 422 return categorized_data_dict
406 423
407 424
425 def _SplitListByTrybot(try_job_data_list):
426 categorized_data_dict = defaultdict(list)
427
428 for try_job_data in try_job_data_list:
429 if not try_job_data.last_buildbucket_response:
430 continue
431
432 trybot = _GetTrybotName(try_job_data.last_buildbucket_response)
433 categorized_data_dict[trybot].append(try_job_data)
434
435 return categorized_data_dict
436
437
408 def SplitListByOption(try_job_data_list, option): 438 def SplitListByOption(try_job_data_list, option):
409 """Takes a WfTryJobData list and separates it into a dict based on arg. 439 """Takes a WfTryJobData list and separates it into a dict based on arg.
410 440
411 Args: 441 Args:
412 try_job_data_list: A list of WfTryJobData entities. 442 try_job_data_list: A list of WfTryJobData entities.
413 option: An option with which to split the data by. 443 option: An option with which to split the data by.
414 444
415 Returns: 445 Returns:
416 A dict where the keys are how the data is separated based on arg and the 446 A dict where the keys are how the data is separated based on arg and the
417 values are the corresponding lists of data. 447 values are the corresponding lists of data.
418 """ 448 """
419 449
420 if option == 't': # Try job type. 450 if option == 'b': # Main waterfall builder.
421 return _SplitListByTryJobType(try_job_data_list)
422 elif option == 'm': # Main waterfall master.
423 return _SplitListByMaster(try_job_data_list)
424 elif option == 'b': # Main waterfall builder.
425 return _SplitListByBuilder(try_job_data_list) 451 return _SplitListByBuilder(try_job_data_list)
426 elif option == 'r': # Whether or not heuristic results are included.
427 return _SplitListByHeuristicResults(try_job_data_list)
428 elif option == 'c': # Whether or not compile targets are included. 452 elif option == 'c': # Whether or not compile targets are included.
429 return _SplitListByCompileTargets(try_job_data_list) 453 return _SplitListByCompileTargets(try_job_data_list)
430 elif option == 'e': # Whether or not try jobs with errors should be counted. 454 elif option == 'e': # Whether or not try jobs with errors should be counted.
431 return _SplitListByError(try_job_data_list) 455 return _SplitListByError(try_job_data_list)
456 elif option == 'm': # Main waterfall master.
457 return _SplitListByMaster(try_job_data_list)
432 elif option == 'p': # Split by OS platform. 458 elif option == 'p': # Split by OS platform.
433 return _SplitListByPlatform(try_job_data_list) 459 return _SplitListByPlatform(try_job_data_list)
460 elif option == 'r': # Whether or not heuristic results are included.
461 return _SplitListByHeuristicResults(try_job_data_list)
462 elif option == 't': # Try job type.
463 return _SplitListByTryJobType(try_job_data_list)
464 elif option == 'T': # Split by trybot.
465 return _SplitListByTrybot(try_job_data_list)
434 466
435 # Unsupported flag, bail out without modification. 467 # Unsupported flag, bail out without modification.
436 return try_job_data_list 468 return try_job_data_list
437 469
438 470
439 def SplitStructByOption(try_job_data_struct, option): 471 def SplitStructByOption(try_job_data_struct, option):
440 if isinstance(try_job_data_struct, list): 472 if isinstance(try_job_data_struct, list):
441 try_job_data_struct = SplitListByOption(try_job_data_struct, option) 473 try_job_data_struct = SplitListByOption(try_job_data_struct, option)
442 elif isinstance(try_job_data_struct, dict): 474 elif isinstance(try_job_data_struct, dict):
443 for key, struct in try_job_data_struct.iteritems(): 475 for key, struct in try_job_data_struct.iteritems():
(...skipping 18 matching lines...) Expand all
462 'errors detected')) 494 'errors detected'))
463 parser.add_argument('-m', action='store_true', 495 parser.add_argument('-m', action='store_true',
464 help='group try job data by master') 496 help='group try job data by master')
465 parser.add_argument('-p', action='store_true', 497 parser.add_argument('-p', action='store_true',
466 help='group try job data by platform') 498 help='group try job data by platform')
467 parser.add_argument('-r', action='store_true', 499 parser.add_argument('-r', action='store_true',
468 help=('group try job data by those with and without ' 500 help=('group try job data by those with and without '
469 'heuristic results')) 501 'heuristic results'))
470 parser.add_argument('-t', action='store_true', 502 parser.add_argument('-t', action='store_true',
471 help='group try job data by type (compile, test)') 503 help='group try job data by type (compile, test)')
504 parser.add_argument('-T', action='store_true',
505 help='group try job data by trybot')
stgao 2016/06/29 01:01:13 how about "--trybot" instead of the short version
lijeffrey 2016/06/30 01:38:55 Done.
472 506
473 args_dict = vars(parser.parse_args()) 507 args_dict = vars(parser.parse_args())
474 508
475 # Preserve order from original command. 509 # Preserve order from original command.
476 ordered_args = [] 510 ordered_args = []
477 511
478 for original_arg in command_line_args: 512 for original_arg in command_line_args:
479 parsed_arg = original_arg[1:] 513 parsed_arg = original_arg[1:]
480 if args_dict[parsed_arg]: 514 if args_dict[parsed_arg]:
481 ordered_args.append(parsed_arg) 515 ordered_args.append(parsed_arg)
(...skipping 12 matching lines...) Expand all
494 WfTryJobData.request_time >= START_DATE, 528 WfTryJobData.request_time >= START_DATE,
495 WfTryJobData.request_time < END_DATE) 529 WfTryJobData.request_time < END_DATE)
496 categorized_data = try_job_data_query.fetch() 530 categorized_data = try_job_data_query.fetch()
497 531
498 args = GetArgsInOrder() 532 args = GetArgsInOrder()
499 for arg in args: 533 for arg in args:
500 categorized_data = SplitStructByOption(categorized_data, arg) 534 categorized_data = SplitStructByOption(categorized_data, arg)
501 535
502 # TODO(lijeffrey): Display data in an html page instead of printing. 536 # TODO(lijeffrey): Display data in an html page instead of printing.
503 PrettyPrint(categorized_data, START_DATE, END_DATE) 537 PrettyPrint(categorized_data, START_DATE, END_DATE)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698