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 |