| Index: mojo/devtools/common/devtoolslib/benchmark.py
|
| diff --git a/mojo/devtools/common/devtoolslib/benchmark.py b/mojo/devtools/common/devtoolslib/benchmark.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3383dd44439a49cdc802db3c6bb8301a55e76650
|
| --- /dev/null
|
| +++ b/mojo/devtools/common/devtoolslib/benchmark.py
|
| @@ -0,0 +1,103 @@
|
| +# Copyright 2015 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""Logic that drives runs of the benchmarking mojo app and parses its output."""
|
| +
|
| +import os.path
|
| +import re
|
| +
|
| +_BENCHMARK_APP = 'https://core.mojoapps.io/benchmark.mojo'
|
| +
|
| +# Additional time in seconds allocated per shell run to accommodate start-up.
|
| +# The shell should terminate before hitting this time out, it is an error if it
|
| +# doesn't.
|
| +_EXTRA_TIMEOUT = 20
|
| +
|
| +_MEASUREMENT_RESULT_FORMAT = r"""
|
| +^ # Beginning of the line.
|
| +measurement: # Hard-coded tag.
|
| +\s+(\S+) # Match measurement spec.
|
| +\s+(\S+) # Match measurement result.
|
| +$ # End of the line.
|
| +"""
|
| +
|
| +_MEASUREMENT_REGEX = re.compile(_MEASUREMENT_RESULT_FORMAT, re.VERBOSE)
|
| +
|
| +
|
| +def _parse_measurement_results(output):
|
| + """Parses the measurement results present in the benchmark output and returns
|
| + the dictionary of correctly recognized and parsed results.
|
| + """
|
| + measurement_results = {}
|
| + output_lines = [line.strip() for line in output.split('\n')]
|
| + for line in output_lines:
|
| + match = re.match(_MEASUREMENT_REGEX, line)
|
| + if match:
|
| + measurement_spec = match.group(1)
|
| + measurement_result = match.group(2)
|
| + try:
|
| + measurement_results[measurement_spec] = float(measurement_result)
|
| + except ValueError:
|
| + pass
|
| + return measurement_results
|
| +
|
| +
|
| +class Results(object):
|
| + """Holds results of a benchmark run."""
|
| +
|
| + def __init__(self, succeeded, error_str, output):
|
| + self.succeeded = succeeded
|
| + self.error_str = error_str
|
| + self.output = output
|
| + self.measurements = None
|
| +
|
| +
|
| +def run(shell, shell_args, app, duration_seconds, measurements, verbose,
|
| + android, output_file):
|
| + """Runs the given benchmark by running `benchmark.mojo` in mojo shell with
|
| + appropriate arguments and returns the produced output.
|
| +
|
| + Returns:
|
| + A tuple of (succeeded, error_msg, output).
|
| + """
|
| + timeout = duration_seconds + _EXTRA_TIMEOUT
|
| + benchmark_args = []
|
| + benchmark_args.append('--app=' + app)
|
| + benchmark_args.append('--duration=' + str(duration_seconds))
|
| +
|
| + device_output_file = None
|
| + if output_file:
|
| + if android:
|
| + device_output_file = os.path.join(shell.get_tmp_dir_path(), output_file)
|
| + benchmark_args.append('--trace-output=' + device_output_file)
|
| + else:
|
| + benchmark_args.append('--trace-output=' + output_file)
|
| +
|
| + for measurement in measurements:
|
| + benchmark_args.append(measurement['spec'])
|
| +
|
| + shell_args = list(shell_args)
|
| + shell_args.append(_BENCHMARK_APP)
|
| + shell_args.append('--force-offline-by-default')
|
| + shell_args.append('--args-for=%s %s' % (_BENCHMARK_APP,
|
| + ' '.join(benchmark_args)))
|
| +
|
| + if verbose:
|
| + print 'shell arguments: ' + str(shell_args)
|
| + return_code, output, did_time_out = shell.run_and_get_output(
|
| + shell_args, timeout=timeout)
|
| +
|
| + if did_time_out:
|
| + return Results(False, 'timed out', output)
|
| + if return_code:
|
| + return Results(False, 'return code: ' + str(return_code), output)
|
| +
|
| + # Pull the trace file even if some measurements are missing, as it can be
|
| + # useful in debugging.
|
| + if device_output_file:
|
| + shell.pull_file(device_output_file, output_file, remove_original=True)
|
| +
|
| + results = Results(True, None, output)
|
| + results.measurements = _parse_measurement_results(output)
|
| + return results
|
|
|