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

Side by Side Diff: build/android/pylib/gtest/test_runner.py

Issue 18258012: [Android] Some clean up around gtest packages. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
OLDNEW
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 import logging 5 import logging
6 import os 6 import os
7 import re
7 8
8 from pylib import android_commands 9 from pylib import android_commands
9 from pylib import constants 10 from pylib import constants
10 from pylib.android_commands import errors 11 from pylib import pexpect
11 from pylib.base import base_test_result 12 from pylib.base import base_test_result
12 from pylib.base import base_test_runner 13 from pylib.base import base_test_runner
13 from pylib.utils import run_tests_helper 14 from pylib.utils import run_tests_helper
14 15
15 import test_package_apk 16 import test_package_apk
16 import test_package_executable 17 import test_package_exe
17 18
18 19
19 # We're moving to using isolate files instead of harcoding 20 # We're moving to using isolate files instead of harcoding
20 # dependencies here. Look at the TODO in dispatch.py. 21 # dependencies here. Look at the TODO in dispatch.py.
21 def _GetDataFilesForTestSuite(test_suite_basename): 22 def _GetDataFilesForTestSuite(test_suite_basename):
22 """Returns a list of data files/dirs needed by the test suite. 23 """Returns a list of data files/dirs needed by the test suite.
23 24
24 Args: 25 Args:
25 test_suite_basename: The test suite basename (e.g. base_unittests). 26 test_suite_basename: The test suite basename (e.g. base_unittests).
26 27
(...skipping 14 matching lines...) Expand all
41 def _TestSuiteRequiresMockTestServer(test_suite_basename): 42 def _TestSuiteRequiresMockTestServer(test_suite_basename):
42 """Returns True if the test suite requires mock test server.""" 43 """Returns True if the test suite requires mock test server."""
43 tests_require_net_test_server = ['unit_tests', 'net_unittests', 44 tests_require_net_test_server = ['unit_tests', 'net_unittests',
44 'content_unittests', 45 'content_unittests',
45 'content_browsertests'] 46 'content_browsertests']
46 return (test_suite_basename in 47 return (test_suite_basename in
47 tests_require_net_test_server) 48 tests_require_net_test_server)
48 49
49 50
50 class TestRunner(base_test_runner.BaseTestRunner): 51 class TestRunner(base_test_runner.BaseTestRunner):
51 """Single test suite attached to a single device.
52
53 Args:
54 device: Device to run the tests.
55 test_suite: A specific test suite to run, empty to run all.
56 test_arguments: Additional arguments to pass to the test binary.
57 timeout: Timeout for each test.
58 cleanup_test_files: Whether or not to cleanup test files on device.
59 tool_name: Name of the Valgrind tool.
60 build_type: 'Release' or 'Debug'.
61 in_webkit_checkout: Whether the suite is being run from a WebKit checkout.
62 push_deps: If True, push all dependencies to the device.
63 test_apk_package_name: Apk package name for tests running in APKs.
64 test_activity_name: Test activity to invoke for APK tests.
65 command_line_file: Filename to use to pass arguments to tests.
66 deps_dir: The path to the dependency dir on the host to push to the device.
67 """
68
69 def __init__(self, device, test_suite, test_arguments, timeout, 52 def __init__(self, device, test_suite, test_arguments, timeout,
70 cleanup_test_files, tool_name, build_type, 53 cleanup_test_files, tool_name, build_type,
71 in_webkit_checkout, push_deps, test_apk_package_name=None, 54 in_webkit_checkout, push_deps, test_apk_package_name=None,
72 test_activity_name=None, command_line_file=None, deps_dir=None): 55 test_activity_name=None, command_line_file=None, deps_dir=None):
73 super(TestRunner, self).__init__(device, tool_name, build_type, push_deps) 56 """Single test suite attached to a single device.
57
58 Args:
59 device: Device to run the tests.
60 test_suite: A specific test suite to run, empty to run all.
61 test_arguments: Additional arguments to pass to the test binary.
62 timeout: Timeout for each test.
63 cleanup_test_files: Whether or not to cleanup test files on device.
64 tool_name: Name of the Valgrind tool.
65 build_type: 'Release' or 'Debug'.
66 in_webkit_checkout: Whether the suite is being run from a WebKit checkout.
67 push_deps: If True, push all dependencies to the device.
68 test_apk_package_name: Apk package name for tests running in APKs.
69 test_activity_name: Test activity to invoke for APK tests.
70 command_line_file: Filename to use to pass arguments to tests.
71 deps_dir: The path to the dependency dir to push to the device.
72 """
73 super(TestRunner, self).__init__(device, tool_name, build_type, push_deps,
74 cleanup_test_files)
74 self._running_on_emulator = self.device.startswith('emulator') 75 self._running_on_emulator = self.device.startswith('emulator')
75 self._test_arguments = test_arguments 76 self._test_arguments = test_arguments
76 self.in_webkit_checkout = in_webkit_checkout 77 self.in_webkit_checkout = in_webkit_checkout
77 self._cleanup_test_files = cleanup_test_files
78 self._deps_dir = deps_dir 78 self._deps_dir = deps_dir
79 if timeout == 0:
80 timeout = 60
81 # On a VM (e.g. chromium buildbots), this timeout is way too small.
82 if os.environ.get('BUILDBOT_SLAVENAME'):
83 timeout = timeout * 2
84 self.timeout = timeout * self.tool.GetTimeoutScale()
79 85
80 logging.warning('Test suite: ' + test_suite) 86 logging.warning('Test suite: ' + test_suite)
81 if os.path.splitext(test_suite)[1] == '.apk': 87 if os.path.splitext(test_suite)[1] == '.apk':
82 self.test_package = test_package_apk.TestPackageApk( 88 self.test_package = test_package_apk.TestPackageApk(
83 self.adb, 89 self.adb,
84 device, 90 device,
85 test_suite, 91 test_suite,
86 timeout,
87 self._cleanup_test_files,
88 self.tool, 92 self.tool,
89 test_apk_package_name, 93 test_apk_package_name,
90 test_activity_name, 94 test_activity_name,
91 command_line_file) 95 command_line_file)
92 else: 96 else:
93 # Put a copy into the android out/target directory, to allow stack trace 97 # Put a copy into the android out/target directory, to allow stack trace
94 # generation. 98 # generation.
95 symbols_dir = os.path.join(constants.DIR_SOURCE_ROOT, 'out', build_type, 99 symbols_dir = os.path.join(constants.DIR_SOURCE_ROOT, 'out', build_type,
96 'lib.target') 100 'lib.target')
97 self.test_package = test_package_executable.TestPackageExecutable( 101 self.test_package = test_package_exe.TestPackageExecutable(
98 self.adb, 102 self.adb,
99 device, 103 device,
100 test_suite, 104 test_suite,
101 timeout,
102 self._cleanup_test_files,
103 self.tool, 105 self.tool,
104 symbols_dir) 106 symbols_dir)
105 107
106 #override 108 #override
107 def InstallTestPackage(self): 109 def InstallTestPackage(self):
108 self.test_package.StripAndCopyExecutable() 110 self.test_package.Install()
109 111
110 #override 112 #override
111 def PushDataDeps(self): 113 def PushDataDeps(self):
112 self.adb.WaitForSdCardReady(20) 114 self.adb.WaitForSdCardReady(20)
113 self.tool.CopyFiles() 115 self.tool.CopyFiles()
114 if self.test_package.test_suite_basename == 'webkit_unit_tests': 116 if self.test_package.test_suite_basename == 'webkit_unit_tests':
115 self.PushWebKitUnitTestsData() 117 self.PushWebKitUnitTestsData()
116 return 118 return
117 119
118 if not self._deps_dir: 120 if not self._deps_dir:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 'filter', 169 'filter',
168 self.test_package.test_suite_basename) 170 self.test_package.test_suite_basename)
169 disabled_tests = run_tests_helper.GetExpectations( 171 disabled_tests = run_tests_helper.GetExpectations(
170 gtest_filter_base_path + '_disabled') 172 gtest_filter_base_path + '_disabled')
171 if self._running_on_emulator: 173 if self._running_on_emulator:
172 # Append emulator's filter file. 174 # Append emulator's filter file.
173 disabled_tests.extend(run_tests_helper.GetExpectations( 175 disabled_tests.extend(run_tests_helper.GetExpectations(
174 gtest_filter_base_path + '_emulator_additional_disabled')) 176 gtest_filter_base_path + '_emulator_additional_disabled'))
175 return disabled_tests 177 return disabled_tests
176 178
179 def _ParseTestOutput(self, p):
180 """Process the test output.
181
182 Args:
183 p: An instance of pexpect spawn class.
184
185 Returns:
186 A TestRunResults object.
187 """
188 results = base_test_result.TestRunResults()
189
190 # Test case statuses.
191 re_run = re.compile('\[ RUN \] ?(.*)\r\n')
192 re_fail = re.compile('\[ FAILED \] ?(.*)\r\n')
193 re_ok = re.compile('\[ OK \] ?(.*?) .*\r\n')
194
195 # Test run statuses.
196 re_passed = re.compile('\[ PASSED \] ?(.*)\r\n')
197 re_runner_fail = re.compile('\[ RUNNER_FAILED \] ?(.*)\r\n')
198 # Signal handlers are installed before starting tests
199 # to output the CRASHED marker when a crash happens.
200 re_crash = re.compile('\[ CRASHED \](.*)\r\n')
201
202 log = ''
203 try:
204 while True:
205 full_test_name = None
206 found = p.expect([re_run, re_passed, re_runner_fail],
207 timeout=self.timeout)
208 if found == 1: # re_passed
209 break
210 elif found == 2: # re_runner_fail
211 break
212 else: # re_run
213 full_test_name = p.match.group(1).replace('\r', '')
214 found = p.expect([re_ok, re_fail, re_crash], timeout=self.timeout)
215 log = p.before.replace('\r', '')
216 if found == 0: # re_ok
217 if full_test_name == p.match.group(1).replace('\r', ''):
218 results.AddResult(base_test_result.BaseTestResult(
219 full_test_name, base_test_result.ResultType.PASS,
220 log=log))
221 elif found == 2: # re_crash
222 results.AddResult(base_test_result.BaseTestResult(
223 full_test_name, base_test_result.ResultType.CRASH,
224 log=log))
225 break
226 else: # re_fail
227 results.AddResult(base_test_result.BaseTestResult(
228 full_test_name, base_test_result.ResultType.FAIL, log=log))
229 except pexpect.EOF:
230 logging.error('Test terminated - EOF')
231 # We're here because either the device went offline, or the test harness
232 # crashed without outputting the CRASHED marker (crbug.com/175538).
233 if not self.adb.IsOnline():
234 raise android_commands.errors.DeviceUnresponsiveError(
235 'Device %s went offline.' % self.device)
236 if full_test_name:
237 results.AddResult(base_test_result.BaseTestResult(
238 full_test_name, base_test_result.ResultType.CRASH,
239 log=p.before.replace('\r', '')))
240 except pexpect.TIMEOUT:
241 logging.error('Test terminated after %d second timeout.',
242 self.timeout)
243 if full_test_name:
244 results.AddResult(base_test_result.BaseTestResult(
245 full_test_name, base_test_result.ResultType.TIMEOUT,
246 log=p.before.replace('\r', '')))
247 finally:
248 p.close()
249
250 ret_code = self.test_package.GetGTestReturnCode()
251 if ret_code:
252 logging.critical(
253 'gtest exit code: %d\npexpect.before: %s\npexpect.after: %s',
254 ret_code, p.before, p.after)
255
256 return results
257
177 #override 258 #override
178 def RunTest(self, test): 259 def RunTest(self, test):
179 test_results = base_test_result.TestRunResults() 260 test_results = base_test_result.TestRunResults()
180 if not test: 261 if not test:
181 return test_results, None 262 return test_results, None
182 263
183 try: 264 try:
184 self.test_package.ClearApplicationState() 265 self.test_package.ClearApplicationState()
185 self.test_package.CreateTestRunnerScript(test, self._test_arguments) 266 self.test_package.CreateTestRunnerScript(test, self._test_arguments)
186 test_results = self.test_package.RunTestsAndListResults() 267 test_results = self._ParseTestOutput(self.test_package.SpawnTestProcess())
187 finally: 268 finally:
188 self.CleanupSpawningServerState() 269 self.CleanupSpawningServerState()
189 # Calculate unknown test results. 270 # Calculate unknown test results.
190 all_tests = set(test.split(':')) 271 all_tests = set(test.split(':'))
191 all_tests_ran = set([t.GetName() for t in test_results.GetAll()]) 272 all_tests_ran = set([t.GetName() for t in test_results.GetAll()])
192 unknown_tests = all_tests - all_tests_ran 273 unknown_tests = all_tests - all_tests_ran
193 test_results.AddResults( 274 test_results.AddResults(
194 [base_test_result.BaseTestResult(t, base_test_result.ResultType.UNKNOWN) 275 [base_test_result.BaseTestResult(t, base_test_result.ResultType.UNKNOWN)
195 for t in unknown_tests]) 276 for t in unknown_tests])
196 retry = ':'.join([t.GetName() for t in test_results.GetNotPass()]) 277 retry = ':'.join([t.GetName() for t in test_results.GetNotPass()])
197 return test_results, retry 278 return test_results, retry
198 279
199 #override 280 #override
200 def SetUp(self): 281 def SetUp(self):
201 """Sets up necessary test enviroment for the test suite.""" 282 """Sets up necessary test enviroment for the test suite."""
202 super(TestRunner, self).SetUp() 283 super(TestRunner, self).SetUp()
203 if _TestSuiteRequiresMockTestServer(self.test_package.test_suite_basename): 284 if _TestSuiteRequiresMockTestServer(self.test_package.test_suite_basename):
204 self.LaunchChromeTestServerSpawner() 285 self.LaunchChromeTestServerSpawner()
205 self.tool.SetupEnvironment() 286 self.tool.SetupEnvironment()
206 287
207 #override 288 #override
208 def TearDown(self): 289 def TearDown(self):
209 """Cleans up the test enviroment for the test suite.""" 290 """Cleans up the test enviroment for the test suite."""
210 self.tool.CleanUpEnvironment() 291 self.tool.CleanUpEnvironment()
211 if self._cleanup_test_files:
212 self.adb.RemovePushedFiles()
213 super(TestRunner, self).TearDown() 292 super(TestRunner, self).TearDown()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698