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

Side by Side Diff: build/android/pylib/base/shard.py

Issue 12544033: [Android] Rewrite base test result classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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) 2013 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2013 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 """Implements test sharding logic.""" 5 """Implements test sharding logic."""
6 6
7 import logging 7 import logging
8 import threading 8 import threading
9 9
10 from pylib import android_commands 10 from pylib import android_commands
11 from pylib import forwarder 11 from pylib import forwarder
12 from pylib.utils import reraiser_thread 12 from pylib.utils import reraiser_thread
13 13
14 import test_result 14 import base_test_result
15 15
16 16
17 class _ThreadSafeCounter(object): 17 class _ThreadSafeCounter(object):
18 """A threadsafe counter.""" 18 """A threadsafe counter."""
19 def __init__(self): 19 def __init__(self):
20 self._lock = threading.Lock() 20 self._lock = threading.Lock()
21 self._value = 0 21 self._value = 0
22 22
23 def GetAndIncrement(self): 23 def GetAndIncrement(self):
24 """Get the current value and increment it atomically. 24 """Get the current value and increment it atomically.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 while True: 105 while True:
106 r = self._pop() 106 r = self._pop()
107 if r is None: 107 if r is None:
108 break 108 break
109 yield r 109 yield r
110 110
111 111
112 def _RunTestsFromQueue(runner, test_collection, out_results): 112 def _RunTestsFromQueue(runner, test_collection, out_results):
113 """Runs tests from the test_collection until empty using the given runner. 113 """Runs tests from the test_collection until empty using the given runner.
114 114
115 Adds TestResults objects to the out_results list and may add tests to the 115 Adds TestRunResults objects to the out_results list and may add tests to the
116 out_retry list. 116 out_retry list.
117 117
118 Args: 118 Args:
119 runner: A TestRunner object used to run the tests. 119 runner: A TestRunner object used to run the tests.
120 test_collection: A _TestCollection from which to get _Test objects to run. 120 test_collection: A _TestCollection from which to get _Test objects to run.
121 out_results: A list to add TestResults to. 121 out_results: A list to add TestRunResults to.
122 """ 122 """
123 for test in test_collection: 123 for test in test_collection:
124 try: 124 try:
125 if not android_commands.IsDeviceAttached(runner.device): 125 if not android_commands.IsDeviceAttached(runner.device):
126 # Device is unresponsive, stop handling tests on this device. 126 # Device is unresponsive, stop handling tests on this device.
127 msg = 'Device %s is unresponsive.' % runner.device 127 msg = 'Device %s is unresponsive.' % runner.device
128 logging.warning(msg) 128 logging.warning(msg)
129 raise android_commands.errors.DeviceUnresponsiveError(msg) 129 raise android_commands.errors.DeviceUnresponsiveError(msg)
130 result, retry = runner.RunTest(test.test) 130 result, retry = runner.RunTest(test.test)
131 test.tries += 1 131 test.tries += 1
132 if retry and test.tries <= 3: 132 if retry and test.tries <= 3:
133 # Retry non-passing results, only record passing results. 133 # Retry non-passing results, only record passing results.
134 out_results.append(test_result.TestResults.FromRun(ok=result.ok)) 134 pass_results = base_test_result.TestRunResults()
135 pass_results.AddResults(result.GetPass())
136 out_results.append(pass_results)
135 logging.warning('****Will retry test, try #%s.' % test.tries) 137 logging.warning('****Will retry test, try #%s.' % test.tries)
136 test_collection.add(_Test(test=retry, tries=test.tries)) 138 test_collection.add(_Test(test=retry, tries=test.tries))
137 else: 139 else:
138 # All tests passed or retry limit reached. Either way, record results. 140 # All tests passed or retry limit reached. Either way, record results.
139 out_results.append(result) 141 out_results.append(result)
140 except android_commands.errors.DeviceUnresponsiveError: 142 except android_commands.errors.DeviceUnresponsiveError:
141 # Device is unresponsive, stop handling tests on this device and ensure 143 # Device is unresponsive, stop handling tests on this device and ensure
142 # current test gets runs by another device. Don't reraise this exception 144 # current test gets runs by another device. Don't reraise this exception
143 # on the main thread. 145 # on the main thread.
144 test_collection.add(test) 146 test_collection.add(test)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 179
178 180
179 def _RunAllTests(runners, tests): 181 def _RunAllTests(runners, tests):
180 """Run all tests using the given TestRunners. 182 """Run all tests using the given TestRunners.
181 183
182 Args: 184 Args:
183 runners: a list of TestRunner objects. 185 runners: a list of TestRunner objects.
184 tests: a list of Tests to run using the given TestRunners. 186 tests: a list of Tests to run using the given TestRunners.
185 187
186 Returns: 188 Returns:
187 A TestResults object. 189 A TestRunResults object.
188 """ 190 """
189 logging.warning('****Running %s tests with %s test runners.' % 191 logging.warning('****Running %s tests with %s test runners.' %
190 (len(tests), len(runners))) 192 (len(tests), len(runners)))
191 tests_collection = _TestCollection([_Test(t) for t in tests]) 193 tests_collection = _TestCollection([_Test(t) for t in tests])
192 results = [] 194 results = []
193 workers = reraiser_thread.ReraiserThreadGroup([reraiser_thread.ReraiserThread( 195 workers = reraiser_thread.ReraiserThreadGroup([reraiser_thread.ReraiserThread(
194 _RunTestsFromQueue, [r, tests_collection, results]) for r in runners]) 196 _RunTestsFromQueue, [r, tests_collection, results]) for r in runners])
195 workers.StartAll() 197 workers.StartAll()
196 workers.JoinAll() 198 workers.JoinAll()
197 return test_result.TestResults.FromTestResults(results) 199 run_results = base_test_result.TestRunResults()
200 for r in results:
201 run_results.AddTestRunResults(r)
202 return run_results
198 203
199 204
200 def _CreateRunners(runner_factory, devices): 205 def _CreateRunners(runner_factory, devices):
201 """Creates a test runner for each device and calls SetUp() in parallel. 206 """Creates a test runner for each device and calls SetUp() in parallel.
202 207
203 Note: if a device is unresponsive the corresponding TestRunner will not be 208 Note: if a device is unresponsive the corresponding TestRunner will not be
204 included in the returned list. 209 included in the returned list.
205 210
206 Args: 211 Args:
207 runner_factory: callable that takes a device and index and returns a 212 runner_factory: callable that takes a device and index and returns a
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 """Run all tests on attached devices, retrying tests that don't pass. 244 """Run all tests on attached devices, retrying tests that don't pass.
240 245
241 Args: 246 Args:
242 runner_factory: callable that takes a device and index and returns a 247 runner_factory: callable that takes a device and index and returns a
243 TestRunner object. 248 TestRunner object.
244 devices: list of attached device serial numbers as strings. 249 devices: list of attached device serial numbers as strings.
245 tests: list of tests to run. 250 tests: list of tests to run.
246 build_type: either 'Debug' or 'Release'. 251 build_type: either 'Debug' or 'Release'.
247 252
248 Returns: 253 Returns:
249 A test_result.TestResults object. 254 A base_test_result.TestRunResults object.
250 """ 255 """
251 forwarder.Forwarder.KillHost(build_type) 256 forwarder.Forwarder.KillHost(build_type)
252 runners = _CreateRunners(runner_factory, devices) 257 runners = _CreateRunners(runner_factory, devices)
253 try: 258 try:
254 return _RunAllTests(runners, tests) 259 return _RunAllTests(runners, tests)
255 finally: 260 finally:
256 try: 261 try:
257 _TearDownRunners(runners) 262 _TearDownRunners(runners)
258 except android_commands.errors.DeviceUnresponsiveError as e: 263 except android_commands.errors.DeviceUnresponsiveError as e:
259 logging.warning('****Device unresponsive during TearDown: [%s]', e) 264 logging.warning('****Device unresponsive during TearDown: [%s]', e)
260 finally: 265 finally:
261 forwarder.Forwarder.KillHost(build_type) 266 forwarder.Forwarder.KillHost(build_type)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698