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

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

Issue 1056733002: Run test tearDowns and clean up temporary directories when a signal is caught. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 5 years, 8 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 | « lib/src/backend/closed_exception.dart ('k') | lib/src/backend/live_test.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
11 import '../frontend/expect.dart'; 11 import '../frontend/expect.dart';
12 import '../utils.dart'; 12 import '../utils.dart';
13 import 'closed_exception.dart';
13 import 'live_test.dart'; 14 import 'live_test.dart';
14 import 'live_test_controller.dart'; 15 import 'live_test_controller.dart';
15 import 'metadata.dart'; 16 import 'metadata.dart';
16 import 'state.dart'; 17 import 'state.dart';
17 import 'suite.dart'; 18 import 'suite.dart';
18 import 'test.dart'; 19 import 'test.dart';
19 20
20 /// A test in this isolate. 21 /// A test in this isolate.
21 class LocalTest implements Test { 22 class LocalTest implements Test {
22 final String name; 23 final String name;
(...skipping 25 matching lines...) Expand all
48 /// The current invoker is accessible within the zone scope of the running test 49 /// The current invoker is accessible within the zone scope of the running test
49 /// using [Invoker.current]. It's used to track asynchronous callbacks and 50 /// using [Invoker.current]. It's used to track asynchronous callbacks and
50 /// report asynchronous errors. 51 /// report asynchronous errors.
51 class Invoker { 52 class Invoker {
52 /// The live test being driven by the invoker. 53 /// The live test being driven by the invoker.
53 /// 54 ///
54 /// This provides a view into the state of the test being executed. 55 /// This provides a view into the state of the test being executed.
55 LiveTest get liveTest => _controller.liveTest; 56 LiveTest get liveTest => _controller.liveTest;
56 LiveTestController _controller; 57 LiveTestController _controller;
57 58
59 /// Whether the test has been closed.
60 ///
61 /// Once the test is closed, [expect] and [expectAsync] will throw
62 /// [ClosedException]s whenever accessed to help the test stop executing as
63 /// soon as possible.
64 bool get closed => _closed;
65 bool _closed = false;
66
58 /// The test being run. 67 /// The test being run.
59 LocalTest get _test => liveTest.test as LocalTest; 68 LocalTest get _test => liveTest.test as LocalTest;
60 69
61 /// Note that this is meaningless once [_onCompleteCompleter] is complete. 70 /// Note that this is meaningless once [_onCompleteCompleter] is complete.
62 var _outstandingCallbacks = 0; 71 var _outstandingCallbacks = 0;
63 72
64 /// The completer to complete once the test body finishes. 73 /// The completer to complete once the test body finishes.
65 /// 74 ///
66 /// This is distinct from [_controller.completer] because a tear-down may need 75 /// This is distinct from [_controller.completer] because a tear-down may need
67 /// to run before the test is truly finished. 76 /// to run before the test is truly finished.
68 final _completer = new Completer(); 77 final _completer = new Completer();
69 78
70 /// The current invoker, or `null` if none is defined. 79 /// The current invoker, or `null` if none is defined.
71 /// 80 ///
72 /// An invoker is only set within the zone scope of a running test. 81 /// An invoker is only set within the zone scope of a running test.
73 static Invoker get current { 82 static Invoker get current {
74 // TODO(nweiz): Use a private symbol when dart2js supports it (issue 17526). 83 // TODO(nweiz): Use a private symbol when dart2js supports it (issue 17526).
75 return Zone.current[#test.invoker]; 84 return Zone.current[#test.invoker];
76 } 85 }
77 86
78 Invoker._(Suite suite, LocalTest test) { 87 Invoker._(Suite suite, LocalTest test) {
79 _controller = new LiveTestController(suite, test, _onRun); 88 _controller = new LiveTestController(suite, test, _onRun, () {
89 _closed = true;
90 });
80 } 91 }
81 92
82 /// Tells the invoker that there's a callback running that it should wait for 93 /// Tells the invoker that there's a callback running that it should wait for
83 /// before considering the test successful. 94 /// before considering the test successful.
84 /// 95 ///
85 /// Each call to [addOutstandingCallback] should be followed by a call to 96 /// Each call to [addOutstandingCallback] should be followed by a call to
86 /// [removeOutstandingCallback] once the callbak is no longer running. Note 97 /// [removeOutstandingCallback] once the callbak is no longer running. Note
87 /// that only successful tests wait for outstanding callbacks; as soon as a 98 /// that only successful tests wait for outstanding callbacks; as soon as a
88 /// test experiences an error, any further calls to [addOutstandingCallback] 99 /// test experiences an error, any further calls to [addOutstandingCallback]
89 /// or [removeOutstandingCallback] will do nothing. 100 /// or [removeOutstandingCallback] will do nothing.
101 ///
102 /// Throws a [ClosedException] if this test has been closed.
90 void addOutstandingCallback() { 103 void addOutstandingCallback() {
104 if (closed) throw new ClosedException();
91 _outstandingCallbacks++; 105 _outstandingCallbacks++;
92 } 106 }
93 107
94 /// Tells the invoker that a callback declared with [addOutstandingCallback] 108 /// Tells the invoker that a callback declared with [addOutstandingCallback]
95 /// is no longer running. 109 /// is no longer running.
96 void removeOutstandingCallback() { 110 void removeOutstandingCallback() {
97 _outstandingCallbacks--; 111 _outstandingCallbacks--;
98 112
99 if (_outstandingCallbacks != 0) return; 113 if (_outstandingCallbacks != 0) return;
100 if (_completer.isCompleted) return; 114 if (_completer.isCompleted) return;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 addOutstandingCallback(); 169 addOutstandingCallback();
156 170
157 // Run the test asynchronously so that the "running" state change has a 171 // Run the test asynchronously so that the "running" state change has a
158 // chance to hit its event handler(s) before the test produces an error. 172 // chance to hit its event handler(s) before the test produces an error.
159 // If an error is emitted before the first state change is handled, we 173 // If an error is emitted before the first state change is handled, we
160 // can end up with [onError] callbacks firing before the corresponding 174 // can end up with [onError] callbacks firing before the corresponding
161 // [onStateChange], which violates the timing guarantees. 175 // [onStateChange], which violates the timing guarantees.
162 new Future(_test._body) 176 new Future(_test._body)
163 .then((_) => removeOutstandingCallback()); 177 .then((_) => removeOutstandingCallback());
164 178
165 // Explicitly handle an error here so that we can return the [Future].
166 // If a [Future] returned from an error zone would throw an error
167 // through the zone boundary, it instead never completes, and we want to
168 // avoid that.
169 _completer.future.then((_) { 179 _completer.future.then((_) {
170 if (_test._tearDown == null) return null; 180 if (_test._tearDown == null) return null;
171 return new Future.sync(_test._tearDown); 181 return new Future.sync(_test._tearDown);
172 }).catchError(Zone.current.handleUncaughtError).then((_) { 182 }).catchError(Zone.current.handleUncaughtError).then((_) {
173 timer.cancel(); 183 timer.cancel();
174 _controller.setState( 184 _controller.setState(
175 new State(Status.complete, liveTest.state.result)); 185 new State(Status.complete, liveTest.state.result));
176 186
177 // Use [Timer.run] here to avoid starving the DOM or other 187 // Use [Timer.run] here to avoid starving the DOM or other
178 // non-microtask events. 188 // non-microtask events.
179 Timer.run(_controller.completer.complete); 189 Timer.run(_controller.completer.complete);
180 }); 190 });
181 }, 191 },
182 zoneSpecification: new ZoneSpecification( 192 zoneSpecification: new ZoneSpecification(
183 print: (self, parent, zone, line) => _controller.print(line)), 193 print: (self, parent, zone, line) => _controller.print(line)),
184 zoneValues: {#test.invoker: this}, 194 zoneValues: {#test.invoker: this},
185 onError: handleError); 195 onError: handleError);
186 }); 196 });
187 } 197 }
188 } 198 }
OLDNEW
« no previous file with comments | « lib/src/backend/closed_exception.dart ('k') | lib/src/backend/live_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698