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 """Runs the Java tests. See more information on run_instrumentation_tests.py.""" | 5 """Runs the Java tests. See more information on run_instrumentation_tests.py.""" |
6 | 6 |
7 import fnmatch | 7 import fnmatch |
8 import logging | 8 import logging |
9 import os | 9 import os |
10 import re | 10 import re |
(...skipping 22 matching lines...) Expand all Loading... | |
33 """A fatal test exception.""" | 33 """A fatal test exception.""" |
34 pass | 34 pass |
35 | 35 |
36 | 36 |
37 def _TestNameToExpectation(test_name): | 37 def _TestNameToExpectation(test_name): |
38 # A test name is a Package.Path.Class#testName; convert to what we use in | 38 # A test name is a Package.Path.Class#testName; convert to what we use in |
39 # the expectation file. | 39 # the expectation file. |
40 return '.'.join(test_name.replace('#', '.').split('.')[-2:]) | 40 return '.'.join(test_name.replace('#', '.').split('.')[-2:]) |
41 | 41 |
42 | 42 |
43 # TODO(jaydeepmehta): FilterTests should be moved to a common file for | |
bulach
2012/09/24 10:40:49
ditto :)
in fact, I think we can remove this, ther
felipeg
2012/09/25 03:27:21
Done.
| |
44 # all integration tests. | |
43 def FilterTests(test_names, pattern_list, inclusive): | 45 def FilterTests(test_names, pattern_list, inclusive): |
44 """Filters |test_names| using a list of patterns. | 46 """Filters |test_names| using a list of patterns. |
45 | 47 |
46 Args: | 48 Args: |
47 test_names: A list of test names. | 49 test_names: A list of test names. |
48 pattern_list: A list of patterns. | 50 pattern_list: A list of patterns. |
49 inclusive: If True, returns the tests that match any pattern. if False, | 51 inclusive: If True, returns the tests that match any pattern. if False, |
50 returns the tests that do not match any pattern. | 52 returns the tests that do not match any pattern. |
51 Returns: | 53 Returns: |
52 A list of test names. | 54 A list of test names. |
53 """ | 55 """ |
54 ret = [] | 56 ret = [] |
55 for t in test_names: | 57 for t in test_names: |
56 has_match = False | 58 has_match = False |
57 for pattern in pattern_list: | 59 for pattern in pattern_list: |
58 has_match = has_match or fnmatch.fnmatch(_TestNameToExpectation(t), | 60 has_match = has_match or fnmatch.fnmatch(_TestNameToExpectation(t), |
59 pattern) | 61 pattern) |
60 if has_match == inclusive: | 62 if has_match == inclusive: |
61 ret += [t] | 63 ret += [t] |
62 return ret | 64 return ret |
63 | 65 |
64 | 66 |
65 class TestRunner(BaseTestRunner): | 67 class TestRunner(BaseTestRunner): |
66 """Responsible for running a series of tests connected to a single device.""" | 68 """Responsible for running a series of tests connected to a single device.""" |
67 | 69 |
68 _DEVICE_DATA_DIR = constants.TEST_DATA_DIR + '/chrome/test/data' | 70 _DEVICE_DATA_DIR = 'chrome/test/data' |
69 _EMMA_JAR = os.path.join(os.environ.get('ANDROID_BUILD_TOP', ''), | 71 _EMMA_JAR = os.path.join(os.environ.get('ANDROID_BUILD_TOP', ''), |
70 'external/emma/lib/emma.jar') | 72 'external/emma/lib/emma.jar') |
71 _COVERAGE_MERGED_FILENAME = 'unittest_coverage.es' | 73 _COVERAGE_MERGED_FILENAME = 'unittest_coverage.es' |
72 _COVERAGE_WEB_ROOT_DIR = os.environ.get('EMMA_WEB_ROOTDIR') | 74 _COVERAGE_WEB_ROOT_DIR = os.environ.get('EMMA_WEB_ROOTDIR') |
73 _COVERAGE_FILENAME = 'coverage.ec' | 75 _COVERAGE_FILENAME = 'coverage.ec' |
74 _COVERAGE_RESULT_PATH = ('/data/data/com.google.android.apps.chrome/files/' + | 76 _COVERAGE_RESULT_PATH = ('/data/data/com.google.android.apps.chrome/files/' + |
75 _COVERAGE_FILENAME) | 77 _COVERAGE_FILENAME) |
76 _COVERAGE_META_INFO_PATH = os.path.join(os.environ.get('ANDROID_BUILD_TOP', | 78 _COVERAGE_META_INFO_PATH = os.path.join(os.environ.get('ANDROID_BUILD_TOP', |
77 ''), | 79 ''), |
78 'out/target/common/obj/APPS', | 80 'out/target/common/obj/APPS', |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 self.wait_for_debugger = options.wait_for_debugger | 125 self.wait_for_debugger = options.wait_for_debugger |
124 | 126 |
125 self.tests_iter = tests_iter | 127 self.tests_iter = tests_iter |
126 self.coverage = coverage | 128 self.coverage = coverage |
127 self.apks = apks | 129 self.apks = apks |
128 self.test_apk = apks[0] | 130 self.test_apk = apks[0] |
129 self.instrumentation_class_path = self.test_apk.GetPackageName() | 131 self.instrumentation_class_path = self.test_apk.GetPackageName() |
130 self.ports_to_forward = ports_to_forward | 132 self.ports_to_forward = ports_to_forward |
131 | 133 |
132 self.test_results = TestResults() | 134 self.test_results = TestResults() |
133 # List of forwarders created by this instance of TestRunner. | 135 self.forwarder = None |
134 self.forwarders = [] | |
135 | 136 |
136 if self.coverage: | 137 if self.coverage: |
137 if os.path.exists(TestRunner._COVERAGE_MERGED_FILENAME): | 138 if os.path.exists(TestRunner._COVERAGE_MERGED_FILENAME): |
138 os.remove(TestRunner._COVERAGE_MERGED_FILENAME) | 139 os.remove(TestRunner._COVERAGE_MERGED_FILENAME) |
139 if not os.path.exists(TestRunner._COVERAGE_META_INFO_PATH): | 140 if not os.path.exists(TestRunner._COVERAGE_META_INFO_PATH): |
140 raise FatalTestException('FATAL ERROR in ' + sys.argv[0] + | 141 raise FatalTestException('FATAL ERROR in ' + sys.argv[0] + |
141 ' : Coverage meta info [' + | 142 ' : Coverage meta info [' + |
142 TestRunner._COVERAGE_META_INFO_PATH + | 143 TestRunner._COVERAGE_META_INFO_PATH + |
143 '] does not exist.') | 144 '] does not exist.') |
144 if (not TestRunner._COVERAGE_WEB_ROOT_DIR or | 145 if (not TestRunner._COVERAGE_WEB_ROOT_DIR or |
(...skipping 10 matching lines...) Expand all Loading... | |
155 self.tests_iter = (BaseTestSharder.tests_container) | 156 self.tests_iter = (BaseTestSharder.tests_container) |
156 assert self.tests_iter | 157 assert self.tests_iter |
157 return self.tests_iter | 158 return self.tests_iter |
158 | 159 |
159 def CopyTestFilesOnce(self): | 160 def CopyTestFilesOnce(self): |
160 """Pushes the test data files to the device. Installs the apk if opted.""" | 161 """Pushes the test data files to the device. Installs the apk if opted.""" |
161 if TestRunner._DEVICE_HAS_TEST_FILES.get(self.device, False): | 162 if TestRunner._DEVICE_HAS_TEST_FILES.get(self.device, False): |
162 logging.warning('Already copied test files to device %s, skipping.', | 163 logging.warning('Already copied test files to device %s, skipping.', |
163 self.device) | 164 self.device) |
164 return | 165 return |
165 host_test_files_path = (constants.CHROME_DIR + | 166 host_test_files = [ |
166 '/chrome/test/data/android/device_files') | 167 ('android_webview/test/data/device_files', 'webview'), |
167 if os.path.exists(host_test_files_path): | 168 ('content/test/data/android/device_files', 'content'), |
168 self.adb.PushIfNeeded(host_test_files_path, | 169 ('chrome/test/data/android/device_files', 'chrome') |
169 TestRunner._DEVICE_DATA_DIR) | 170 ] |
171 for (host_src, dst_layer) in host_test_files: | |
172 host_test_files_path = constants.CHROME_DIR + '/' + host_src | |
173 if os.path.exists(host_test_files_path): | |
174 self.adb.PushIfNeeded(host_test_files_path, | |
175 self.adb.GetExternalStorage() + '/' + | |
176 TestRunner._DEVICE_DATA_DIR + '/' + dst_layer) | |
170 if self.install_apk: | 177 if self.install_apk: |
171 for apk in self.apks: | 178 for apk in self.apks: |
172 self.adb.ManagedInstall(apk.GetApkPath(), | 179 self.adb.ManagedInstall(apk.GetApkPath(), |
173 package_name=apk.GetPackageName()) | 180 package_name=apk.GetPackageName()) |
174 self.tool.CopyFiles() | 181 self.tool.CopyFiles() |
175 TestRunner._DEVICE_HAS_TEST_FILES[self.device] = True | 182 TestRunner._DEVICE_HAS_TEST_FILES[self.device] = True |
176 | 183 |
177 def SaveCoverageData(self, test): | 184 def SaveCoverageData(self, test): |
178 """Saves the Emma coverage data before it's overwritten by the next test. | 185 """Saves the Emma coverage data before it's overwritten by the next test. |
179 | 186 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 def _GetInstrumentationArgs(self): | 237 def _GetInstrumentationArgs(self): |
231 ret = {} | 238 ret = {} |
232 if self.coverage: | 239 if self.coverage: |
233 ret['coverage'] = 'true' | 240 ret['coverage'] = 'true' |
234 if self.wait_for_debugger: | 241 if self.wait_for_debugger: |
235 ret['debug'] = 'true' | 242 ret['debug'] = 'true' |
236 return ret | 243 return ret |
237 | 244 |
238 def _TakeScreenshot(self, test): | 245 def _TakeScreenshot(self, test): |
239 """Takes a screenshot from the device.""" | 246 """Takes a screenshot from the device.""" |
240 screenshot_tool = os.path.join(os.getenv('ANDROID_HOST_OUT'), 'bin', | 247 screenshot_tool = os.path.join(constants.CHROME_DIR, |
bulach
2012/09/24 10:40:49
don't quite understand this diff, you probably nee
felipeg
2012/09/25 03:27:21
yep, sorry
It was some confusion in my git client
| |
241 'screenshot2') | 248 'third_party/android_tools/sdk/tools/monkeyrunner') |
249 screenshot_script = os.path.join(constants.CHROME_DIR, | |
250 'build/android/monkeyrunner_screenshot.py') | |
242 screenshot_path = os.path.join(constants.CHROME_DIR, | 251 screenshot_path = os.path.join(constants.CHROME_DIR, |
243 'out_screenshots') | 252 'out_screenshots') |
244 if not os.path.exists(screenshot_path): | 253 if not os.path.exists(screenshot_path): |
245 os.mkdir(screenshot_path) | 254 os.mkdir(screenshot_path) |
246 screenshot_name = os.path.join(screenshot_path, test + '.png') | 255 screenshot_name = os.path.join(screenshot_path, test + '.png') |
247 logging.info('Taking screenshot named %s', screenshot_name) | 256 logging.info('Taking screenshot named %s', screenshot_name) |
248 cmd_helper.RunCmd([screenshot_tool, '-s', self.device, screenshot_name]) | 257 cmd_helper.RunCmd([screenshot_tool, screenshot_script, |
258 '--serial', self.device, | |
259 '--file', screenshot_name]) | |
249 | 260 |
250 def SetUp(self): | 261 def SetUp(self): |
251 """Sets up the test harness and device before all tests are run.""" | 262 """Sets up the test harness and device before all tests are run.""" |
252 super(TestRunner, self).SetUp() | 263 super(TestRunner, self).SetUp() |
253 if not self.adb.IsRootEnabled(): | 264 if not self.adb.IsRootEnabled(): |
254 logging.warning('Unable to enable java asserts for %s, non rooted device', | 265 logging.warning('Unable to enable java asserts for %s, non rooted device', |
255 self.device) | 266 self.device) |
256 else: | 267 else: |
257 if self.adb.SetJavaAssertsEnabled(enable=True): | 268 if self.adb.SetJavaAssertsEnabled(enable=True): |
258 self.adb.Reboot(full_reboot=False) | 269 self.adb.Reboot(full_reboot=False) |
259 | 270 |
260 # We give different default value to launch HTTP server based on shard index | 271 # We give different default value to launch HTTP server based on shard index |
261 # because it may have race condition when multiple processes are trying to | 272 # because it may have race condition when multiple processes are trying to |
262 # launch lighttpd with same port at same time. | 273 # launch lighttpd with same port at same time. |
263 # This line *must* come before the forwarding below, as it nukes all | 274 # This line *must* come before the forwarding below, as it nukes all |
264 # the other forwarders. A more comprehensive fix might be to pull the | 275 # the other forwarders. A more comprehensive fix might be to pull the |
265 # forwarder-killing line up to here, but that might violate assumptions | 276 # forwarder-killing line up to here, but that might violate assumptions |
266 # implicit in other places. | 277 # implicit in other places. |
267 self.LaunchTestHttpServer(os.path.join(constants.CHROME_DIR), | 278 self.LaunchTestHttpServer(os.path.join(constants.CHROME_DIR), |
268 (constants.LIGHTTPD_RANDOM_PORT_FIRST + | 279 (constants.LIGHTTPD_RANDOM_PORT_FIRST + |
269 self.shard_index)) | 280 self.shard_index)) |
270 | 281 print "====================================== " + str(self.ports_to_forward) |
bulach
2012/09/24 10:40:49
spurious?
felipeg
2012/09/25 03:27:21
Done.
| |
282 port_pairs = [] | |
271 if self.ports_to_forward: | 283 if self.ports_to_forward: |
272 for port in self.ports_to_forward: | 284 for port in self.ports_to_forward: |
273 self.forwarders.append(Forwarder( | 285 port_pairs.append([(port, port)]) |
274 self.adb, [(port, port)], self.tool, '127.0.0.1', self.build_type)) | 286 self.forwarder = Forwarder( |
287 self.adb, port_pairs, self.tool, '127.0.0.1', self.build_type) | |
275 self.CopyTestFilesOnce() | 288 self.CopyTestFilesOnce() |
276 self.flags.AddFlags(['--enable-test-intents']) | 289 self.flags.AddFlags(['--enable-test-intents']) |
277 | 290 |
278 def TearDown(self): | 291 def TearDown(self): |
279 """Cleans up the test harness and saves outstanding data from test run.""" | 292 """Cleans up the test harness and saves outstanding data from test run.""" |
280 if self.forwarders: | 293 if self.forwarder: |
281 for forwarder in self.forwarders: | 294 forwarder.Close() |
282 forwarder.Close() | |
283 self.GenerateCoverageReportIfNeeded() | 295 self.GenerateCoverageReportIfNeeded() |
284 super(TestRunner, self).TearDown() | 296 super(TestRunner, self).TearDown() |
285 | 297 |
286 def TestSetup(self, test): | 298 def TestSetup(self, test): |
287 """Sets up the test harness for running a particular test. | 299 """Sets up the test harness for running a particular test. |
288 | 300 |
289 Args: | 301 Args: |
290 test: The name of the test that will be run. | 302 test: The name of the test that will be run. |
291 """ | 303 """ |
292 self.SetupPerfMonitoringIfNeeded(test) | 304 self.SetupPerfMonitoringIfNeeded(test) |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 Args: | 358 Args: |
347 test: The name of the test that was just run. | 359 test: The name of the test that was just run. |
348 Raises: | 360 Raises: |
349 FatalTestException: if there's anything wrong with the perf data. | 361 FatalTestException: if there's anything wrong with the perf data. |
350 """ | 362 """ |
351 if not self._IsPerfTest(test): | 363 if not self._IsPerfTest(test): |
352 return | 364 return |
353 raw_test_name = test.split('#')[1] | 365 raw_test_name = test.split('#')[1] |
354 | 366 |
355 # Wait and grab annotation data so we can figure out which traces to parse | 367 # Wait and grab annotation data so we can figure out which traces to parse |
368 # TODO(tonyg): Is there an error log line to watch for here? | |
bulach
2012/09/24 10:40:49
:)
felipeg
2012/09/25 03:27:21
Done.
| |
356 regex = self.adb.WaitForLogMatch(re.compile('\*\*PERFANNOTATION\(' + | 369 regex = self.adb.WaitForLogMatch(re.compile('\*\*PERFANNOTATION\(' + |
357 raw_test_name + | 370 raw_test_name + |
358 '\)\:(.*)'), None) | 371 '\)\:(.*)'), None) |
359 | 372 |
360 # If the test is set to run on a specific device type only (IE: only | 373 # If the test is set to run on a specific device type only (IE: only |
361 # tablet or phone) and it is being run on the wrong device, the test | 374 # tablet or phone) and it is being run on the wrong device, the test |
362 # just quits and does not do anything. The java test harness will still | 375 # just quits and does not do anything. The java test harness will still |
363 # print the appropriate annotation for us, but will add --NORUN-- for | 376 # print the appropriate annotation for us, but will add --NORUN-- for |
364 # us so we know to ignore the results. | 377 # us so we know to ignore the results. |
365 # The --NORUN-- tag is managed by MainActivityTestBase.java | 378 # The --NORUN-- tag is managed by MainActivityTestBase.java |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 | 590 |
578 logging.info('Will run: %s', str(tests)) | 591 logging.info('Will run: %s', str(tests)) |
579 | 592 |
580 if len(attached_devices) > 1 and (coverage or options.wait_for_debugger): | 593 if len(attached_devices) > 1 and (coverage or options.wait_for_debugger): |
581 logging.warning('Coverage / debugger can not be sharded, ' | 594 logging.warning('Coverage / debugger can not be sharded, ' |
582 'using first available device') | 595 'using first available device') |
583 attached_devices = attached_devices[:1] | 596 attached_devices = attached_devices[:1] |
584 sharder = TestSharder(attached_devices, options, tests, apks) | 597 sharder = TestSharder(attached_devices, options, tests, apks) |
585 test_results = sharder.RunShardedTests() | 598 test_results = sharder.RunShardedTests() |
586 return test_results | 599 return test_results |
OLD | NEW |