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 collections | 5 import collections |
6 import itertools | 6 import itertools |
7 import logging | 7 import logging |
8 import os | 8 import os |
9 import posixpath | 9 import posixpath |
| 10 import tempfile |
10 | 11 |
11 from devil.android import device_errors | 12 from devil.android import device_errors |
12 from devil.android import device_temp_file | 13 from devil.android import device_temp_file |
13 from devil.android import ports | 14 from devil.android import ports |
14 from devil.utils import reraiser_thread | 15 from devil.utils import reraiser_thread |
15 from pylib import constants | 16 from pylib import constants |
16 from pylib.base import base_test_result | 17 from pylib.base import base_test_result |
17 from pylib.gtest import gtest_test_instance | 18 from pylib.gtest import gtest_test_instance |
18 from pylib.local import local_test_server_spawner | 19 from pylib.local import local_test_server_spawner |
19 from pylib.local.device import local_device_environment | 20 from pylib.local.device import local_device_environment |
20 from pylib.local.device import local_device_test_run | 21 from pylib.local.device import local_device_test_run |
21 | 22 |
22 _COMMAND_LINE_FLAGS_SUPPORTED = True | |
23 | |
24 _MAX_INLINE_FLAGS_LENGTH = 50 # Arbitrarily chosen. | 23 _MAX_INLINE_FLAGS_LENGTH = 50 # Arbitrarily chosen. |
25 _EXTRA_COMMAND_LINE_FILE = ( | 24 _EXTRA_COMMAND_LINE_FILE = ( |
26 'org.chromium.native_test.NativeTest.CommandLineFile') | 25 'org.chromium.native_test.NativeTest.CommandLineFile') |
27 _EXTRA_COMMAND_LINE_FLAGS = ( | 26 _EXTRA_COMMAND_LINE_FLAGS = ( |
28 'org.chromium.native_test.NativeTest.CommandLineFlags') | 27 'org.chromium.native_test.NativeTest.CommandLineFlags') |
29 _EXTRA_TEST_LIST = ( | 28 _EXTRA_TEST_LIST = ( |
30 'org.chromium.native_test.NativeTestInstrumentationTestRunner' | 29 'org.chromium.native_test.NativeTestInstrumentationTestRunner' |
31 '.TestList') | 30 '.TestList') |
32 _EXTRA_TEST = ( | 31 _EXTRA_TEST = ( |
33 'org.chromium.native_test.NativeTestInstrumentationTestRunner' | 32 'org.chromium.native_test.NativeTestInstrumentationTestRunner' |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 self._extras = test_instance.extras | 108 self._extras = test_instance.extras |
110 | 109 |
111 def Install(self, device): | 110 def Install(self, device): |
112 if self._test_apk_incremental_install_script: | 111 if self._test_apk_incremental_install_script: |
113 local_device_test_run.IncrementalInstall(device, self._apk_helper, | 112 local_device_test_run.IncrementalInstall(device, self._apk_helper, |
114 self._test_apk_incremental_install_script) | 113 self._test_apk_incremental_install_script) |
115 else: | 114 else: |
116 device.Install(self._apk_helper, reinstall=True, | 115 device.Install(self._apk_helper, reinstall=True, |
117 permissions=self._permissions) | 116 permissions=self._permissions) |
118 | 117 |
| 118 def ResultsDirectory(self, device): |
| 119 return device.GetApplicationDataDirectory(self._package) |
| 120 |
119 def Run(self, test, device, flags=None, **kwargs): | 121 def Run(self, test, device, flags=None, **kwargs): |
120 extras = dict(self._extras) | 122 extras = dict(self._extras) |
121 | 123 |
122 if ('timeout' in kwargs | 124 if ('timeout' in kwargs |
123 and gtest_test_instance.EXTRA_SHARD_NANO_TIMEOUT not in extras): | 125 and gtest_test_instance.EXTRA_SHARD_NANO_TIMEOUT not in extras): |
124 # Make sure the instrumentation doesn't kill the test before the | 126 # Make sure the instrumentation doesn't kill the test before the |
125 # scripts do. The provided timeout value is in seconds, but the | 127 # scripts do. The provided timeout value is in seconds, but the |
126 # instrumentation deals with nanoseconds because that's how Android | 128 # instrumentation deals with nanoseconds because that's how Android |
127 # handles time. | 129 # handles time. |
128 extras[gtest_test_instance.EXTRA_SHARD_NANO_TIMEOUT] = int( | 130 extras[gtest_test_instance.EXTRA_SHARD_NANO_TIMEOUT] = int( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 self._device_dist_dir = posixpath.join( | 170 self._device_dist_dir = posixpath.join( |
169 constants.TEST_EXECUTABLE_DIR, os.path.basename(dist_dir)) | 171 constants.TEST_EXECUTABLE_DIR, os.path.basename(dist_dir)) |
170 self._test_run = tr | 172 self._test_run = tr |
171 | 173 |
172 def Install(self, device): | 174 def Install(self, device): |
173 # TODO(jbudorick): Look into merging this with normal data deps pushing if | 175 # TODO(jbudorick): Look into merging this with normal data deps pushing if |
174 # executables become supported on nonlocal environments. | 176 # executables become supported on nonlocal environments. |
175 device.PushChangedFiles([(self._host_dist_dir, self._device_dist_dir)], | 177 device.PushChangedFiles([(self._host_dist_dir, self._device_dist_dir)], |
176 delete_device_stale=True) | 178 delete_device_stale=True) |
177 | 179 |
| 180 def ResultsDirectory(self, device): |
| 181 # pylint: disable=no-self-use |
| 182 # pylint: disable=unused-argument |
| 183 return constants.TEST_EXECUTABLE_DIR |
| 184 |
178 def Run(self, test, device, flags=None, **kwargs): | 185 def Run(self, test, device, flags=None, **kwargs): |
179 tool = self._test_run.GetTool(device).GetTestWrapper() | 186 tool = self._test_run.GetTool(device).GetTestWrapper() |
180 if tool: | 187 if tool: |
181 cmd = [tool] | 188 cmd = [tool] |
182 else: | 189 else: |
183 cmd = [] | 190 cmd = [] |
184 cmd.append(posixpath.join(self._device_dist_dir, self._exe_file_name)) | 191 cmd.append(posixpath.join(self._device_dist_dir, self._exe_file_name)) |
185 | 192 |
186 if test: | 193 if test: |
187 cmd.append('--gtest_filter=%s' % ':'.join(test)) | 194 cmd.append('--gtest_filter=%s' % ':'.join(test)) |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 if all(not tl for tl in test_lists): | 341 if all(not tl for tl in test_lists): |
335 raise device_errors.CommandFailedError( | 342 raise device_errors.CommandFailedError( |
336 'Failed to list tests on any device') | 343 'Failed to list tests on any device') |
337 return list(sorted(set().union(*[set(tl) for tl in test_lists if tl]))) | 344 return list(sorted(set().union(*[set(tl) for tl in test_lists if tl]))) |
338 | 345 |
339 #override | 346 #override |
340 def _RunTest(self, device, test): | 347 def _RunTest(self, device, test): |
341 # Run the test. | 348 # Run the test. |
342 timeout = (self._test_instance.shard_timeout | 349 timeout = (self._test_instance.shard_timeout |
343 * self.GetTool(device).GetTimeoutScale()) | 350 * self.GetTool(device).GetTimeoutScale()) |
344 output = self._delegate.Run( | 351 with tempfile.NamedTemporaryFile(suffix='.xml') as host_tmp_results_file: |
345 test, device, flags=self._test_instance.test_arguments, | 352 with device_temp_file.DeviceTempFile( |
346 timeout=timeout, retries=0) | 353 adb=device.adb, |
347 for s in self._servers[str(device)]: | 354 dir=self._delegate.ResultsDirectory(device), |
348 s.Reset() | 355 suffix='.xml') as device_tmp_results_file: |
349 if self._test_instance.app_files: | |
350 self._delegate.PullAppFiles(device, self._test_instance.app_files, | |
351 self._test_instance.app_file_dir) | |
352 if not self._env.skip_clear_data: | |
353 self._delegate.Clear(device) | |
354 | 356 |
355 # Parse the output. | 357 flags = self._test_instance.test_arguments or '' |
356 # TODO(jbudorick): Transition test scripts away from parsing stdout. | 358 if self._test_instance.enable_xml_result_parsing: |
357 results = gtest_test_instance.ParseGTestOutput(output) | 359 flags += ' --gtest_output=xml:%s' % device_tmp_results_file.name |
| 360 |
| 361 output = self._delegate.Run( |
| 362 test, device, flags=flags, |
| 363 timeout=timeout, retries=0) |
| 364 |
| 365 if self._test_instance.enable_xml_result_parsing: |
| 366 device.PullFile( |
| 367 device_tmp_results_file.name, |
| 368 host_tmp_results_file.name) |
| 369 |
| 370 for s in self._servers[str(device)]: |
| 371 s.Reset() |
| 372 if self._test_instance.app_files: |
| 373 self._delegate.PullAppFiles(device, self._test_instance.app_files, |
| 374 self._test_instance.app_file_dir) |
| 375 if not self._env.skip_clear_data: |
| 376 self._delegate.Clear(device) |
| 377 |
| 378 # Parse the output. |
| 379 # TODO(jbudorick): Transition test scripts away from parsing stdout. |
| 380 if self._test_instance.enable_xml_result_parsing: |
| 381 with open(host_tmp_results_file.name) as xml_results_file: |
| 382 results = gtest_test_instance.ParseGTestXML(xml_results_file.read()) |
| 383 else: |
| 384 results = gtest_test_instance.ParseGTestOutput(output) |
358 | 385 |
359 # Check whether there are any crashed testcases. | 386 # Check whether there are any crashed testcases. |
360 self._crashes.update(r.GetName() for r in results | 387 self._crashes.update(r.GetName() for r in results |
361 if r.GetType() == base_test_result.ResultType.CRASH) | 388 if r.GetType() == base_test_result.ResultType.CRASH) |
362 return results | 389 return results |
363 | 390 |
364 #override | 391 #override |
365 def TearDown(self): | 392 def TearDown(self): |
366 @local_device_environment.handle_shard_failures | 393 @local_device_environment.handle_shard_failures |
367 def individual_device_tear_down(dev): | 394 def individual_device_tear_down(dev): |
368 for s in self._servers.get(str(dev), []): | 395 for s in self._servers.get(str(dev), []): |
369 s.TearDown() | 396 s.TearDown() |
370 | 397 |
371 tool = self.GetTool(dev) | 398 tool = self.GetTool(dev) |
372 tool.CleanUpEnvironment() | 399 tool.CleanUpEnvironment() |
373 | 400 |
374 self._env.parallel_devices.pMap(individual_device_tear_down) | 401 self._env.parallel_devices.pMap(individual_device_tear_down) |
OLD | NEW |