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

Side by Side Diff: lib/src/backend/invoker.dart

Issue 1256833003: Add Timeout.none. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Fix invoker_test. Created 5 years, 4 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 | « CHANGELOG.md ('k') | lib/src/backend/metadata.dart » ('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 (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library test.backend.invoker; 5 library test.backend.invoker;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:stack_trace/stack_trace.dart'; 9 import 'package:stack_trace/stack_trace.dart';
10 10
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 } 90 }
91 91
92 /// The current invoker, or `null` if none is defined. 92 /// The current invoker, or `null` if none is defined.
93 /// 93 ///
94 /// An invoker is only set within the zone scope of a running test. 94 /// An invoker is only set within the zone scope of a running test.
95 static Invoker get current { 95 static Invoker get current {
96 // TODO(nweiz): Use a private symbol when dart2js supports it (issue 17526). 96 // TODO(nweiz): Use a private symbol when dart2js supports it (issue 17526).
97 return Zone.current[#test.invoker]; 97 return Zone.current[#test.invoker];
98 } 98 }
99 99
100 /// The zone that the top level of [_test.body] is running in.
101 ///
102 /// Tracking this ensures that [_timeoutTimer] isn't created in a
103 /// timer-mocking zone created by the test.
104 Zone _invokerZone;
105
100 /// The timer for tracking timeouts. 106 /// The timer for tracking timeouts.
101 /// 107 ///
102 /// This will be `null` until the test starts running. 108 /// This will be `null` until the test starts running.
103 Timer _timeoutTimer; 109 Timer _timeoutTimer;
104 110
105 Invoker._(Suite suite, LocalTest test) 111 Invoker._(Suite suite, LocalTest test)
106 : metadata = suite.metadata.merge(test.metadata) { 112 : metadata = suite.metadata.merge(test.metadata) {
107 _controller = new LiveTestController( 113 _controller = new LiveTestController(
108 suite, test, _onRun, _onCloseCompleter.complete); 114 suite, test, _onRun, _onCloseCompleter.complete);
109 } 115 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 170
165 /// Notifies the invoker that progress is being made. 171 /// Notifies the invoker that progress is being made.
166 /// 172 ///
167 /// Each heartbeat resets the timeout timer. This helps ensure that 173 /// Each heartbeat resets the timeout timer. This helps ensure that
168 /// long-running tests that still make progress don't time out. 174 /// long-running tests that still make progress don't time out.
169 void heartbeat() { 175 void heartbeat() {
170 if (liveTest.isComplete) return; 176 if (liveTest.isComplete) return;
171 if (_timeoutTimer != null) _timeoutTimer.cancel(); 177 if (_timeoutTimer != null) _timeoutTimer.cancel();
172 178
173 var timeout = metadata.timeout.apply(new Duration(seconds: 30)); 179 var timeout = metadata.timeout.apply(new Duration(seconds: 30));
174 _timeoutTimer = new Timer(timeout, () { 180 if (timeout == null) return;
181 _timeoutTimer = _invokerZone.createTimer(timeout,
182 Zone.current.bindCallback(() {
175 if (liveTest.isComplete) return; 183 if (liveTest.isComplete) return;
176 _handleError( 184 _handleError(
177 new TimeoutException( 185 new TimeoutException(
178 "Test timed out after ${niceDuration(timeout)}.", timeout)); 186 "Test timed out after ${niceDuration(timeout)}.", timeout));
179 }); 187 }));
180 } 188 }
181 189
182 /// Notifies the invoker of an asynchronous error. 190 /// Notifies the invoker of an asynchronous error.
183 void _handleError(error, [StackTrace stackTrace]) { 191 void _handleError(error, [StackTrace stackTrace]) {
184 if (stackTrace == null) stackTrace = new Chain.current(); 192 if (stackTrace == null) stackTrace = new Chain.current();
185 193
186 var afterSuccess = liveTest.isComplete && 194 var afterSuccess = liveTest.isComplete &&
187 liveTest.state.result == Result.success; 195 liveTest.state.result == Result.success;
188 196
189 if (error is! TestFailure) { 197 if (error is! TestFailure) {
(...skipping 18 matching lines...) Expand all
208 /// The method that's run when the test is started. 216 /// The method that's run when the test is started.
209 void _onRun() { 217 void _onRun() {
210 _controller.setState(const State(Status.running, Result.success)); 218 _controller.setState(const State(Status.running, Result.success));
211 219
212 var outstandingCallbacksForBody = new OutstandingCallbackCounter(); 220 var outstandingCallbacksForBody = new OutstandingCallbackCounter();
213 221
214 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in two 222 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in two
215 // stable versions. 223 // stable versions.
216 Chain.capture(() { 224 Chain.capture(() {
217 runZonedWithValues(() { 225 runZonedWithValues(() {
226 _invokerZone = Zone.current;
227
218 heartbeat(); 228 heartbeat();
219 229
220 // Run the test asynchronously so that the "running" state change has 230 // Run the test asynchronously so that the "running" state change has
221 // a chance to hit its event handler(s) before the test produces an 231 // a chance to hit its event handler(s) before the test produces an
222 // error. If an error is emitted before the first state change is 232 // error. If an error is emitted before the first state change is
223 // handled, we can end up with [onError] callbacks firing before the 233 // handled, we can end up with [onError] callbacks firing before the
224 // corresponding [onStateChange], which violates the timing 234 // corresponding [onStateChange], which violates the timing
225 // guarantees. 235 // guarantees.
226 new Future(_test._body) 236 new Future(_test._body)
227 .then((_) => removeOutstandingCallback()); 237 .then((_) => removeOutstandingCallback());
228 238
229 _outstandingCallbacks.noOutstandingCallbacks.then((_) { 239 _outstandingCallbacks.noOutstandingCallbacks.then((_) {
230 if (_test._tearDown == null) return null; 240 if (_test._tearDown == null) return null;
231 241
232 // Reset the outstanding callback counter to wait for callbacks from 242 // Reset the outstanding callback counter to wait for callbacks from
233 // the test's `tearDown` to complete. 243 // the test's `tearDown` to complete.
234 return waitForOutstandingCallbacks(() => 244 return waitForOutstandingCallbacks(() =>
235 runZoned(_test._tearDown, onError: _handleError)); 245 runZoned(_test._tearDown, onError: _handleError));
236 }).then((_) { 246 }).then((_) {
237 _timeoutTimer.cancel(); 247 if (_timeoutTimer != null) _timeoutTimer.cancel();
238 _controller.setState( 248 _controller.setState(
239 new State(Status.complete, liveTest.state.result)); 249 new State(Status.complete, liveTest.state.result));
240 250
241 // Use [Timer.run] here to avoid starving the DOM or other 251 // Use [Timer.run] here to avoid starving the DOM or other
242 // non-microtask events. 252 // non-microtask events.
243 Timer.run(_controller.completer.complete); 253 Timer.run(_controller.completer.complete);
244 }); 254 });
245 }, zoneValues: { 255 }, zoneValues: {
246 #test.invoker: this, 256 #test.invoker: this,
247 // Use the invoker as a key so that multiple invokers can have different 257 // Use the invoker as a key so that multiple invokers can have different
248 // outstanding callback counters at once. 258 // outstanding callback counters at once.
249 this: outstandingCallbacksForBody 259 this: outstandingCallbacksForBody
250 }, 260 },
251 zoneSpecification: new ZoneSpecification( 261 zoneSpecification: new ZoneSpecification(
252 print: (self, parent, zone, line) => _controller.print(line)), 262 print: (self, parent, zone, line) => _controller.print(line)),
253 onError: _handleError); 263 onError: _handleError);
254 }); 264 });
255 } 265 }
256 } 266 }
OLDNEW
« no previous file with comments | « CHANGELOG.md ('k') | lib/src/backend/metadata.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698