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

Side by Side Diff: lib/src/runner/engine.dart

Issue 1400743002: Add support for setUpAll and tearDownAll. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Created 5 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 | « lib/src/runner/browser/iframe_listener.dart ('k') | lib/src/runner/loader.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.runner.engine; 5 library test.runner.engine;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:async/async.dart' hide Result; 10 import 'package:async/async.dart' hide Result;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 return success; 208 return success;
209 } 209 }
210 210
211 /// Runs all the entries in [entries] in sequence. 211 /// Runs all the entries in [entries] in sequence.
212 Future _runGroup(RunnerSuite suite, Group group) async { 212 Future _runGroup(RunnerSuite suite, Group group) async {
213 if (group.metadata.skip) { 213 if (group.metadata.skip) {
214 await _runLiveTest(_skippedTest(suite, group)); 214 await _runLiveTest(_skippedTest(suite, group));
215 return; 215 return;
216 } 216 }
217 217
218 for (var entry in group.entries) { 218 var setUpAllSucceeded = true;
219 if (_closed) return; 219 if (group.setUpAll != null) {
220 var liveTest = group.setUpAll.load(suite);
221 await _runLiveTest(liveTest, countSuccess: false);
222 setUpAllSucceeded = liveTest.state.result == Result.success;
223 }
220 224
221 if (entry is Group) { 225 if (!_closed && setUpAllSucceeded) {
222 await _runGroup(suite, entry); 226 for (var entry in group.entries) {
223 } else if (entry.metadata.skip) { 227 if (_closed) return;
224 await _runLiveTest(_skippedTest(suite, entry)); 228
225 } else { 229 if (entry is Group) {
226 var test = entry as Test; 230 await _runGroup(suite, entry);
227 await _runLiveTest(test.load(suite)); 231 } else if (entry.metadata.skip) {
232 await _runLiveTest(_skippedTest(suite, entry));
233 } else {
234 var test = entry as Test;
235 await _runLiveTest(test.load(suite));
236 }
228 } 237 }
229 } 238 }
239
240 // Even if we're closed or setUpAll failed, we want to run all the teardowns
241 // to ensure that any state is properly cleaned up.
242 if (group.tearDownAll != null) {
243 var liveTest = group.tearDownAll.load(suite);
244 await _runLiveTest(liveTest, countSuccess: false);
245 if (_closed) await liveTest.close();
246 }
230 } 247 }
231 248
232 /// Returns a dummy [LiveTest] for a test or group marked as "skip". 249 /// Returns a dummy [LiveTest] for a test or group marked as "skip".
233 LiveTest _skippedTest(RunnerSuite suite, GroupEntry entry) { 250 LiveTest _skippedTest(RunnerSuite suite, GroupEntry entry) {
234 // The netry name will be `null` for the root group. 251 // The netry name will be `null` for the root group.
235 var test = new LocalTest(entry.name ?? "(suite)", entry.metadata, () {}); 252 var test = new LocalTest(entry.name ?? "(suite)", entry.metadata, () {});
236 253
237 var controller; 254 var controller;
238 controller = new LiveTestController(suite, test, () { 255 controller = new LiveTestController(suite, test, () {
239 controller.setState(const State(Status.running, Result.success)); 256 controller.setState(const State(Status.running, Result.success));
240 controller.setState(const State(Status.complete, Result.success)); 257 controller.setState(const State(Status.complete, Result.success));
241 controller.completer.complete(); 258 controller.completer.complete();
242 }, () {}); 259 }, () {});
243 return controller.liveTest; 260 return controller.liveTest;
244 } 261 }
245 262
246 /// Runs [liveTest]. 263 /// Runs [liveTest].
247 Future _runLiveTest(LiveTest liveTest) async { 264 ///
265 /// If [countSuccess] is `true` (the default), the test is put into [passed]
266 /// if it succeeds. Otherwise, it's removed from [liveTests] entirely.
267 Future _runLiveTest(LiveTest liveTest, {bool countSuccess: true}) async {
248 _liveTests.add(liveTest); 268 _liveTests.add(liveTest);
249 _active.add(liveTest); 269 _active.add(liveTest);
250 270
251 // If there were no active non-load tests, the current active test would 271 // If there were no active non-load tests, the current active test would
252 // have been a load test. In that case, remove it, since now we have a 272 // have been a load test. In that case, remove it, since now we have a
253 // non-load test to add. 273 // non-load test to add.
254 if (_active.isNotEmpty && _active.first.suite is LoadSuite) { 274 if (_active.isNotEmpty && _active.first.suite is LoadSuite) {
255 _liveTests.remove(_active.removeFirst()); 275 _liveTests.remove(_active.removeFirst());
256 } 276 }
257 277
258 liveTest.onStateChange.listen((state) { 278 liveTest.onStateChange.listen((state) {
259 if (state.status != Status.complete) return; 279 if (state.status != Status.complete) return;
260 _active.remove(liveTest); 280 _active.remove(liveTest);
261 281
262 // If we're out of non-load tests, surface a load test. 282 // If we're out of non-load tests, surface a load test.
263 if (_active.isEmpty && _activeLoadTests.isNotEmpty) { 283 if (_active.isEmpty && _activeLoadTests.isNotEmpty) {
264 _active.add(_activeLoadTests.first); 284 _active.add(_activeLoadTests.first);
265 _liveTests.add(_activeLoadTests.first); 285 _liveTests.add(_activeLoadTests.first);
266 } 286 }
267 287
268 if (state.result != Result.success) { 288 if (state.result != Result.success) {
269 _passed.remove(liveTest); 289 _passed.remove(liveTest);
270 _failed.add(liveTest); 290 _failed.add(liveTest);
271 } else if (liveTest.test.metadata.skip) { 291 } else if (liveTest.test.metadata.skip) {
272 _skipped.add(liveTest); 292 _skipped.add(liveTest);
293 } else if (countSuccess) {
294 _passed.add(liveTest);
273 } else { 295 } else {
274 _passed.add(liveTest); 296 _liveTests.remove(liveTest);
275 } 297 }
276 }); 298 });
277 299
278 _onTestStartedController.add(liveTest); 300 _onTestStartedController.add(liveTest);
279 301
280 // First, schedule a microtask to ensure that [onTestStarted] fires before 302 // First, schedule a microtask to ensure that [onTestStarted] fires before
281 // the first [LiveTest.onStateChange] event. Once the test finishes, use 303 // the first [LiveTest.onStateChange] event. Once the test finishes, use
282 // [new Future] to do a coarse-grained event loop pump to avoid starving 304 // [new Future] to do a coarse-grained event loop pump to avoid starving
283 // non-microtask events. 305 // non-microtask events.
284 await new Future.microtask(liveTest.run); 306 await new Future.microtask(liveTest.run);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 /// 357 ///
336 /// Any actively-running tests are also closed. VM tests are allowed to finish 358 /// Any actively-running tests are also closed. VM tests are allowed to finish
337 /// running so that any modifications they've made to the filesystem can be 359 /// running so that any modifications they've made to the filesystem can be
338 /// cleaned up. 360 /// cleaned up.
339 /// 361 ///
340 /// **Note that closing the engine is not the same as closing [suiteSink].** 362 /// **Note that closing the engine is not the same as closing [suiteSink].**
341 /// Closing [suiteSink] indicates that no more input will be provided, closing 363 /// Closing [suiteSink] indicates that no more input will be provided, closing
342 /// the engine indicates that no more output should be emitted. 364 /// the engine indicates that no more output should be emitted.
343 Future close() async { 365 Future close() async {
344 _closed = true; 366 _closed = true;
345 if (_closedBeforeDone == null) _closedBeforeDone = true; 367 if (_closedBeforeDone != null) _closedBeforeDone = true;
346 _suiteController.close(); 368 _suiteController.close();
347 369
348 // Close the running tests first so that we're sure to wait for them to 370 // Close the running tests first so that we're sure to wait for them to
349 // finish before we close their suites and cause them to become unloaded. 371 // finish before we close their suites and cause them to become unloaded.
350 var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests); 372 var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests);
351 await Future.wait(allLiveTests.map((liveTest) => liveTest.close())); 373 var futures = allLiveTests.map((liveTest) => liveTest.close()).toList();
352 374
353 var allSuites = allLiveTests.map((liveTest) => liveTest.suite).toSet(); 375 // Closing the load pool will close the test suites as soon as their tests
354 await Future.wait(allSuites.map((suite) => suite.close())); 376 // are done. For browser suites this is effectively immediate since their
377 // tests shut down as soon as they're closed, but for VM suites we may need
378 // to wait for tearDowns or tearDownAlls to run.
379 futures.add(_loadPool.close());
380 await Future.wait(futures, eagerError: true);
355 } 381 }
356 } 382 }
OLDNEW
« no previous file with comments | « lib/src/runner/browser/iframe_listener.dart ('k') | lib/src/runner/loader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698