| OLD | NEW |
| 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 | 7 |
| 8 import 'package:async/async.dart' hide Result; | 8 import 'package:async/async.dart' hide Result; |
| 9 import 'package:collection/collection.dart'; | 9 import 'package:collection/collection.dart'; |
| 10 import 'package:pool/pool.dart'; | 10 import 'package:pool/pool.dart'; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 /// A sink used to pass [RunnerSuite]s in to the engine to run. | 88 /// A sink used to pass [RunnerSuite]s in to the engine to run. |
| 89 /// | 89 /// |
| 90 /// Suites may be added as quickly as they're available; the Engine will only | 90 /// Suites may be added as quickly as they're available; the Engine will only |
| 91 /// run as many as necessary at a time based on its concurrency settings. | 91 /// run as many as necessary at a time based on its concurrency settings. |
| 92 /// | 92 /// |
| 93 /// Suites added to the sink will be closed by the engine based on its | 93 /// Suites added to the sink will be closed by the engine based on its |
| 94 /// internal logic. | 94 /// internal logic. |
| 95 Sink<RunnerSuite> get suiteSink => new DelegatingSink(_suiteController.sink); | 95 Sink<RunnerSuite> get suiteSink => new DelegatingSink(_suiteController.sink); |
| 96 final _suiteController = new StreamController<RunnerSuite>(); | 96 final _suiteController = new StreamController<RunnerSuite>(); |
| 97 | 97 |
| 98 /// All the [RunnerSuite]s added to [suiteSink] so far. |
| 99 /// |
| 100 /// Note that if a [LoadSuite] is added, this will only contain that suite, |
| 101 /// not the suite it loads. |
| 102 Set<RunnerSuite> get addedSuites => new UnmodifiableSetView(_addedSuites); |
| 103 final _addedSuites = new Set<RunnerSuite>(); |
| 104 |
| 105 /// A broadcast that emits each [RunnerSuite] as it's added to the engine via |
| 106 /// [suiteSink]. |
| 107 /// |
| 108 /// Note that if a [LoadSuite] is added, this will only return that suite, not |
| 109 /// the suite it loads. |
| 110 /// |
| 111 /// This is guaranteed to fire after the suite is added to [addedSuites]. |
| 112 Stream<RunnerSuite> get onSuiteAdded => _onSuiteAddedController.stream; |
| 113 final _onSuiteAddedController = new StreamController<RunnerSuite>.broadcast(); |
| 114 |
| 98 /// All the currently-known tests that have run, are running, or will run. | 115 /// All the currently-known tests that have run, are running, or will run. |
| 99 /// | 116 /// |
| 100 /// These are [LiveTest]s, representing the in-progress state of each test. | 117 /// These are [LiveTest]s, representing the in-progress state of each test. |
| 101 /// Tests that have not yet begun running are marked [Status.pending]; tests | 118 /// Tests that have not yet begun running are marked [Status.pending]; tests |
| 102 /// that have finished are marked [Status.complete]. | 119 /// that have finished are marked [Status.complete]. |
| 103 /// | 120 /// |
| 104 /// This is guaranteed to contain the same tests as the union of [passed], | 121 /// This is guaranteed to contain the same tests as the union of [passed], |
| 105 /// [skipped], [failed], and [active]. | 122 /// [skipped], [failed], and [active]. |
| 106 /// | 123 /// |
| 107 /// [LiveTest.run] must not be called on these tests. | 124 /// [LiveTest.run] must not be called on these tests. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 /// This returns `true` if all tests succeed, and `false` otherwise. It will | 206 /// This returns `true` if all tests succeed, and `false` otherwise. It will |
| 190 /// only return once all tests have finished running and [suiteSink] has been | 207 /// only return once all tests have finished running and [suiteSink] has been |
| 191 /// closed. | 208 /// closed. |
| 192 Future<bool> run() { | 209 Future<bool> run() { |
| 193 if (_runCalled) { | 210 if (_runCalled) { |
| 194 throw new StateError("Engine.run() may not be called more than once."); | 211 throw new StateError("Engine.run() may not be called more than once."); |
| 195 } | 212 } |
| 196 _runCalled = true; | 213 _runCalled = true; |
| 197 | 214 |
| 198 _suiteController.stream.listen((suite) { | 215 _suiteController.stream.listen((suite) { |
| 216 _addedSuites.add(suite); |
| 217 _onSuiteAddedController.add(suite); |
| 218 |
| 199 _group.add(new Future.sync(() async { | 219 _group.add(new Future.sync(() async { |
| 200 var loadResource = await _loadPool.request(); | 220 var loadResource = await _loadPool.request(); |
| 201 | 221 |
| 202 if (suite is LoadSuite) { | 222 if (suite is LoadSuite) { |
| 203 suite = await _addLoadSuite(suite); | 223 suite = await _addLoadSuite(suite); |
| 204 if (suite == null) { | 224 if (suite == null) { |
| 205 loadResource.release(); | 225 loadResource.release(); |
| 206 return; | 226 return; |
| 207 } | 227 } |
| 208 } | 228 } |
| 209 | 229 |
| 210 await _runPool.withResource(() async { | 230 await _runPool.withResource(() async { |
| 211 if (_closed) return; | 231 if (_closed) return; |
| 212 await _runGroup(suite, suite.group, []); | 232 await _runGroup(suite, suite.group, []); |
| 213 loadResource.allowRelease(() => suite.close()); | 233 loadResource.allowRelease(() => suite.close()); |
| 214 }); | 234 }); |
| 215 })); | 235 })); |
| 216 }, onDone: _group.close); | 236 }, onDone: () { |
| 237 _onSuiteAddedController.close(); |
| 238 _group.close(); |
| 239 }); |
| 217 | 240 |
| 218 return success; | 241 return success; |
| 219 } | 242 } |
| 220 | 243 |
| 221 /// Runs all the entries in [entries] in sequence. | 244 /// Runs all the entries in [entries] in sequence. |
| 222 /// | 245 /// |
| 223 /// [parents] is a list of groups that contain [group]. It may be modified, | 246 /// [parents] is a list of groups that contain [group]. It may be modified, |
| 224 /// but it's guaranteed to be in its original state once this function has | 247 /// but it's guaranteed to be in its original state once this function has |
| 225 /// finished. | 248 /// finished. |
| 226 Future _runGroup(RunnerSuite suite, Group group, List<Group> parents) async { | 249 Future _runGroup(RunnerSuite suite, Group group, List<Group> parents) async { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 /// Any actively-running tests are also closed. VM tests are allowed to finish | 430 /// Any actively-running tests are also closed. VM tests are allowed to finish |
| 408 /// running so that any modifications they've made to the filesystem can be | 431 /// running so that any modifications they've made to the filesystem can be |
| 409 /// cleaned up. | 432 /// cleaned up. |
| 410 /// | 433 /// |
| 411 /// **Note that closing the engine is not the same as closing [suiteSink].** | 434 /// **Note that closing the engine is not the same as closing [suiteSink].** |
| 412 /// Closing [suiteSink] indicates that no more input will be provided, closing | 435 /// Closing [suiteSink] indicates that no more input will be provided, closing |
| 413 /// the engine indicates that no more output should be emitted. | 436 /// the engine indicates that no more output should be emitted. |
| 414 Future close() async { | 437 Future close() async { |
| 415 _closed = true; | 438 _closed = true; |
| 416 if (_closedBeforeDone != null) _closedBeforeDone = true; | 439 if (_closedBeforeDone != null) _closedBeforeDone = true; |
| 440 _onSuiteAddedController.close(); |
| 417 _suiteController.close(); | 441 _suiteController.close(); |
| 418 | 442 |
| 419 // Close the running tests first so that we're sure to wait for them to | 443 // Close the running tests first so that we're sure to wait for them to |
| 420 // finish before we close their suites and cause them to become unloaded. | 444 // finish before we close their suites and cause them to become unloaded. |
| 421 var allLiveTests = liveTests.toSet() | 445 var allLiveTests = liveTests.toSet() |
| 422 ..addAll(_activeLoadTests) | 446 ..addAll(_activeLoadTests) |
| 423 ..addAll(_hidden); | 447 ..addAll(_hidden); |
| 424 var futures = allLiveTests.map((liveTest) => liveTest.close()).toList(); | 448 var futures = allLiveTests.map((liveTest) => liveTest.close()).toList(); |
| 425 | 449 |
| 426 // Closing the load pool will close the test suites as soon as their tests | 450 // Closing the load pool will close the test suites as soon as their tests |
| 427 // are done. For browser suites this is effectively immediate since their | 451 // are done. For browser suites this is effectively immediate since their |
| 428 // tests shut down as soon as they're closed, but for VM suites we may need | 452 // tests shut down as soon as they're closed, but for VM suites we may need |
| 429 // to wait for tearDowns or tearDownAlls to run. | 453 // to wait for tearDowns or tearDownAlls to run. |
| 430 futures.add(_loadPool.close()); | 454 futures.add(_loadPool.close()); |
| 431 await Future.wait(futures, eagerError: true); | 455 await Future.wait(futures, eagerError: true); |
| 432 } | 456 } |
| 433 } | 457 } |
| OLD | NEW |