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 functools | |
7 import imp | 6 import imp |
8 import logging | 7 import logging |
9 import signal | 8 import signal |
10 import thread | 9 import thread |
11 import threading | 10 import threading |
12 | 11 |
13 from devil import base_error | |
14 from devil.android import device_errors | |
15 from devil.utils import signal_handler | 12 from devil.utils import signal_handler |
16 from pylib import valgrind_tools | 13 from pylib import valgrind_tools |
17 from pylib.base import base_test_result | 14 from pylib.base import base_test_result |
18 from pylib.base import test_run | 15 from pylib.base import test_run |
19 from pylib.base import test_collection | 16 from pylib.base import test_collection |
| 17 from pylib.local.device import local_device_environment |
20 | 18 |
21 | 19 |
22 def IncrementalInstall(device, apk_helper, installer_script): | 20 def IncrementalInstall(device, apk_helper, installer_script): |
23 """Performs an incremental install. | 21 """Performs an incremental install. |
24 | 22 |
25 Args: | 23 Args: |
26 device: Device to install on. | 24 device: Device to install on. |
27 apk_helper: ApkHelper instance for the _incremental.apk. | 25 apk_helper: ApkHelper instance for the _incremental.apk. |
28 installer_script: Path to the installer script for the incremental apk. | 26 installer_script: Path to the installer script for the incremental apk. |
29 """ | 27 """ |
30 try: | 28 try: |
31 install_wrapper = imp.load_source('install_wrapper', installer_script) | 29 install_wrapper = imp.load_source('install_wrapper', installer_script) |
32 except IOError: | 30 except IOError: |
33 raise Exception('Incremental install script not found: %s\n' % | 31 raise Exception('Incremental install script not found: %s\n' % |
34 installer_script) | 32 installer_script) |
35 params = install_wrapper.GetInstallParameters() | 33 params = install_wrapper.GetInstallParameters() |
36 | 34 |
37 from incremental_install import installer | 35 from incremental_install import installer |
38 installer.Install(device, apk_helper, split_globs=params['splits'], | 36 installer.Install(device, apk_helper, split_globs=params['splits'], |
39 native_libs=params['native_libs'], | 37 native_libs=params['native_libs'], |
40 dex_files=params['dex_files'], | 38 dex_files=params['dex_files'], |
41 permissions=None) # Auto-grant permissions from manifest. | 39 permissions=None) # Auto-grant permissions from manifest. |
42 | 40 |
43 | 41 |
44 def handle_shard_failures(f): | |
45 """A decorator that handles device failures for per-device functions. | |
46 | |
47 Args: | |
48 f: the function being decorated. The function must take at least one | |
49 argument, and that argument must be the device. | |
50 """ | |
51 return handle_shard_failures_with(None)(f) | |
52 | |
53 | |
54 def handle_shard_failures_with(on_failure): | |
55 """A decorator that handles device failures for per-device functions. | |
56 | |
57 This calls on_failure in the event of a failure. | |
58 | |
59 Args: | |
60 f: the function being decorated. The function must take at least one | |
61 argument, and that argument must be the device. | |
62 on_failure: A binary function to call on failure. | |
63 """ | |
64 def decorator(f): | |
65 @functools.wraps(f) | |
66 def wrapper(dev, *args, **kwargs): | |
67 try: | |
68 return f(dev, *args, **kwargs) | |
69 except device_errors.CommandTimeoutError: | |
70 logging.exception('Shard timed out: %s(%s)', f.__name__, str(dev)) | |
71 except device_errors.DeviceUnreachableError: | |
72 logging.exception('Shard died: %s(%s)', f.__name__, str(dev)) | |
73 except base_error.BaseError: | |
74 logging.exception('Shard failed: %s(%s)', f.__name__, str(dev)) | |
75 except SystemExit: | |
76 logging.exception('Shard killed: %s(%s)', f.__name__, str(dev)) | |
77 raise | |
78 if on_failure: | |
79 on_failure(dev, f.__name__) | |
80 return None | |
81 | |
82 return wrapper | |
83 | |
84 return decorator | |
85 | |
86 | |
87 class LocalDeviceTestRun(test_run.TestRun): | 42 class LocalDeviceTestRun(test_run.TestRun): |
88 | 43 |
89 def __init__(self, env, test_instance): | 44 def __init__(self, env, test_instance): |
90 super(LocalDeviceTestRun, self).__init__(env, test_instance) | 45 super(LocalDeviceTestRun, self).__init__(env, test_instance) |
91 self._tools = {} | 46 self._tools = {} |
92 | 47 |
93 #override | 48 #override |
94 def RunTests(self): | 49 def RunTests(self): |
95 tests = self._GetTests() | 50 tests = self._GetTests() |
96 | 51 |
97 exit_now = threading.Event() | 52 exit_now = threading.Event() |
98 | 53 |
99 @handle_shard_failures | 54 @local_device_environment.handle_shard_failures |
100 def run_tests_on_device(dev, tests, results): | 55 def run_tests_on_device(dev, tests, results): |
101 for test in tests: | 56 for test in tests: |
102 if exit_now.isSet(): | 57 if exit_now.isSet(): |
103 thread.exit() | 58 thread.exit() |
104 | 59 |
105 result = None | 60 result = None |
106 try: | 61 try: |
107 result = self._RunTest(dev, test) | 62 result = self._RunTest(dev, test) |
108 if isinstance(result, base_test_result.BaseTestResult): | 63 if isinstance(result, base_test_result.BaseTestResult): |
109 results.AddResult(result) | 64 results.AddResult(result) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 | 174 |
220 def _RunTest(self, device, test): | 175 def _RunTest(self, device, test): |
221 raise NotImplementedError | 176 raise NotImplementedError |
222 | 177 |
223 def _ShouldShard(self): | 178 def _ShouldShard(self): |
224 raise NotImplementedError | 179 raise NotImplementedError |
225 | 180 |
226 | 181 |
227 class NoTestsError(Exception): | 182 class NoTestsError(Exception): |
228 """Error for when no tests are found.""" | 183 """Error for when no tests are found.""" |
OLD | NEW |