OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Logic that drives runs of the benchmarking mojo app and parses its output.""" |
| 6 |
| 7 import os.path |
| 8 import re |
| 9 |
| 10 _BENCHMARK_APP = 'https://core.mojoapps.io/benchmark.mojo' |
| 11 |
| 12 # Additional time in seconds allocated per shell run to accommodate start-up. |
| 13 # The shell should terminate before hitting this time out, it is an error if it |
| 14 # doesn't. |
| 15 _EXTRA_TIMEOUT = 20 |
| 16 |
| 17 _MEASUREMENT_RESULT_FORMAT = r""" |
| 18 ^ # Beginning of the line. |
| 19 measurement: # Hard-coded tag. |
| 20 \s+(\S+) # Match measurement spec. |
| 21 \s+(\S+) # Match measurement result. |
| 22 $ # End of the line. |
| 23 """ |
| 24 |
| 25 _MEASUREMENT_REGEX = re.compile(_MEASUREMENT_RESULT_FORMAT, re.VERBOSE) |
| 26 |
| 27 |
| 28 def _parse_measurement_results(output): |
| 29 """Parses the measurement results present in the benchmark output and returns |
| 30 the dictionary of correctly recognized and parsed results. |
| 31 """ |
| 32 measurement_results = {} |
| 33 output_lines = [line.strip() for line in output.split('\n')] |
| 34 for line in output_lines: |
| 35 match = re.match(_MEASUREMENT_REGEX, line) |
| 36 if match: |
| 37 measurement_spec = match.group(1) |
| 38 measurement_result = match.group(2) |
| 39 try: |
| 40 measurement_results[measurement_spec] = float(measurement_result) |
| 41 except ValueError: |
| 42 pass |
| 43 return measurement_results |
| 44 |
| 45 |
| 46 class Results(object): |
| 47 """Holds results of a benchmark run.""" |
| 48 |
| 49 def __init__(self, succeeded, error_str, output): |
| 50 self.succeeded = succeeded |
| 51 self.error_str = error_str |
| 52 self.output = output |
| 53 self.measurements = None |
| 54 |
| 55 |
| 56 def run(shell, shell_args, app, duration_seconds, measurements, verbose, |
| 57 android, output_file): |
| 58 """Runs the given benchmark by running `benchmark.mojo` in mojo shell with |
| 59 appropriate arguments and returns the produced output. |
| 60 |
| 61 Returns: |
| 62 A tuple of (succeeded, error_msg, output). |
| 63 """ |
| 64 timeout = duration_seconds + _EXTRA_TIMEOUT |
| 65 benchmark_args = [] |
| 66 benchmark_args.append('--app=' + app) |
| 67 benchmark_args.append('--duration=' + str(duration_seconds)) |
| 68 |
| 69 device_output_file = None |
| 70 if output_file: |
| 71 if android: |
| 72 device_output_file = os.path.join(shell.get_tmp_dir_path(), output_file) |
| 73 benchmark_args.append('--trace-output=' + device_output_file) |
| 74 else: |
| 75 benchmark_args.append('--trace-output=' + output_file) |
| 76 |
| 77 for measurement in measurements: |
| 78 benchmark_args.append(measurement['spec']) |
| 79 |
| 80 shell_args = list(shell_args) |
| 81 shell_args.append(_BENCHMARK_APP) |
| 82 shell_args.append('--force-offline-by-default') |
| 83 shell_args.append('--args-for=%s %s' % (_BENCHMARK_APP, |
| 84 ' '.join(benchmark_args))) |
| 85 |
| 86 if verbose: |
| 87 print 'shell arguments: ' + str(shell_args) |
| 88 return_code, output, did_time_out = shell.run_and_get_output( |
| 89 shell_args, timeout=timeout) |
| 90 |
| 91 if did_time_out: |
| 92 return Results(False, 'timed out', output) |
| 93 if return_code: |
| 94 return Results(False, 'return code: ' + str(return_code), output) |
| 95 |
| 96 # Pull the trace file even if some measurements are missing, as it can be |
| 97 # useful in debugging. |
| 98 if device_output_file: |
| 99 shell.pull_file(device_output_file, output_file, remove_original=True) |
| 100 |
| 101 results = Results(True, None, output) |
| 102 results.measurements = _parse_measurement_results(output) |
| 103 return results |
OLD | NEW |