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

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: Addressing comments 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 27 matching lines...) Expand all
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
56 57
58 def _GetTrybotName(buildbucket_response):
59 # First try parameters_json.
60 parameters = json.loads(buildbucket_response.get('parameters_json', '{}'))
61 trybot = parameters.get('builder_name')
62
63 if not trybot:
64 # Fallback to response_details_json.
65 response_details = json.loads(
66 buildbucket_response.get('response_details_json', '{}'))
67 properties = response_details.get('properties', {})
68 trybot = properties.get('buildername')
69
70 if not trybot:
71 trybot = 'unknown'
72
73 return trybot
74
75
57 def _GetAverageOfNumbersInList(numbers): 76 def _GetAverageOfNumbersInList(numbers):
58 """Returns a float average of numbers or NOT_AVAILABLE if numbers is empty.""" 77 """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 78 return (float(sum(numbers)) / len(numbers)) if numbers else NOT_AVAILABLE
60 79
61 80
62 def _FormatDigits(number): 81 def _FormatDigits(number):
63 """Formats number into a 2-digit float, or NOT_AVAILABLE.""" 82 """Formats number into a 2-digit float, or NOT_AVAILABLE."""
64 if isinstance(number, float): 83 if isinstance(number, float):
65 return float('%.2f' % number) 84 return float('%.2f' % number)
66 return NOT_AVAILABLE 85 return NOT_AVAILABLE
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 417
399 if not master_name or not builder_name: 418 if not master_name or not builder_name:
400 continue 419 continue
401 420
402 platform = _GetOSPlatformName(master_name, builder_name) 421 platform = _GetOSPlatformName(master_name, builder_name)
403 categorized_data_dict[platform].append(try_job_data) 422 categorized_data_dict[platform].append(try_job_data)
404 423
405 return categorized_data_dict 424 return categorized_data_dict
406 425
407 426
427 def _SplitListByTrybot(try_job_data_list):
428 categorized_data_dict = defaultdict(list)
429
430 for try_job_data in try_job_data_list:
431 if not try_job_data.last_buildbucket_response:
432 continue
433
434 trybot = _GetTrybotName(try_job_data.last_buildbucket_response)
435 categorized_data_dict[trybot].append(try_job_data)
436
437 return categorized_data_dict
438
439
408 def SplitListByOption(try_job_data_list, option): 440 def SplitListByOption(try_job_data_list, option):
409 """Takes a WfTryJobData list and separates it into a dict based on arg. 441 """Takes a WfTryJobData list and separates it into a dict based on arg.
410 442
411 Args: 443 Args:
412 try_job_data_list: A list of WfTryJobData entities. 444 try_job_data_list: A list of WfTryJobData entities.
413 option: An option with which to split the data by. 445 option: An option with which to split the data by.
414 446
415 Returns: 447 Returns:
416 A dict where the keys are how the data is separated based on arg and the 448 A dict where the keys are how the data is separated based on arg and the
417 values are the corresponding lists of data. 449 values are the corresponding lists of data.
418 """ 450 """
419 451
420 if option == 't': # Try job type. 452 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) 453 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. 454 elif option == 'c': # Whether or not compile targets are included.
429 return _SplitListByCompileTargets(try_job_data_list) 455 return _SplitListByCompileTargets(try_job_data_list)
430 elif option == 'e': # Whether or not try jobs with errors should be counted. 456 elif option == 'e': # Whether or not try jobs with errors should be counted.
431 return _SplitListByError(try_job_data_list) 457 return _SplitListByError(try_job_data_list)
458 elif option == 'm': # Main waterfall master.
459 return _SplitListByMaster(try_job_data_list)
432 elif option == 'p': # Split by OS platform. 460 elif option == 'p': # Split by OS platform.
433 return _SplitListByPlatform(try_job_data_list) 461 return _SplitListByPlatform(try_job_data_list)
462 elif option == 'r': # Whether or not heuristic results are included.
463 return _SplitListByHeuristicResults(try_job_data_list)
464 elif option == 't': # Try job type.
465 return _SplitListByTryJobType(try_job_data_list)
466 elif 'trybot' in option: # Split by trybot.
467 return _SplitListByTrybot(try_job_data_list)
434 468
435 # Unsupported flag, bail out without modification. 469 # Unsupported flag, bail out without modification.
436 return try_job_data_list 470 return try_job_data_list
437 471
438 472
439 def SplitStructByOption(try_job_data_struct, option): 473 def SplitStructByOption(try_job_data_struct, option):
440 if isinstance(try_job_data_struct, list): 474 if isinstance(try_job_data_struct, list):
441 try_job_data_struct = SplitListByOption(try_job_data_struct, option) 475 try_job_data_struct = SplitListByOption(try_job_data_struct, option)
442 elif isinstance(try_job_data_struct, dict): 476 elif isinstance(try_job_data_struct, dict):
443 for key, struct in try_job_data_struct.iteritems(): 477 for key, struct in try_job_data_struct.iteritems():
(...skipping 18 matching lines...) Expand all
462 'errors detected')) 496 'errors detected'))
463 parser.add_argument('-m', action='store_true', 497 parser.add_argument('-m', action='store_true',
464 help='group try job data by master') 498 help='group try job data by master')
465 parser.add_argument('-p', action='store_true', 499 parser.add_argument('-p', action='store_true',
466 help='group try job data by platform') 500 help='group try job data by platform')
467 parser.add_argument('-r', action='store_true', 501 parser.add_argument('-r', action='store_true',
468 help=('group try job data by those with and without ' 502 help=('group try job data by those with and without '
469 'heuristic results')) 503 'heuristic results'))
470 parser.add_argument('-t', action='store_true', 504 parser.add_argument('-t', action='store_true',
471 help='group try job data by type (compile, test)') 505 help='group try job data by type (compile, test)')
506 parser.add_argument('--trybot', action='store_true',
507 help='group try job data by trybot')
472 508
473 args_dict = vars(parser.parse_args()) 509 args_dict = vars(parser.parse_args())
474 510
475 # Preserve order from original command. 511 # Preserve order from original command.
476 ordered_args = [] 512 ordered_args = []
477 513
478 for original_arg in command_line_args: 514 for original_arg in command_line_args:
479 parsed_arg = original_arg[1:] 515 parsed_arg = original_arg.lstrip('-')
480 if args_dict[parsed_arg]: 516 if args_dict[parsed_arg]:
481 ordered_args.append(parsed_arg) 517 ordered_args.append(parsed_arg)
482 518
483 return ordered_args 519 return ordered_args
484 520
485 521
486 if __name__ == '__main__': 522 if __name__ == '__main__':
487 # Set up the Remote API to use services on the live App Engine. 523 # Set up the Remote API to use services on the live App Engine.
488 remote_api.EnableRemoteApi(app_id='findit-for-me') 524 remote_api.EnableRemoteApi(app_id='findit-for-me')
489 525
490 START_DATE = datetime.datetime(2016, 5, 1) 526 START_DATE = datetime.datetime(2016, 5, 1)
491 END_DATE = datetime.datetime(2016, 6, 23) 527 END_DATE = datetime.datetime(2016, 6, 23)
492 528
493 try_job_data_query = WfTryJobData.query( 529 try_job_data_query = WfTryJobData.query(
494 WfTryJobData.request_time >= START_DATE, 530 WfTryJobData.request_time >= START_DATE,
495 WfTryJobData.request_time < END_DATE) 531 WfTryJobData.request_time < END_DATE)
496 categorized_data = try_job_data_query.fetch() 532 categorized_data = try_job_data_query.fetch()
497 533
498 args = GetArgsInOrder() 534 args = GetArgsInOrder()
499 for arg in args: 535 for arg in args:
500 categorized_data = SplitStructByOption(categorized_data, arg) 536 categorized_data = SplitStructByOption(categorized_data, arg)
501 537
502 # TODO(lijeffrey): Display data in an html page instead of printing. 538 # TODO(lijeffrey): Display data in an html page instead of printing.
503 PrettyPrint(categorized_data, START_DATE, END_DATE) 539 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