blob: b78c8b9eb73d31b29c6591b9b96ff86dad672234 [file] [log] [blame]
George Burgess IVed696762016-09-12 18:24:54 -07001#!/usr/bin/env python2
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08002
3# Copyright 2011 Google Inc. All Rights Reserved.
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08004"""The driver script for running performance benchmarks on ChromeOS."""
5
Rahul Chaudhrycbc5a262015-12-30 17:05:14 -08006from __future__ import print_function
7
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -08008import atexit
Rahul Chaudhry4f07bbf2016-01-29 15:10:02 -08009import argparse
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080010import os
Luis Lozano45b53c52015-09-30 11:36:27 -070011import signal
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080012import sys
13from experiment_runner import ExperimentRunner
14from experiment_runner import MockExperimentRunner
15from experiment_factory import ExperimentFactory
16from experiment_file import ExperimentFile
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080017from settings_factory import GlobalSettings
Rahul Chaudhryeff2fc12016-02-24 10:12:43 -080018
Caroline Ticea8af9a72016-07-20 12:52:59 -070019# This import causes pylint to warn about "No name 'logger' in module
20# 'cros_utils'". I do not understand why. The import works fine in python.
Rahul Chaudhryeff2fc12016-02-24 10:12:43 -080021# pylint: disable=no-name-in-module
Caroline Ticea8af9a72016-07-20 12:52:59 -070022from cros_utils import logger
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080023
Ahmad Sharif4467f002012-12-20 12:09:49 -080024import test_flag
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080025
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080026
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080027def SetupParserOptions(parser):
28 """Add all options to the parser."""
Manoj Guptaaee96b72016-10-24 13:43:28 -070029 parser.add_argument(
30 '--dry_run',
31 dest='dry_run',
32 help=('Parse the experiment file and '
33 'show what will be done'),
34 action='store_true',
35 default=False)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080036 # Allow each of the global fields to be overridden by passing in
37 # options. Add each global field as an option.
Luis Lozanof2a3ef42015-12-15 13:49:30 -080038 option_settings = GlobalSettings('')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080039 for field_name in option_settings.fields:
40 field = option_settings.fields[field_name]
Manoj Guptaaee96b72016-10-24 13:43:28 -070041 parser.add_argument(
42 '--%s' % field.name,
43 dest=field.name,
44 help=field.description,
45 action='store')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080046
47
48def ConvertOptionsToSettings(options):
49 """Convert options passed in into global settings."""
Luis Lozanof2a3ef42015-12-15 13:49:30 -080050 option_settings = GlobalSettings('option_settings')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080051 for option_name in options.__dict__:
52 if (options.__dict__[option_name] is not None and
53 option_name in option_settings.fields):
54 option_settings.SetField(option_name, options.__dict__[option_name])
55 return option_settings
56
57
58def Cleanup(experiment):
59 """Handler function which is registered to the atexit handler."""
60 experiment.Cleanup()
61
62
Luis Lozano45b53c52015-09-30 11:36:27 -070063def CallExitHandler(signum, _):
64 """Signal handler that transforms a signal into a call to exit.
65
66 This is useful because functionality registered by "atexit" will
67 be called. It also means you can "catch" the signal by catching
68 the SystemExit exception.
69 """
70 sys.exit(128 + signum)
71
72
Manoj Guptaaee96b72016-10-24 13:43:28 -070073def RunCrosperf(argv):
Rahul Chaudhry4f07bbf2016-01-29 15:10:02 -080074 parser = argparse.ArgumentParser()
Luis Lozanof81680c2013-03-15 14:44:13 -070075
Manoj Guptaaee96b72016-10-24 13:43:28 -070076 parser.add_argument(
77 '--noschedv2',
78 dest='noschedv2',
79 default=False,
80 action='store_true',
81 help=('Do not use new scheduler. '
82 'Use original scheduler instead.'))
83 parser.add_argument(
84 '-l',
85 '--log_dir',
86 dest='log_dir',
87 default='',
88 help='The log_dir, default is under <crosperf_logs>/logs')
Luis Lozanof81680c2013-03-15 14:44:13 -070089
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080090 SetupParserOptions(parser)
Rahul Chaudhry4f07bbf2016-01-29 15:10:02 -080091 options, args = parser.parse_known_args(argv)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080092
93 # Convert the relevant options that are passed in into a settings
94 # object which will override settings in the experiment file.
95 option_settings = ConvertOptionsToSettings(options)
Luis Lozanof81680c2013-03-15 14:44:13 -070096 log_dir = os.path.abspath(os.path.expanduser(options.log_dir))
97 logger.GetLogger(log_dir)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -080098
99 if len(args) == 2:
100 experiment_filename = args[1]
101 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800102 parser.error('Invalid number arguments.')
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800103
104 working_directory = os.getcwd()
Ahmad Sharif4467f002012-12-20 12:09:49 -0800105 if options.dry_run:
106 test_flag.SetTestMode(True)
107
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800108 experiment_file = ExperimentFile(
109 open(experiment_filename, 'rb'), option_settings)
110 if not experiment_file.GetGlobalSettings().GetField('name'):
Ahmad Sharif822c55d2012-02-08 20:55:47 -0800111 experiment_name = os.path.basename(experiment_filename)
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800112 experiment_file.GetGlobalSettings().SetField('name', experiment_name)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800113 experiment = ExperimentFactory().GetExperiment(experiment_file,
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800114 working_directory, log_dir)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800115
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800116 json_report = experiment_file.GetGlobalSettings().GetField('json_report')
Caroline Ticeef4ca8a2015-08-25 12:53:38 -0700117
Luis Lozano45b53c52015-09-30 11:36:27 -0700118 signal.signal(signal.SIGTERM, CallExitHandler)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800119 atexit.register(Cleanup, experiment)
120
121 if options.dry_run:
Caroline Tice6e8726d2015-12-09 12:42:13 -0800122 runner = MockExperimentRunner(experiment, json_report)
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800123 else:
Manoj Guptaaee96b72016-10-24 13:43:28 -0700124 runner = ExperimentRunner(
125 experiment, json_report, using_schedv2=(not options.noschedv2))
Han Shenba649282015-08-05 17:19:55 -0700126
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800127 runner.Run()
128
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800129
Manoj Guptaaee96b72016-10-24 13:43:28 -0700130def Main(argv):
131 try:
132 RunCrosperf(argv)
133 except Exception as ex:
134 # Flush buffers before exiting to avoid out of order printing
135 sys.stdout.flush()
136 sys.stderr.flush()
137 print('Crosperf error: %s' % repr(ex))
138 sys.stdout.flush()
139 sys.stderr.flush()
140 sys.exit(1)
141
142
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800143if __name__ == '__main__':
Ahmad Sharif0dcbc4b2012-02-02 16:37:18 -0800144 Main(sys.argv)