diff options
Diffstat (limited to 'deps/v8/build/android/pylib/perf/perf_test_instance.py')
-rw-r--r-- | deps/v8/build/android/pylib/perf/perf_test_instance.py | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/deps/v8/build/android/pylib/perf/perf_test_instance.py b/deps/v8/build/android/pylib/perf/perf_test_instance.py new file mode 100644 index 0000000000..49d75e48e3 --- /dev/null +++ b/deps/v8/build/android/pylib/perf/perf_test_instance.py @@ -0,0 +1,239 @@ +# Copyright 2016 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. + +import json +import logging +import os +import pickle +import re + +from devil import base_error +from devil.utils import cmd_helper +from pylib import constants +from pylib.base import base_test_result +from pylib.base import test_instance +from pylib.constants import host_paths +from pylib.utils import test_filter + + +_GIT_CR_POS_RE = re.compile(r'^Cr-Commit-Position: refs/heads/master@{#(\d+)}$') + + +def _GetPersistedResult(test_name): + file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name) + if not os.path.exists(file_name): + logging.error('File not found %s', file_name) + return None + + with file(file_name, 'r') as f: + return pickle.load(f) + + +def _GetChromiumRevision(): + # pylint: disable=line-too-long + """Get the git hash and commit position of the chromium master branch. + + See: + https://chromium.googlesource.com/chromium/tools/build/+/387e3cf3/scripts/slave/runtest.py#211 + + Returns: + A dictionary with 'revision' and 'commit_pos' keys. + """ + # pylint: enable=line-too-long + status, output = cmd_helper.GetCmdStatusAndOutput( + ['git', 'log', '-n', '1', '--pretty=format:%H%n%B', 'HEAD'], + cwd=host_paths.DIR_SOURCE_ROOT) + revision = None + commit_pos = None + if not status: + lines = output.splitlines() + revision = lines[0] + for line in reversed(lines): + m = _GIT_CR_POS_RE.match(line.strip()) + if m: + commit_pos = int(m.group(1)) + break + return {'revision': revision, 'commit_pos': commit_pos} + + +class PerfTestInstance(test_instance.TestInstance): + def __init__(self, args, _): + super(PerfTestInstance, self).__init__() + + self._collect_chartjson_data = args.collect_chartjson_data + self._dry_run = args.dry_run + self._output_dir_archive_path = args.output_dir_archive_path + # TODO(rnephew): Get rid of this when everything uses + # --output-dir-archive-path + if self._output_dir_archive_path is None and args.get_output_dir_archive: + self._output_dir_archive_path = args.get_output_dir_archive + self._known_devices_file = args.known_devices_file + self._max_battery_temp = args.max_battery_temp + self._min_battery_level = args.min_battery_level + self._no_timeout = args.no_timeout + self._output_chartjson_data = args.output_chartjson_data + self._output_json_list = args.output_json_list + self._print_step = args.print_step + self._single_step = ( + ' '.join(args.single_step_command) if args.single_step else None) + self._steps = args.steps + self._test_filter = test_filter.InitializeFilterFromArgs(args) + self._write_buildbot_json = args.write_buildbot_json + + #override + def SetUp(self): + pass + + #override + def TearDown(self): + pass + + def OutputJsonList(self): + try: + with file(self._steps, 'r') as i: + all_steps = json.load(i) + + step_values = [] + for k, v in all_steps['steps'].iteritems(): + data = {'test': k, 'device_affinity': v['device_affinity']} + + persisted_result = _GetPersistedResult(k) + if persisted_result: + data['start_time'] = persisted_result['start_time'] + data['end_time'] = persisted_result['end_time'] + data['total_time'] = persisted_result['total_time'] + data['has_archive'] = persisted_result['archive_bytes'] is not None + step_values.append(data) + + with file(self.output_json_list, 'w') as o: + o.write(json.dumps(step_values)) + return base_test_result.ResultType.PASS + except KeyError: + logging.exception('Persistent results file missing key.') + return base_test_result.ResultType.FAIL + + def PrintTestOutput(self): + """Helper method to print the output of previously executed test_name. + + Test_name is passed from the command line as print_step + + Returns: + exit code generated by the test step. + """ + persisted_result = _GetPersistedResult(self._print_step) + if not persisted_result: + raise PersistentDataError('No data for test %s found.' % self._print_step) + logging.info('*' * 80) + logging.info('Output from:') + logging.info(persisted_result['cmd']) + logging.info('*' * 80) + + output_formatted = '' + persisted_outputs = persisted_result['output'] + for i in xrange(len(persisted_outputs)): + output_formatted += '\n\nOutput from run #%d:\n\n%s' % ( + i, persisted_outputs[i]) + print output_formatted + + if self.output_chartjson_data: + with file(self.output_chartjson_data, 'w') as f: + f.write(persisted_result['chartjson']) + + if self.output_dir_archive_path: + if persisted_result['archive_bytes'] is not None: + with file(self.output_dir_archive_path, 'wb') as f: + f.write(persisted_result['archive_bytes']) + else: + logging.error('The output dir was not archived.') + if persisted_result['exit_code'] == 0: + return base_test_result.ResultType.PASS + return base_test_result.ResultType.FAIL + + #override + def TestType(self): + return 'perf' + + @staticmethod + def ReadChartjsonOutput(output_dir): + if not output_dir: + return '' + json_output_path = os.path.join(output_dir, 'results-chart.json') + try: + with open(json_output_path) as f: + return f.read() + except IOError: + logging.exception('Exception when reading chartjson.') + logging.error('This usually means that telemetry did not run, so it could' + ' not generate the file. Please check the device running' + ' the test.') + return '' + + def WriteBuildBotJson(self, output_dir): + """Write metadata about the buildbot environment to the output dir.""" + if not output_dir or not self._write_buildbot_json: + return + data = { + 'chromium': _GetChromiumRevision(), + 'environment': dict(os.environ) + } + with open(os.path.join(output_dir, 'buildbot.json'), 'w') as f: + json.dump(data, f, sort_keys=True, separators=(',', ': ')) + + @property + def collect_chartjson_data(self): + return self._collect_chartjson_data + + @property + def dry_run(self): + return self._dry_run + + @property + def known_devices_file(self): + return self._known_devices_file + + @property + def max_battery_temp(self): + return self._max_battery_temp + + @property + def min_battery_level(self): + return self._min_battery_level + + @property + def no_timeout(self): + return self._no_timeout + + @property + def output_chartjson_data(self): + return self._output_chartjson_data + + @property + def output_dir_archive_path(self): + return self._output_dir_archive_path + + @property + def output_json_list(self): + return self._output_json_list + + @property + def print_step(self): + return self._print_step + + @property + def single_step(self): + return self._single_step + + @property + def steps(self): + return self._steps + + @property + def test_filter(self): + return self._test_filter + + +class PersistentDataError(base_error.BaseError): + def __init__(self, message): + super(PersistentDataError, self).__init__(message) + self._is_infra_error = True |