fix style failures in webkitpy: expected 2 blank lines found 1
[WebKit-https.git] / Tools / Scripts / webkitpy / benchmark_runner / run_benchmark.py
1 #!/usr/bin/env python
2
3 import argparse
4 import json
5 import logging
6 import platform
7 import os
8 import sys
9
10 from browser_driver.browser_driver_factory import BrowserDriverFactory
11 from benchmark_runner import BenchmarkRunner
12 from webdriver_benchmark_runner import WebDriverBenchmarkRunner
13 from webserver_benchmark_runner import WebServerBenchmarkRunner
14
15
16 _log = logging.getLogger(__name__)
17 benchmark_runner_subclasses = {
18     WebDriverBenchmarkRunner.name: WebDriverBenchmarkRunner,
19     WebServerBenchmarkRunner.name: WebServerBenchmarkRunner,
20 }
21
22
23 def default_platform():
24     if sys.platform.startswith('linux'):
25         return 'linux'
26     return 'osx'
27
28
29 def default_browser():
30     if sys.platform.startswith('linux'):
31         return 'minibrowser-gtk'
32     return 'safari'
33
34
35 def parse_args():
36     parser = argparse.ArgumentParser(description='Run browser based performance benchmarks. To run a single benchmark in the recommended way, use run-benchmark --plan. To see the vailable benchmarks, use run-benchmark --list-plans.')
37     mutual_group = parser.add_mutually_exclusive_group(required=True)
38     mutual_group.add_argument('--plan', help='Run a specific benchmark plan (e.g. speedometer, jetstream).')
39     mutual_group.add_argument('--list-plans', action='store_true', help='List all available benchmark plans.')
40     mutual_group.add_argument('--allplans', action='store_true', help='Run all available benchmark plans in order.')
41     mutual_group.add_argument('--read-results-json', dest='json_file', help='Instead of running a benchmark, format the output saved in JSON_FILE.')
42     parser.add_argument('--output-file', default=None, help='Save detailed results to OUTPUT in JSON format. By default, results will not be saved.')
43     parser.add_argument('--build-directory', dest='build_dir', help='Path to the browser executable (e.g. WebKitBuild/Release/).')
44     parser.add_argument('--count', type=int, help='Number of times to run the benchmark (e.g. 5).')
45     parser.add_argument('--driver', default=WebServerBenchmarkRunner.name, choices=benchmark_runner_subclasses.keys(), help='Use the specified benchmark driver. Defaults to %s.' % WebServerBenchmarkRunner.name)
46     parser.add_argument('--browser', default=default_browser(), choices=BrowserDriverFactory.available_browsers(), help='Browser to run the nechmark in. Defaults to %s.' % default_browser())
47     parser.add_argument('--platform', default=default_platform(), choices=BrowserDriverFactory.available_platforms(), help='Platform that this script is running on. Defaults to %s.' % default_platform())
48     parser.add_argument('--local-copy', help='Path to a local copy of the benchmark (e.g. PerformanceTests/SunSpider/).')
49     parser.add_argument('--device-id', default=None, help='Undocumented option for mobile device testing.')
50     parser.add_argument('--debug', action='store_true', help='Enable debug logging.')
51     parser.add_argument('--no-adjust-unit', dest='scale_unit', action='store_false', help="Don't convert to scientific notation.")
52
53     args = parser.parse_args()
54
55     if args.debug:
56         _log.setLevel(logging.DEBUG)
57     _log.debug('Initializing program with following parameters')
58     _log.debug('\toutput file name\t: %s' % args.output_file)
59     _log.debug('\tbuild directory\t: %s' % args.build_dir)
60     _log.debug('\tplan name\t: %s', args.plan)
61
62     return args
63
64
65 def run_benchmark_plan(args, plan):
66     benchmark_runner_class = benchmark_runner_subclasses[args.driver]
67     runner = benchmark_runner_class(plan, args.local_copy, args.count, args.build_dir, args.output_file, args.platform, args.browser, args.scale_unit, args.device_id)
68     runner.execute()
69
70
71 def list_benchmark_plans():
72     print "Available benchmark plans: "
73     for plan in BenchmarkRunner.available_plans():
74         print "\t%s" % plan
75
76
77 def start(args):
78     if args.json_file:
79         results_json = json.load(open(args.json_file, 'r'))
80         if 'debugOutput' in results_json:
81             del results_json['debugOutput']
82         BenchmarkRunner.show_results(results_json, args.scale_unit)
83         return
84     if args.allplans:
85         failed = []
86         skipped = []
87         planlist = BenchmarkRunner.available_plans()
88         skippedfile = os.path.join(plandir, 'Skipped')
89         if not planlist:
90             raise Exception('Cant find any .plan file in directory %s' % BenchmarkRunner.plan_directory())
91         if os.path.isfile(skippedfile):
92             skipped = [line.strip() for line in open(skippedfile) if not line.startswith('#') and len(line) > 1]
93         for plan in sorted(planlist):
94             if plan in skipped:
95                 _log.info('Skipping benchmark plan: %s because is listed on the Skipped file' % plan)
96                 continue
97             _log.info('Starting benchmark plan: %s' % plan)
98             try:
99                 run_benchmark_plan(args, plan)
100                 _log.info('Finished benchmark plan: %s' % plan)
101             except KeyboardInterrupt:
102                 raise
103             except:
104                 failed.append(plan)
105                 _log.exception('Error running benchmark plan: %s' % plan)
106         if failed:
107             _log.error('The following benchmark plans have failed: %s' % failed)
108         return len(failed)
109     if args.list_plans:
110         list_benchmark_plans()
111         return
112
113     run_benchmark_plan(args, args.plan)
114
115
116 def format_logger(logger):
117     logger.setLevel(logging.INFO)
118     ch = logging.StreamHandler()
119     formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
120     ch.setFormatter(formatter)
121     logger.addHandler(ch)
122
123
124 def main():
125     return start(parse_args())