OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 import fnmatch | 5 import fnmatch |
6 import imp | 6 import imp |
7 import logging | 7 import logging |
8 import posixpath | 8 import posixpath |
9 import signal | 9 import signal |
10 import thread | 10 import thread |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 def SubstituteDeviceRoot(device_path, device_root): | 48 def SubstituteDeviceRoot(device_path, device_root): |
49 if not device_path: | 49 if not device_path: |
50 return device_root | 50 return device_root |
51 elif isinstance(device_path, list): | 51 elif isinstance(device_path, list): |
52 return posixpath.join(*(p if p else device_root for p in device_path)) | 52 return posixpath.join(*(p if p else device_root for p in device_path)) |
53 else: | 53 else: |
54 return device_path | 54 return device_path |
55 | 55 |
56 | 56 |
| 57 class TestsTerminated(Exception): |
| 58 pass |
| 59 |
| 60 |
| 61 class InvalidShardingSettings(Exception): |
| 62 def __init__(self, shard_index, total_shards): |
| 63 super(InvalidShardingSettings, self).__init__( |
| 64 'Invalid sharding settings. shard_index: %d total_shards: %d' |
| 65 % (shard_index, total_shards)) |
| 66 |
| 67 |
57 class LocalDeviceTestRun(test_run.TestRun): | 68 class LocalDeviceTestRun(test_run.TestRun): |
58 | 69 |
59 def __init__(self, env, test_instance): | 70 def __init__(self, env, test_instance): |
60 super(LocalDeviceTestRun, self).__init__(env, test_instance) | 71 super(LocalDeviceTestRun, self).__init__(env, test_instance) |
61 self._tools = {} | 72 self._tools = {} |
62 | 73 |
63 #override | 74 #override |
64 def RunTests(self): | 75 def RunTests(self): |
65 tests = self._GetTests() | 76 tests = self._GetTests() |
66 | 77 |
(...skipping 21 matching lines...) Expand all Loading... |
88 rerun = test | 99 rerun = test |
89 raise | 100 raise |
90 finally: | 101 finally: |
91 if isinstance(tests, test_collection.TestCollection): | 102 if isinstance(tests, test_collection.TestCollection): |
92 if rerun: | 103 if rerun: |
93 tests.add(rerun) | 104 tests.add(rerun) |
94 tests.test_completed() | 105 tests.test_completed() |
95 | 106 |
96 logging.info('Finished running tests on this device.') | 107 logging.info('Finished running tests on this device.') |
97 | 108 |
98 class TestsTerminated(Exception): | |
99 pass | |
100 | |
101 def stop_tests(_signum, _frame): | 109 def stop_tests(_signum, _frame): |
102 logging.critical('Received SIGTERM. Stopping test execution.') | 110 logging.critical('Received SIGTERM. Stopping test execution.') |
103 exit_now.set() | 111 exit_now.set() |
104 raise TestsTerminated() | 112 raise TestsTerminated() |
105 | 113 |
106 try: | 114 try: |
107 with signal_handler.SignalHandler(signal.SIGTERM, stop_tests): | 115 with signal_handler.SignalHandler(signal.SIGTERM, stop_tests): |
108 tries = 0 | 116 tries = 0 |
109 results = [] | 117 results = [] |
110 while tries < self._env.max_tries and tests: | 118 while tries < self._env.max_tries and tests: |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 # See local_device_gtest_run._ExtractTestsFromFilter() | 178 # See local_device_gtest_run._ExtractTestsFromFilter() |
171 if name.endswith('*'): | 179 if name.endswith('*'): |
172 return any(fnmatch.fnmatch(n, name) and is_failure_result(t) | 180 return any(fnmatch.fnmatch(n, name) and is_failure_result(t) |
173 for n, t in all_test_results.iteritems()) | 181 for n, t in all_test_results.iteritems()) |
174 return is_failure_result(all_test_results.get(name)) | 182 return is_failure_result(all_test_results.get(name)) |
175 | 183 |
176 failed_tests = (t for t in tests if test_failed(self._GetUniqueTestName(t))) | 184 failed_tests = (t for t in tests if test_failed(self._GetUniqueTestName(t))) |
177 | 185 |
178 return [t for t in failed_tests if self._ShouldRetry(t)] | 186 return [t for t in failed_tests if self._ShouldRetry(t)] |
179 | 187 |
| 188 def _ApplyExternalSharding(self, tests, shard_index, total_shards): |
| 189 logging.info('Using external sharding settings. This is shard %d/%d', |
| 190 shard_index, total_shards) |
| 191 |
| 192 if total_shards < 0 or shard_index < 0 or total_shards <= shard_index: |
| 193 raise InvalidShardingSettings(shard_index, total_shards) |
| 194 |
| 195 return [ |
| 196 t for t in tests |
| 197 if hash(self._GetUniqueTestName(t)) % total_shards == shard_index] |
| 198 |
180 def GetTool(self, device): | 199 def GetTool(self, device): |
181 if not str(device) in self._tools: | 200 if not str(device) in self._tools: |
182 self._tools[str(device)] = valgrind_tools.CreateTool( | 201 self._tools[str(device)] = valgrind_tools.CreateTool( |
183 self._env.tool, device) | 202 self._env.tool, device) |
184 return self._tools[str(device)] | 203 return self._tools[str(device)] |
185 | 204 |
186 def _CreateShards(self, tests): | 205 def _CreateShards(self, tests): |
187 raise NotImplementedError | 206 raise NotImplementedError |
188 | 207 |
189 def _GetUniqueTestName(self, test): | 208 def _GetUniqueTestName(self, test): |
190 # pylint: disable=no-self-use | 209 # pylint: disable=no-self-use |
191 return test | 210 return test |
192 | 211 |
193 def _ShouldRetry(self, test): | 212 def _ShouldRetry(self, test): |
194 # pylint: disable=no-self-use,unused-argument | 213 # pylint: disable=no-self-use,unused-argument |
195 return True | 214 return True |
196 | 215 |
197 def _GetTests(self): | 216 def _GetTests(self): |
198 raise NotImplementedError | 217 raise NotImplementedError |
199 | |
200 def _RunTest(self, device, test): | 218 def _RunTest(self, device, test): |
201 raise NotImplementedError | 219 raise NotImplementedError |
202 | 220 |
203 def _ShouldShard(self): | 221 def _ShouldShard(self): |
204 raise NotImplementedError | 222 raise NotImplementedError |
205 | 223 |
206 | 224 |
207 class NoTestsError(Exception): | 225 class NoTestsError(Exception): |
208 """Error for when no tests are found.""" | 226 """Error for when no tests are found.""" |
OLD | NEW |