| 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 |