| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 """Class for running instrumentation tests on a single device.""" | 5 """Class for running instrumentation tests on a single device.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import re | 9 import re |
| 10 import time | 10 import time |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 test_files += [ | 37 test_files += [ |
| 38 'net/data/ssl/certificates/', | 38 'net/data/ssl/certificates/', |
| 39 ] | 39 ] |
| 40 return test_files | 40 return test_files |
| 41 | 41 |
| 42 | 42 |
| 43 class TestRunner(base_test_runner.BaseTestRunner): | 43 class TestRunner(base_test_runner.BaseTestRunner): |
| 44 """Responsible for running a series of tests connected to a single device.""" | 44 """Responsible for running a series of tests connected to a single device.""" |
| 45 | 45 |
| 46 _DEVICE_DATA_DIR = 'chrome/test/data' | 46 _DEVICE_DATA_DIR = 'chrome/test/data' |
| 47 _DEVICE_COVERAGE_DIR = 'chrome/test/coverage' |
| 47 _HOSTMACHINE_PERF_OUTPUT_FILE = '/tmp/chrome-profile' | 48 _HOSTMACHINE_PERF_OUTPUT_FILE = '/tmp/chrome-profile' |
| 48 _DEVICE_PERF_OUTPUT_SEARCH_PREFIX = (constants.DEVICE_PERF_OUTPUT_DIR + | 49 _DEVICE_PERF_OUTPUT_SEARCH_PREFIX = (constants.DEVICE_PERF_OUTPUT_DIR + |
| 49 '/chrome-profile*') | 50 '/chrome-profile*') |
| 50 _DEVICE_HAS_TEST_FILES = {} | 51 _DEVICE_HAS_TEST_FILES = {} |
| 51 | 52 |
| 52 def __init__(self, test_options, device, shard_index, test_pkg, | 53 def __init__(self, test_options, device, shard_index, test_pkg, |
| 53 ports_to_forward): | 54 ports_to_forward): |
| 54 """Create a new TestRunner. | 55 """Create a new TestRunner. |
| 55 | 56 |
| 56 Args: | 57 Args: |
| 57 test_options: An InstrumentationOptions object. | 58 test_options: An InstrumentationOptions object. |
| 58 device: Attached android device. | 59 device: Attached android device. |
| 59 shard_index: Shard index. | 60 shard_index: Shard index. |
| 60 test_pkg: A TestPackage object. | 61 test_pkg: A TestPackage object. |
| 61 ports_to_forward: A list of port numbers for which to set up forwarders. | 62 ports_to_forward: A list of port numbers for which to set up forwarders. |
| 62 Can be optionally requested by a test case. | 63 Can be optionally requested by a test case. |
| 63 """ | 64 """ |
| 64 super(TestRunner, self).__init__(device, test_options.tool, | 65 super(TestRunner, self).__init__(device, test_options.tool, |
| 65 test_options.build_type, | 66 test_options.build_type, |
| 66 test_options.push_deps, | 67 test_options.push_deps, |
| 67 test_options.cleanup_test_files) | 68 test_options.cleanup_test_files) |
| 68 self._lighttp_port = constants.LIGHTTPD_RANDOM_PORT_FIRST + shard_index | 69 self._lighttp_port = constants.LIGHTTPD_RANDOM_PORT_FIRST + shard_index |
| 69 | 70 |
| 70 self.options = test_options | 71 self.options = test_options |
| 71 self.test_pkg = test_pkg | 72 self.test_pkg = test_pkg |
| 72 self.ports_to_forward = ports_to_forward | 73 self.ports_to_forward = ports_to_forward |
| 74 self.coverage_dir = test_options.coverage_dir |
| 73 | 75 |
| 74 #override | 76 #override |
| 75 def InstallTestPackage(self): | 77 def InstallTestPackage(self): |
| 76 self.test_pkg.Install(self.adb) | 78 self.test_pkg.Install(self.adb) |
| 77 | 79 |
| 78 #override | 80 #override |
| 79 def PushDataDeps(self): | 81 def PushDataDeps(self): |
| 80 # TODO(frankf): Implement a general approach for copying/installing | 82 # TODO(frankf): Implement a general approach for copying/installing |
| 81 # once across test runners. | 83 # once across test runners. |
| 82 if TestRunner._DEVICE_HAS_TEST_FILES.get(self.device, False): | 84 if TestRunner._DEVICE_HAS_TEST_FILES.get(self.device, False): |
| 83 logging.warning('Already copied test files to device %s, skipping.', | 85 logging.warning('Already copied test files to device %s, skipping.', |
| 84 self.device) | 86 self.device) |
| 85 return | 87 return |
| 86 | 88 |
| 87 test_data = _GetDataFilesForTestSuite(self.test_pkg.GetApkName()) | 89 test_data = _GetDataFilesForTestSuite(self.test_pkg.GetApkName()) |
| 88 if test_data: | 90 if test_data: |
| 89 # Make sure SD card is ready. | 91 # Make sure SD card is ready. |
| 90 self.adb.WaitForSdCardReady(20) | 92 self.adb.WaitForSdCardReady(20) |
| 91 for p in test_data: | 93 for p in test_data: |
| 92 self.adb.PushIfNeeded( | 94 self.adb.PushIfNeeded( |
| 93 os.path.join(constants.DIR_SOURCE_ROOT, p), | 95 os.path.join(constants.DIR_SOURCE_ROOT, p), |
| 94 os.path.join(self.adb.GetExternalStorage(), p)) | 96 os.path.join(self.adb.GetExternalStorage(), p)) |
| 95 | 97 |
| 96 # TODO(frankf): Specify test data in this file as opposed to passing | 98 # TODO(frankf): Specify test data in this file as opposed to passing |
| 97 # as command-line. | 99 # as command-line. |
| 98 for dest_host_pair in self.options.test_data: | 100 for dest_host_pair in self.options.test_data: |
| 99 dst_src = dest_host_pair.split(':',1) | 101 dst_src = dest_host_pair.split(':',1) |
| 100 dst_layer = dst_src[0] | 102 dst_layer = dst_src[0] |
| 101 host_src = dst_src[1] | 103 host_src = dst_src[1] |
| 102 host_test_files_path = constants.DIR_SOURCE_ROOT + '/' + host_src | 104 host_test_files_path = '%s/%s' % (constants.DIR_SOURCE_ROOT, host_src) |
| 103 if os.path.exists(host_test_files_path): | 105 if os.path.exists(host_test_files_path): |
| 104 self.adb.PushIfNeeded(host_test_files_path, | 106 self.adb.PushIfNeeded(host_test_files_path, '%s/%s/%s' % ( |
| 105 self.adb.GetExternalStorage() + '/' + | 107 self.adb.GetExternalStorage(), TestRunner._DEVICE_DATA_DIR, |
| 106 TestRunner._DEVICE_DATA_DIR + '/' + dst_layer) | 108 dst_layer)) |
| 107 self.tool.CopyFiles() | 109 self.tool.CopyFiles() |
| 108 TestRunner._DEVICE_HAS_TEST_FILES[self.device] = True | 110 TestRunner._DEVICE_HAS_TEST_FILES[self.device] = True |
| 109 | 111 |
| 110 def _GetInstrumentationArgs(self): | 112 def _GetInstrumentationArgs(self): |
| 111 ret = {} | 113 ret = {} |
| 112 if self.options.wait_for_debugger: | 114 if self.options.wait_for_debugger: |
| 113 ret['debug'] = 'true' | 115 ret['debug'] = 'true' |
| 116 if self.coverage_dir: |
| 117 ret['coverage'] = 'true' |
| 118 ret['coverageFile'] = self.coverage_device_file |
| 119 |
| 114 return ret | 120 return ret |
| 115 | 121 |
| 116 def _TakeScreenshot(self, test): | 122 def _TakeScreenshot(self, test): |
| 117 """Takes a screenshot from the device.""" | 123 """Takes a screenshot from the device.""" |
| 118 screenshot_name = os.path.join(constants.SCREENSHOTS_DIR, test + '.png') | 124 screenshot_name = os.path.join(constants.SCREENSHOTS_DIR, '%s.png' % test) |
| 119 logging.info('Taking screenshot named %s', screenshot_name) | 125 logging.info('Taking screenshot named %s', screenshot_name) |
| 120 self.adb.TakeScreenshot(screenshot_name) | 126 self.adb.TakeScreenshot(screenshot_name) |
| 121 | 127 |
| 122 def SetUp(self): | 128 def SetUp(self): |
| 123 """Sets up the test harness and device before all tests are run.""" | 129 """Sets up the test harness and device before all tests are run.""" |
| 124 super(TestRunner, self).SetUp() | 130 super(TestRunner, self).SetUp() |
| 125 if not self.adb.IsRootEnabled(): | 131 if not self.adb.IsRootEnabled(): |
| 126 logging.warning('Unable to enable java asserts for %s, non rooted device', | 132 logging.warning('Unable to enable java asserts for %s, non rooted device', |
| 127 self.device) | 133 self.device) |
| 128 else: | 134 else: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 150 Args: | 156 Args: |
| 151 test: The name of the test that will be run. | 157 test: The name of the test that will be run. |
| 152 """ | 158 """ |
| 153 self.SetupPerfMonitoringIfNeeded(test) | 159 self.SetupPerfMonitoringIfNeeded(test) |
| 154 self._SetupIndividualTestTimeoutScale(test) | 160 self._SetupIndividualTestTimeoutScale(test) |
| 155 self.tool.SetupEnvironment() | 161 self.tool.SetupEnvironment() |
| 156 | 162 |
| 157 # Make sure the forwarder is still running. | 163 # Make sure the forwarder is still running. |
| 158 self._RestartHttpServerForwarderIfNecessary() | 164 self._RestartHttpServerForwarderIfNecessary() |
| 159 | 165 |
| 166 if self.coverage_dir: |
| 167 coverage_basename = '%s.ec' % test |
| 168 self.coverage_device_file = '%s/%s/%s' % (self.adb.GetExternalStorage(), |
| 169 TestRunner._DEVICE_COVERAGE_DIR, |
| 170 coverage_basename) |
| 171 self.coverage_host_file = os.path.join( |
| 172 self.coverage_dir, coverage_basename) |
| 173 |
| 160 def _IsPerfTest(self, test): | 174 def _IsPerfTest(self, test): |
| 161 """Determines whether a test is a performance test. | 175 """Determines whether a test is a performance test. |
| 162 | 176 |
| 163 Args: | 177 Args: |
| 164 test: The name of the test to be checked. | 178 test: The name of the test to be checked. |
| 165 | 179 |
| 166 Returns: | 180 Returns: |
| 167 Whether the test is annotated as a performance test. | 181 Whether the test is annotated as a performance test. |
| 168 """ | 182 """ |
| 169 return _PERF_TEST_ANNOTATION in self.test_pkg.GetTestAnnotations(test) | 183 return _PERF_TEST_ANNOTATION in self.test_pkg.GetTestAnnotations(test) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 192 """ | 206 """ |
| 193 | 207 |
| 194 self.tool.CleanUpEnvironment() | 208 self.tool.CleanUpEnvironment() |
| 195 | 209 |
| 196 # The logic below relies on the test passing. | 210 # The logic below relies on the test passing. |
| 197 if not raw_result or raw_result.GetStatusCode(): | 211 if not raw_result or raw_result.GetStatusCode(): |
| 198 return | 212 return |
| 199 | 213 |
| 200 self.TearDownPerfMonitoring(test) | 214 self.TearDownPerfMonitoring(test) |
| 201 | 215 |
| 216 if self.coverage_dir: |
| 217 self.adb.Adb().Pull(self.coverage_device_file, self.coverage_host_file) |
| 218 self.adb.RunShellCommand('rm -f %s' % self.coverage_device_file) |
| 219 |
| 202 def TearDownPerfMonitoring(self, test): | 220 def TearDownPerfMonitoring(self, test): |
| 203 """Cleans up performance monitoring if the specified test required it. | 221 """Cleans up performance monitoring if the specified test required it. |
| 204 | 222 |
| 205 Args: | 223 Args: |
| 206 test: The name of the test that was just run. | 224 test: The name of the test that was just run. |
| 207 Raises: | 225 Raises: |
| 208 Exception: if there's anything wrong with the perf data. | 226 Exception: if there's anything wrong with the perf data. |
| 209 """ | 227 """ |
| 210 if not self._IsPerfTest(test): | 228 if not self._IsPerfTest(test): |
| 211 return | 229 return |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 duration_ms = 0 | 354 duration_ms = 0 |
| 337 message = str(e) | 355 message = str(e) |
| 338 if not message: | 356 if not message: |
| 339 message = 'No information.' | 357 message = 'No information.' |
| 340 results.AddResult(test_result.InstrumentationTestResult( | 358 results.AddResult(test_result.InstrumentationTestResult( |
| 341 test, base_test_result.ResultType.CRASH, start_date_ms, duration_ms, | 359 test, base_test_result.ResultType.CRASH, start_date_ms, duration_ms, |
| 342 log=message)) | 360 log=message)) |
| 343 raw_result = None | 361 raw_result = None |
| 344 self.TestTeardown(test, raw_result) | 362 self.TestTeardown(test, raw_result) |
| 345 return (results, None if results.DidRunPass() else test) | 363 return (results, None if results.DidRunPass() else test) |
| OLD | NEW |