Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1772)

Side by Side Diff: build/android/pylib/local/device/local_device_gtest_run.py

Issue 2362143002: [Android] Add experimental gtest xml result handling. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/android/pylib/gtest/gtest_test_instance.py ('k') | build/android/test_runner.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 flags = self._test_instance.test_arguments or ''
345 test, device, flags=self._test_instance.test_arguments, 352 with tempfile.NamedTemporaryFile(suffix='.xml') as host_tmp_results_file:
346 timeout=timeout, retries=0) 353 with device_temp_file.DeviceTempFile(
347 for s in self._servers[str(device)]: 354 adb=device.adb,
348 s.Reset() 355 dir=self._delegate.ResultsDirectory(device),
349 if self._test_instance.app_files: 356 suffix='.xml') as device_tmp_results_file:
350 self._delegate.PullAppFiles(device, self._test_instance.app_files, 357 flags += ' --gtest_output=xml:%s' % device_tmp_results_file.name
rnephew (Reviews Here) 2016/09/23 14:10:51 Do we want this always on, or should we check for
jbudorick 2016/09/23 15:23:02 It works w/ the flag off, but it's unnecessary. I'
351 self._test_instance.app_file_dir) 358 output = self._delegate.Run(
352 if not self._env.skip_clear_data: 359 test, device, flags=flags,
353 self._delegate.Clear(device) 360 timeout=timeout, retries=0)
361 device.PullFile(
362 device_tmp_results_file.name,
363 host_tmp_results_file.name)
354 364
355 # Parse the output. 365 for s in self._servers[str(device)]:
356 # TODO(jbudorick): Transition test scripts away from parsing stdout. 366 s.Reset()
357 results = gtest_test_instance.ParseGTestOutput(output) 367 if self._test_instance.app_files:
368 self._delegate.PullAppFiles(device, self._test_instance.app_files,
369 self._test_instance.app_file_dir)
370 if not self._env.skip_clear_data:
371 self._delegate.Clear(device)
372
373 # Parse the output.
374 # TODO(jbudorick): Transition test scripts away from parsing stdout.
375 if self._test_instance.enable_xml_result_parsing:
376 with open(host_tmp_results_file.name) as xml_results_file:
377 results = gtest_test_instance.ParseGTestXML(xml_results_file.read())
378 else:
379 results = gtest_test_instance.ParseGTestOutput(output)
358 380
359 # Check whether there are any crashed testcases. 381 # Check whether there are any crashed testcases.
360 self._crashes.update(r.GetName() for r in results 382 self._crashes.update(r.GetName() for r in results
361 if r.GetType() == base_test_result.ResultType.CRASH) 383 if r.GetType() == base_test_result.ResultType.CRASH)
362 return results 384 return results
363 385
364 #override 386 #override
365 def TearDown(self): 387 def TearDown(self):
366 @local_device_environment.handle_shard_failures 388 @local_device_environment.handle_shard_failures
367 def individual_device_tear_down(dev): 389 def individual_device_tear_down(dev):
368 for s in self._servers.get(str(dev), []): 390 for s in self._servers.get(str(dev), []):
369 s.TearDown() 391 s.TearDown()
370 392
371 tool = self.GetTool(dev) 393 tool = self.GetTool(dev)
372 tool.CleanUpEnvironment() 394 tool.CleanUpEnvironment()
373 395
374 self._env.parallel_devices.pMap(individual_device_tear_down) 396 self._env.parallel_devices.pMap(individual_device_tear_down)
OLDNEW
« no previous file with comments | « build/android/pylib/gtest/gtest_test_instance.py ('k') | build/android/test_runner.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698