| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Runs perf tests. | 5 """Runs perf tests. |
| 6 | 6 |
| 7 Our buildbot infrastructure requires each slave to run steps serially. | 7 Our buildbot infrastructure requires each slave to run steps serially. |
| 8 This is sub-optimal for android, where these steps can run independently on | 8 This is sub-optimal for android, where these steps can run independently on |
| 9 multiple connected devices. | 9 multiple connected devices. |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 Note that script_to_execute necessarily have to take at least the following | 39 Note that script_to_execute necessarily have to take at least the following |
| 40 option: | 40 option: |
| 41 --device: the serial number to be passed to all adb commands. | 41 --device: the serial number to be passed to all adb commands. |
| 42 """ | 42 """ |
| 43 | 43 |
| 44 import datetime | 44 import datetime |
| 45 import logging | 45 import logging |
| 46 import os | 46 import os |
| 47 import pickle | 47 import pickle |
| 48 import sys | 48 import sys |
| 49 import threading |
| 49 import time | 50 import time |
| 50 | 51 |
| 51 from pylib import constants | 52 from pylib import constants |
| 52 from pylib import forwarder | 53 from pylib import forwarder |
| 53 from pylib import pexpect | 54 from pylib import pexpect |
| 54 from pylib.base import base_test_result | 55 from pylib.base import base_test_result |
| 55 from pylib.base import base_test_runner | 56 from pylib.base import base_test_runner |
| 56 | 57 |
| 57 | 58 |
| 58 def PrintTestOutput(test_name): | 59 def PrintTestOutput(test_name): |
| (...skipping 22 matching lines...) Expand all Loading... |
| 81 | 82 |
| 82 | 83 |
| 83 class _HeartBeatLogger(object): | 84 class _HeartBeatLogger(object): |
| 84 # How often to print the heartbeat on flush(). | 85 # How often to print the heartbeat on flush(). |
| 85 _PRINT_INTERVAL = 600 | 86 _PRINT_INTERVAL = 600 |
| 86 | 87 |
| 87 def __init__(self): | 88 def __init__(self): |
| 88 """A file-like class for keeping the buildbot alive.""" | 89 """A file-like class for keeping the buildbot alive.""" |
| 89 self._len = 0 | 90 self._len = 0 |
| 90 self._tick = time.time() | 91 self._tick = time.time() |
| 92 self._stopped = threading.Event() |
| 93 self._timer = threading.Thread(target=self._runner) |
| 94 self._timer.start() |
| 95 |
| 96 def _runner(self): |
| 97 while not self._stopped.is_set(): |
| 98 self.flush() |
| 99 self._stopped.wait(_HeartBeatLogger._PRINT_INTERVAL) |
| 91 | 100 |
| 92 def write(self, data): | 101 def write(self, data): |
| 93 self._len += len(data) | 102 self._len += len(data) |
| 94 | 103 |
| 95 def flush(self): | 104 def flush(self): |
| 96 now = time.time() | 105 now = time.time() |
| 97 if now - self._tick >= _HeartBeatLogger._PRINT_INTERVAL: | 106 if now - self._tick >= _HeartBeatLogger._PRINT_INTERVAL: |
| 98 self._tick = now | 107 self._tick = now |
| 99 print '--single-step output length %d' % self._len | 108 print '--single-step output length %d' % self._len |
| 100 | 109 |
| 110 def stop(self): |
| 111 self._stopped.set() |
| 112 |
| 101 | 113 |
| 102 class TestRunner(base_test_runner.BaseTestRunner): | 114 class TestRunner(base_test_runner.BaseTestRunner): |
| 103 def __init__(self, test_options, device, tests, flaky_tests): | 115 def __init__(self, test_options, device, tests, flaky_tests): |
| 104 """A TestRunner instance runs a perf test on a single device. | 116 """A TestRunner instance runs a perf test on a single device. |
| 105 | 117 |
| 106 Args: | 118 Args: |
| 107 test_options: A PerfOptions object. | 119 test_options: A PerfOptions object. |
| 108 device: Device to run the tests. | 120 device: Device to run the tests. |
| 109 tests: a dict mapping test_name to command. | 121 tests: a dict mapping test_name to command. |
| 110 flaky_tests: a list of flaky test_name. | 122 flaky_tests: a list of flaky test_name. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 # Just print a heart-beat so that the outer buildbot scripts won't timeout | 178 # Just print a heart-beat so that the outer buildbot scripts won't timeout |
| 167 # without response. | 179 # without response. |
| 168 logfile = _HeartBeatLogger() | 180 logfile = _HeartBeatLogger() |
| 169 cwd = os.path.abspath(constants.DIR_SOURCE_ROOT) | 181 cwd = os.path.abspath(constants.DIR_SOURCE_ROOT) |
| 170 if full_cmd.startswith('src/'): | 182 if full_cmd.startswith('src/'): |
| 171 cwd = os.path.abspath(os.path.join(constants.DIR_SOURCE_ROOT, os.pardir)) | 183 cwd = os.path.abspath(os.path.join(constants.DIR_SOURCE_ROOT, os.pardir)) |
| 172 output, exit_code = pexpect.run( | 184 output, exit_code = pexpect.run( |
| 173 full_cmd, cwd=cwd, | 185 full_cmd, cwd=cwd, |
| 174 withexitstatus=True, logfile=logfile, timeout=timeout, | 186 withexitstatus=True, logfile=logfile, timeout=timeout, |
| 175 env=os.environ) | 187 env=os.environ) |
| 188 if self._options.single_step: |
| 189 # Stop the logger. |
| 190 logfile.stop() |
| 176 end_time = datetime.datetime.now() | 191 end_time = datetime.datetime.now() |
| 177 if exit_code is None: | 192 if exit_code is None: |
| 178 exit_code = -1 | 193 exit_code = -1 |
| 179 logging.info('%s : exit_code=%d in %d secs at %s', | 194 logging.info('%s : exit_code=%d in %d secs at %s', |
| 180 test_name, exit_code, (end_time - start_time).seconds, | 195 test_name, exit_code, (end_time - start_time).seconds, |
| 181 self.device) | 196 self.device) |
| 182 result_type = base_test_result.ResultType.FAIL | 197 result_type = base_test_result.ResultType.FAIL |
| 183 if exit_code == 0: | 198 if exit_code == 0: |
| 184 result_type = base_test_result.ResultType.PASS | 199 result_type = base_test_result.ResultType.PASS |
| 185 actual_exit_code = exit_code | 200 actual_exit_code = exit_code |
| (...skipping 27 matching lines...) Expand all Loading... |
| 213 Returns: | 228 Returns: |
| 214 A tuple of (TestRunResults, retry). | 229 A tuple of (TestRunResults, retry). |
| 215 """ | 230 """ |
| 216 output, result_type = self._LaunchPerfTest(test_name) | 231 output, result_type = self._LaunchPerfTest(test_name) |
| 217 results = base_test_result.TestRunResults() | 232 results = base_test_result.TestRunResults() |
| 218 results.AddResult(base_test_result.BaseTestResult(test_name, result_type)) | 233 results.AddResult(base_test_result.BaseTestResult(test_name, result_type)) |
| 219 retry = None | 234 retry = None |
| 220 if not results.DidRunPass(): | 235 if not results.DidRunPass(): |
| 221 retry = test_name | 236 retry = test_name |
| 222 return results, retry | 237 return results, retry |
| OLD | NEW |