#!/usr/bin/env python2 # # Copyright Google Inc. 2014 """Module to generate the 7-day crosperf reports.""" from __future__ import print_function import argparse import datetime import os import sys from cros_utils import constants from cros_utils import command_executer WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] DATA_ROOT_DIR = os.path.join(constants.CROSTC_WORKSPACE, 'weekly_test_data') EXPERIMENT_FILE = os.path.join(DATA_ROOT_DIR, 'weekly_report') MAIL_PROGRAM = '~/var/bin/mail-sheriff' def Generate_Vanilla_Report_File(vanilla_image_paths, board, remote, chromeos_root, cmd_executer): experiment_header = """ name: weekly_vanilla_report cache_only: True same_specs: False board: %s remote: %s """ % (board, remote) experiment_tests = """ benchmark: all_toolchain_perf { suite: telemetry_Crosperf iterations: 3 } """ filename = '%s_%s_vanilla.exp' % (EXPERIMENT_FILE, board) if os.path.exists(filename): cmd = 'rm %s' % filename cmd_executer.RunCommand(cmd) with open(filename, 'w') as f: f.write(experiment_header) f.write(experiment_tests) # Add each vanilla image for test_path in vanilla_image_paths: pieces = test_path.split('/') test_name = pieces[-1] test_image = """ %s { chromeos_root: %s chromeos_image: %s } """ % (test_name, chromeos_root, os.path.join(test_path, 'chromiumos_test_image.bin')) f.write(test_image) return filename def Generate_Test_File(test_image_paths, vanilla_image_path, board, remote, chromeos_root, cmd_executer): experiment_header = """ name: weekly_report cache_only: True same_specs: False board: %s remote: %s """ % (board, remote) experiment_tests = """ benchmark: all_toolchain_perf { suite: telemetry_Crosperf iterations: 3 } """ filename = '%s_%s.exp' % (EXPERIMENT_FILE, board) if os.path.exists(filename): cmd = 'rm %s' % filename cmd_executer.RunCommand(cmd) with open(filename, 'w') as f: f.write(experiment_header) f.write(experiment_tests) # Add vanilla image (first) vanilla_image = """ %s { chromeos_root: %s chromeos_image: %s } """ % (vanilla_image_path.split('/')[-1], chromeos_root, os.path.join(vanilla_image_path, 'chromiumos_test_image.bin')) f.write(vanilla_image) # Add each test image for test_path in test_image_paths: pieces = test_path.split('/') test_name = pieces[-1] test_image = """ %s { chromeos_root: %s chromeos_image: %s } """ % (test_name, chromeos_root, os.path.join(test_path, 'chromiumos_test_image.bin')) f.write(test_image) return filename def Main(argv): parser = argparse.ArgumentParser() parser.add_argument('-b', '--board', dest='board', help='Target board.') parser.add_argument('-r', '--remote', dest='remote', help='Target device.') parser.add_argument( '-v', '--vanilla_only', dest='vanilla_only', action='store_true', default=False, help='Generate a report comparing only the vanilla ' 'images.') options = parser.parse_args(argv[1:]) if not options.board: print('Must specify a board.') return 1 if not options.remote: print('Must specify at least one remote.') return 1 cmd_executer = command_executer.GetCommandExecuter(log_level='average') # Find starting index, for cycling through days of week, generating # reports starting 6 days ago from today. Generate list of indices for # order in which to look at weekdays for report: todays_index = datetime.datetime.today().isoweekday() indices = [] start = todays_index + 1 end = start + 7 for i in range(start, end): indices.append(i % 7) # E.g. if today is Sunday, then start report with last Monday, so # indices = [1, 2, 3, 4, 5, 6, 0]. # Find all the test image tar files, untar them and add them to # the list. Also find and untar vanilla image tar files, and keep # track of the first vanilla image. report_image_paths = [] vanilla_image_paths = [] first_vanilla_image = None for i in indices: day = WEEKDAYS[i] data_path = os.path.join(DATA_ROOT_DIR, options.board, day) if os.path.exists(data_path): # First, untar the test image. tar_file_name = '%s_test_image.tar' % day tar_file_path = os.path.join(data_path, tar_file_name) image_dir = '%s_test_image' % day image_path = os.path.join(data_path, image_dir) if os.path.exists(tar_file_path): if not os.path.exists(image_path): os.makedirs(image_path) cmd = ('cd %s; tar -xvf %s -C %s --strip-components 1' % (data_path, tar_file_path, image_path)) ret = cmd_executer.RunCommand(cmd) if not ret: report_image_paths.append(image_path) # Next, untar the vanilla image. vanilla_file = '%s_vanilla_image.tar' % day v_file_path = os.path.join(data_path, vanilla_file) image_dir = '%s_vanilla_image' % day image_path = os.path.join(data_path, image_dir) if os.path.exists(v_file_path): if not os.path.exists(image_path): os.makedirs(image_path) cmd = ('cd %s; tar -xvf %s -C %s --strip-components 1' % (data_path, v_file_path, image_path)) ret = cmd_executer.RunCommand(cmd) if not ret: vanilla_image_paths.append(image_path) if not first_vanilla_image: first_vanilla_image = image_path # Find a chroot we can use. Look for a directory containing both # an experiment file and a chromeos directory (the experiment file will # only be created if both images built successfully, i.e. the chroot is # good). chromeos_root = None timestamp = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d_%H:%M:%S') results_dir = os.path.join( os.path.expanduser('~/nightly_test_reports'), '%s.%s' % (timestamp, options.board), 'weekly_tests') for day in WEEKDAYS: startdir = os.path.join(constants.CROSTC_WORKSPACE, day) num_dirs = os.listdir(startdir) for d in num_dirs: exp_file = os.path.join(startdir, d, 'toolchain_experiment.txt') chroot = os.path.join(startdir, d, 'chromeos') if os.path.exists(chroot) and os.path.exists(exp_file): chromeos_root = chroot if chromeos_root: break if chromeos_root: break if not chromeos_root: print('Unable to locate a usable chroot. Exiting without report.') return 1 # Create the Crosperf experiment file for generating the weekly report. if not options.vanilla_only: filename = Generate_Test_File(report_image_paths, first_vanilla_image, options.board, options.remote, chromeos_root, cmd_executer) else: filename = Generate_Vanilla_Report_File(vanilla_image_paths, options.board, options.remote, chromeos_root, cmd_executer) # Run Crosperf on the file to generate the weekly report. cmd = ('%s/toolchain-utils/crosperf/crosperf ' '%s --no_email=True --results_dir=%s' % (constants.CROSTC_WORKSPACE, filename, results_dir)) retv = cmd_executer.RunCommand(cmd) if retv == 0: # Send the email, if the crosperf command worked. filename = os.path.join(results_dir, 'msg_body.html') if (os.path.exists(filename) and os.path.exists(os.path.expanduser(MAIL_PROGRAM))): vanilla_string = ' ' if options.vanilla_only: vanilla_string = ' Vanilla ' command = ('cat %s | %s -s "Weekly%sReport results, %s" -team -html' % (filename, MAIL_PROGRAM, vanilla_string, options.board)) retv = cmd_executer.RunCommand(command) return retv if __name__ == '__main__': retval = Main(sys.argv) sys.exit(retval)