diff options
Diffstat (limited to 'deprecated/new-generate-waterfall-reports.py')
-rwxr-xr-x | deprecated/new-generate-waterfall-reports.py | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/deprecated/new-generate-waterfall-reports.py b/deprecated/new-generate-waterfall-reports.py deleted file mode 100755 index ef48f8be..00000000 --- a/deprecated/new-generate-waterfall-reports.py +++ /dev/null @@ -1,410 +0,0 @@ -#!/usr/bin/env python2 -"""Generate summary report for ChromeOS toolchain waterfalls.""" - -from __future__ import print_function - -import argparse -import datetime -import getpass -import json -import os -import re -import shutil -import sys -import time - -from cros_utils import command_executer - -# All the test suites whose data we might want for the reports. -TESTS = (('bvt-inline', 'HWTest [bvt-inline]'), ('bvt-cq', 'HWTest [bvt-cq]'), - ('security', 'HWTest [security]')) - -# The main waterfall builders, IN THE ORDER IN WHICH WE WANT THEM -# LISTED IN THE REPORT. -WATERFALL_BUILDERS = [ - 'amd64-llvm-next-toolchain', - 'arm-llvm-next-toolchain', - 'arm64-llvm-next-toolchain', -] - -DATA_DIR = '/google/data/rw/users/mo/mobiletc-prebuild/waterfall-report-data/' -ARCHIVE_DIR = '/google/data/rw/users/mo/mobiletc-prebuild/waterfall-reports/' -DOWNLOAD_DIR = '/tmp/waterfall-logs' -MAX_SAVE_RECORDS = 7 -BUILD_DATA_FILE = '%s/build-data.txt' % DATA_DIR -LLVM_ROTATING_BUILDER = 'llvm_next_toolchain' -ROTATING_BUILDERS = [LLVM_ROTATING_BUILDER] - -# For int-to-string date conversion. Note, the index of the month in this -# list needs to correspond to the month's integer value. i.e. 'Sep' must -# be as MONTHS[9]. -MONTHS = [ - '', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', - 'Nov', 'Dec' -] - -DAYS_PER_MONTH = { - 1: 31, - 2: 28, - 3: 31, - 4: 30, - 5: 31, - 6: 30, - 7: 31, - 8: 31, - 9: 30, - 10: 31, - 11: 31, - 12: 31 -} - - -def format_date(int_date, use_int_month=False): - """Convert an integer date to a string date. YYYYMMDD -> YYYY-MMM-DD""" - - if int_date == 0: - return 'today' - - tmp_date = int_date - day = tmp_date % 100 - tmp_date = tmp_date / 100 - month = tmp_date % 100 - year = tmp_date / 100 - - if use_int_month: - date_str = '%d-%02d-%02d' % (year, month, day) - else: - month_str = MONTHS[month] - date_str = '%d-%s-%d' % (year, month_str, day) - return date_str - - -def EmailReport(report_file, report_type, date, email_to): - """Emails the report to the approprite address.""" - subject = '%s Waterfall Summary report, %s' % (report_type, date) - sendgmr_path = '/google/data/ro/projects/gws-sre/sendgmr' - command = ('%s --to=%s --subject="%s" --body_file=%s' % - (sendgmr_path, email_to, subject, report_file)) - command_executer.GetCommandExecuter().RunCommand(command) - - -def GetColor(status): - """Given a job status string, returns appropriate color string.""" - if status.strip() == 'pass': - color = 'green ' - elif status.strip() == 'fail': - color = ' red ' - elif status.strip() == 'warning': - color = 'orange' - else: - color = ' ' - return color - - -def GenerateWaterfallReport(report_dict, waterfall_type, date): - """Write out the actual formatted report.""" - - filename = 'waterfall_report.%s_waterfall.%s.txt' % (waterfall_type, date) - - date_string = '' - report_list = report_dict.keys() - - with open(filename, 'w') as out_file: - # Write Report Header - out_file.write('\nStatus of %s Waterfall Builds from %s\n\n' % - (waterfall_type, date_string)) - out_file.write(' \n') - out_file.write( - ' Build bvt- ' - ' bvt-cq ' - ' security \n') - out_file.write( - ' status inline ' - ' \n') - - # Write daily waterfall status section. - for builder in report_list: - build_dict = report_dict[builder] - buildbucket_id = build_dict['buildbucket_id'] - overall_status = build_dict['status'] - if 'bvt-inline' in build_dict.keys(): - inline_status = build_dict['bvt-inline'] - else: - inline_status = ' ' - if 'bvt-cq' in build_dict.keys(): - cq_status = build_dict['bvt-cq'] - else: - cq_status = ' ' - if 'security' in build_dict.keys(): - security_status = build_dict['security'] - else: - security_status = ' ' - inline_color = GetColor(inline_status) - cq_color = GetColor(cq_status) - security_color = GetColor(security_status) - - out_file.write( - '%26s %4s %6s %6s %6s\n' % - (builder, overall_status, inline_color, cq_color, security_color)) - if waterfall_type == 'main': - out_file.write(' build url: https://cros-goldeneye.corp.google.com/' - 'chromeos/healthmonitoring/buildDetails?buildbucketId=%s' - '\n' % buildbucket_id) - else: - out_file.write(' build url: https://ci.chromium.org/p/chromeos/' - 'builds/b%s \n' % buildbucket_id) - report_url = ('https://logs.chromium.org/v/?s=chromeos%2Fbuildbucket%2F' - 'cr-buildbucket.appspot.com%2F' + buildbucket_id + - '%2F%2B%2Fsteps%2FReport%2F0%2Fstdout') - out_file.write('\n report status url: %s\n' % report_url) - out_file.write('\n') - - print('Report generated in %s.' % filename) - return filename - - -def GetTryjobData(date, rotating_builds_dict): - """Read buildbucket id and board from stored file. - - buildbot_test_llvm.py, when it launches the rotating builders, - records the buildbucket_id and board for each launch in a file. - This reads that data out of the file so we can find the right - tryjob data. - """ - - date_str = format_date(date, use_int_month=True) - fname = '%s.builds' % date_str - filename = os.path.join(DATA_DIR, 'rotating-builders', fname) - - if not os.path.exists(filename): - print('Cannot find file: %s' % filename) - print('Unable to generate rotating builder report for date %d.' % date) - return - - with open(filename, 'r') as in_file: - lines = in_file.readlines() - - for line in lines: - l = line.strip() - parts = l.split(',') - if len(parts) != 2: - print('Warning: Illegal line in data file.') - print('File: %s' % filename) - print('Line: %s' % l) - continue - buildbucket_id = parts[0] - board = parts[1] - rotating_builds_dict[board] = buildbucket_id - - return - - -def GetRotatingBuildData(date, report_dict, chromeos_root, board, - buildbucket_id, ce): - """Gets rotating builder job results via 'cros buildresult'.""" - path = os.path.join(chromeos_root, 'chromite') - save_dir = os.getcwd() - date_str = format_date(date, use_int_month=True) - os.chdir(path) - - command = ( - 'cros buildresult --buildbucket-id %s --report json' % buildbucket_id) - _, out, _ = ce.RunCommandWOutput(command) - tmp_dict = json.loads(out) - results = tmp_dict[buildbucket_id] - - board_dict = dict() - board_dict['buildbucket_id'] = buildbucket_id - stages_results = results['stages'] - for test in TESTS: - key1 = test[0] - key2 = test[1] - if key2 in stages_results: - board_dict[key1] = stages_results[key2] - board_dict['status'] = results['status'] - report_dict[board] = board_dict - os.chdir(save_dir) - return - - -def GetMainWaterfallData(date, report_dict, chromeos_root, ce): - """Gets main waterfall job results via 'cros buildresult'.""" - path = os.path.join(chromeos_root, 'chromite') - save_dir = os.getcwd() - date_str = format_date(date, use_int_month=True) - os.chdir(path) - for builder in WATERFALL_BUILDERS: - command = ('cros buildresult --build-config %s --date %s --report json' % - (builder, date_str)) - _, out, _ = ce.RunCommandWOutput(command) - tmp_dict = json.loads(out) - builder_dict = dict() - for k in tmp_dict.keys(): - buildbucket_id = k - results = tmp_dict[k] - - builder_dict['buildbucket_id'] = buildbucket_id - builder_dict['status'] = results['status'] - stages_results = results['stages'] - for test in TESTS: - key1 = test[0] - key2 = test[1] - builder_dict[key1] = stages_results[key2] - report_dict[builder] = builder_dict - os.chdir(save_dir) - return - - -# Check for prodaccess. -def CheckProdAccess(): - """Verifies prodaccess is current.""" - status, output, _ = command_executer.GetCommandExecuter().RunCommandWOutput( - 'prodcertstatus') - if status != 0: - return False - # Verify that status is not expired - if 'expires' in output: - return True - return False - - -def ValidDate(date): - """Ensures 'date' is a valid date.""" - min_year = 2018 - - tmp_date = date - day = tmp_date % 100 - tmp_date = tmp_date / 100 - month = tmp_date % 100 - year = tmp_date / 100 - - if day < 1 or month < 1 or year < min_year: - return False - - cur_year = datetime.datetime.now().year - if year > cur_year: - return False - - if month > 12: - return False - - if month == 2 and cur_year % 4 == 0 and cur_year % 100 != 0: - max_day = 29 - else: - max_day = DAYS_PER_MONTH[month] - - if day > max_day: - return False - - return True - - -def ValidOptions(parser, options): - """Error-check the options passed to this script.""" - too_many_options = False - if options.main: - if options.rotating: - too_many_options = True - - if too_many_options: - parser.error('Can only specify one of --main, --rotating.') - - if not os.path.exists(options.chromeos_root): - parser.error( - 'Invalid chromeos root. Cannot find: %s' % options.chromeos_root) - - email_ok = True - if options.email and options.email.find('@') == -1: - email_ok = False - parser.error('"%s" is not a valid email address; it must contain "@..."' % - options.email) - - valid_date = ValidDate(options.date) - - return not too_many_options and valid_date and email_ok - - -def Main(argv): - """Main function for this script.""" - parser = argparse.ArgumentParser() - parser.add_argument( - '--main', - dest='main', - default=False, - action='store_true', - help='Generate report only for main waterfall ' - 'builders.') - parser.add_argument( - '--rotating', - dest='rotating', - default=False, - action='store_true', - help='Generate report only for rotating builders.') - parser.add_argument( - '--date', - dest='date', - required=True, - type=int, - help='The date YYYYMMDD of waterfall report.') - parser.add_argument( - '--email', - dest='email', - default='', - help='Email address to use for sending the report.') - parser.add_argument( - '--chromeos_root', - dest='chromeos_root', - required=True, - help='Chrome OS root in which to run chroot commands.') - - options = parser.parse_args(argv) - - if not ValidOptions(parser, options): - return 1 - - main_only = options.main - rotating_only = options.rotating - date = options.date - - prod_access = CheckProdAccess() - if not prod_access: - print('ERROR: Please run prodaccess first.') - return - - waterfall_report_dict = dict() - rotating_report_dict = dict() - - ce = command_executer.GetCommandExecuter() - if not rotating_only: - GetMainWaterfallData(date, waterfall_report_dict, options.chromeos_root, ce) - - if not main_only: - rotating_builds_dict = dict() - GetTryjobData(date, rotating_builds_dict) - if len(rotating_builds_dict.keys()) > 0: - for board in rotating_builds_dict.keys(): - buildbucket_id = rotating_builds_dict[board] - GetRotatingBuildData(date, rotating_report_dict, options.chromeos_root, - board, buildbucket_id, ce) - - if options.email: - email_to = options.email - else: - email_to = getpass.getuser() - - if waterfall_report_dict and not rotating_only: - main_report = GenerateWaterfallReport(waterfall_report_dict, 'main', date) - - EmailReport(main_report, 'Main', format_date(date), email_to) - shutil.copy(main_report, ARCHIVE_DIR) - if rotating_report_dict and not main_only: - rotating_report = GenerateWaterfallReport(rotating_report_dict, 'rotating', - date) - - EmailReport(rotating_report, 'Rotating', format_date(date), email_to) - shutil.copy(rotating_report, ARCHIVE_DIR) - - -if __name__ == '__main__': - Main(sys.argv[1:]) - sys.exit(0) |