crosperf.py revision eff2fc1c86365c53ae228df4653524ceb6168d92
1#!/usr/bin/python2 2 3# Copyright 2011 Google Inc. All Rights Reserved. 4"""The driver script for running performance benchmarks on ChromeOS.""" 5 6from __future__ import print_function 7 8import atexit 9import argparse 10import os 11import signal 12import sys 13from experiment_runner import ExperimentRunner 14from experiment_runner import MockExperimentRunner 15from experiment_factory import ExperimentFactory 16from experiment_file import ExperimentFile 17from settings_factory import GlobalSettings 18 19# This import causes pylint to warn about "No name 'logger' in module 'utils'". 20# I do not understand why. The import works fine in python. 21# pylint: disable=no-name-in-module 22from utils import logger 23 24import test_flag 25 26 27def SetupParserOptions(parser): 28 """Add all options to the parser.""" 29 parser.add_argument('--dry_run', 30 dest='dry_run', 31 help=('Parse the experiment file and ' 32 'show what will be done'), 33 action='store_true', 34 default=False) 35 # Allow each of the global fields to be overridden by passing in 36 # options. Add each global field as an option. 37 option_settings = GlobalSettings('') 38 for field_name in option_settings.fields: 39 field = option_settings.fields[field_name] 40 parser.add_argument('--%s' % field.name, 41 dest=field.name, 42 help=field.description, 43 action='store') 44 45 46def ConvertOptionsToSettings(options): 47 """Convert options passed in into global settings.""" 48 option_settings = GlobalSettings('option_settings') 49 for option_name in options.__dict__: 50 if (options.__dict__[option_name] is not None and 51 option_name in option_settings.fields): 52 option_settings.SetField(option_name, options.__dict__[option_name]) 53 return option_settings 54 55 56def Cleanup(experiment): 57 """Handler function which is registered to the atexit handler.""" 58 experiment.Cleanup() 59 60 61def CallExitHandler(signum, _): 62 """Signal handler that transforms a signal into a call to exit. 63 64 This is useful because functionality registered by "atexit" will 65 be called. It also means you can "catch" the signal by catching 66 the SystemExit exception. 67 """ 68 sys.exit(128 + signum) 69 70 71def Main(argv): 72 parser = argparse.ArgumentParser() 73 74 parser.add_argument('--noschedv2', 75 dest='noschedv2', 76 default=False, 77 action='store_true', 78 help=('Do not use new scheduler. ' 79 'Use original scheduler instead.')) 80 parser.add_argument('-l', 81 '--log_dir', 82 dest='log_dir', 83 default='', 84 help='The log_dir, default is under <crosperf_logs>/logs') 85 86 SetupParserOptions(parser) 87 options, args = parser.parse_known_args(argv) 88 89 # Convert the relevant options that are passed in into a settings 90 # object which will override settings in the experiment file. 91 option_settings = ConvertOptionsToSettings(options) 92 log_dir = os.path.abspath(os.path.expanduser(options.log_dir)) 93 logger.GetLogger(log_dir) 94 95 if len(args) == 2: 96 experiment_filename = args[1] 97 else: 98 parser.error('Invalid number arguments.') 99 100 working_directory = os.getcwd() 101 if options.dry_run: 102 test_flag.SetTestMode(True) 103 104 experiment_file = ExperimentFile( 105 open(experiment_filename, 'rb'), option_settings) 106 if not experiment_file.GetGlobalSettings().GetField('name'): 107 experiment_name = os.path.basename(experiment_filename) 108 experiment_file.GetGlobalSettings().SetField('name', experiment_name) 109 experiment = ExperimentFactory().GetExperiment(experiment_file, 110 working_directory, log_dir) 111 112 json_report = experiment_file.GetGlobalSettings().GetField('json_report') 113 114 signal.signal(signal.SIGTERM, CallExitHandler) 115 atexit.register(Cleanup, experiment) 116 117 if options.dry_run: 118 runner = MockExperimentRunner(experiment, json_report) 119 else: 120 runner = ExperimentRunner(experiment, 121 json_report, 122 using_schedv2=(not options.noschedv2)) 123 124 runner.Run() 125 126 127if __name__ == '__main__': 128 Main(sys.argv) 129