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 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; |
11 import 'package:collection/collection.dart'; | 11 import 'package:collection/collection.dart'; |
12 import 'package:pool/pool.dart'; | 12 import 'package:pool/pool.dart'; |
13 | 13 |
14 import '../backend/live_test.dart'; | 14 import '../backend/live_test.dart'; |
15 import '../backend/live_test_controller.dart'; | 15 import '../backend/live_test_controller.dart'; |
16 import '../backend/state.dart'; | 16 import '../backend/state.dart'; |
17 import '../backend/suite.dart'; | |
18 import '../backend/test.dart'; | 17 import '../backend/test.dart'; |
19 import 'load_suite.dart'; | 18 import 'load_suite.dart'; |
| 19 import 'runner_suite.dart'; |
20 | 20 |
21 /// An [Engine] manages a run that encompasses multiple test suites. | 21 /// An [Engine] manages a run that encompasses multiple test suites. |
22 /// | 22 /// |
23 /// Test suites are provided by passing them into [suiteSink]. Once all suites | 23 /// Test suites are provided by passing them into [suiteSink]. Once all suites |
24 /// have been provided, the user should close [suiteSink] to indicate this. | 24 /// have been provided, the user should close [suiteSink] to indicate this. |
25 /// [run] won't terminate until [suiteSink] is closed. Suites will be run in the | 25 /// [run] won't terminate until [suiteSink] is closed. Suites will be run in the |
26 /// order they're provided to [suiteSink]. Tests within those suites will | 26 /// order they're provided to [suiteSink]. Tests within those suites will |
27 /// likewise be run in the order of [Suite.tests]. | 27 /// likewise be run in the order of [Suite.tests]. |
28 /// | 28 /// |
29 /// The current status of every test is visible via [liveTests]. [onTestStarted] | 29 /// The current status of every test is visible via [liveTests]. [onTestStarted] |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 Future<bool> get success async { | 77 Future<bool> get success async { |
78 await _group.future; | 78 await _group.future; |
79 if (_closedBeforeDone) return null; | 79 if (_closedBeforeDone) return null; |
80 return liveTests.every((liveTest) => | 80 return liveTests.every((liveTest) => |
81 liveTest.state.result == Result.success); | 81 liveTest.state.result == Result.success); |
82 } | 82 } |
83 | 83 |
84 /// A group of futures for each test suite. | 84 /// A group of futures for each test suite. |
85 final _group = new FutureGroup(); | 85 final _group = new FutureGroup(); |
86 | 86 |
87 /// A sink used to pass [Suite]s in to the engine to run. | 87 /// A sink used to pass [RunnerSuite]s in to the engine to run. |
88 /// | 88 /// |
89 /// Suites may be added as quickly as they're available; the Engine will only | 89 /// Suites may be added as quickly as they're available; the Engine will only |
90 /// run as many as necessary at a time based on its concurrency settings. | 90 /// run as many as necessary at a time based on its concurrency settings. |
91 /// | 91 /// |
92 /// Suites added to the sink will be closed by the engine based on its | 92 /// Suites added to the sink will be closed by the engine based on its |
93 /// internal logic. | 93 /// internal logic. |
94 Sink<Suite> get suiteSink => new DelegatingSink(_suiteController.sink); | 94 Sink<RunnerSuite> get suiteSink => new DelegatingSink(_suiteController.sink); |
95 final _suiteController = new StreamController<Suite>(); | 95 final _suiteController = new StreamController<RunnerSuite>(); |
96 | 96 |
97 /// All the currently-known tests that have run, are running, or will run. | 97 /// All the currently-known tests that have run, are running, or will run. |
98 /// | 98 /// |
99 /// These are [LiveTest]s, representing the in-progress state of each test. | 99 /// These are [LiveTest]s, representing the in-progress state of each test. |
100 /// Tests that have not yet begun running are marked [Status.pending]; tests | 100 /// Tests that have not yet begun running are marked [Status.pending]; tests |
101 /// that have finished are marked [Status.complete]. | 101 /// that have finished are marked [Status.complete]. |
102 /// | 102 /// |
103 /// This is guaranteed to contain the same tests as the union of [passed], | 103 /// This is guaranteed to contain the same tests as the union of [passed], |
104 /// [skipped], [failed], and [active]. | 104 /// [skipped], [failed], and [active]. |
105 /// | 105 /// |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 }).catchError((_) { | 157 }).catchError((_) { |
158 // Don't top-level errors. They'll be thrown via [success] anyway. | 158 // Don't top-level errors. They'll be thrown via [success] anyway. |
159 }); | 159 }); |
160 } | 160 } |
161 | 161 |
162 /// Creates an [Engine] that will run all tests in [suites]. | 162 /// Creates an [Engine] that will run all tests in [suites]. |
163 /// | 163 /// |
164 /// [concurrency] controls how many suites are run at once. An engine | 164 /// [concurrency] controls how many suites are run at once. An engine |
165 /// constructed this way will automatically close its [suiteSink], meaning | 165 /// constructed this way will automatically close its [suiteSink], meaning |
166 /// that no further suites may be provided. | 166 /// that no further suites may be provided. |
167 factory Engine.withSuites(List<Suite> suites, {int concurrency}) { | 167 factory Engine.withSuites(List<RunnerSuite> suites, {int concurrency}) { |
168 var engine = new Engine(concurrency: concurrency); | 168 var engine = new Engine(concurrency: concurrency); |
169 for (var suite in suites) engine.suiteSink.add(suite); | 169 for (var suite in suites) engine.suiteSink.add(suite); |
170 engine.suiteSink.close(); | 170 engine.suiteSink.close(); |
171 return engine; | 171 return engine; |
172 } | 172 } |
173 | 173 |
174 /// Runs all tests in all suites defined by this engine. | 174 /// Runs all tests in all suites defined by this engine. |
175 /// | 175 /// |
176 /// This returns `true` if all tests succeed, and `false` otherwise. It will | 176 /// This returns `true` if all tests succeed, and `false` otherwise. It will |
177 /// only return once all tests have finished running and [suiteSink] has been | 177 /// only return once all tests have finished running and [suiteSink] has been |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 246 |
247 loadResource.allowRelease(() => suite.close()); | 247 loadResource.allowRelease(() => suite.close()); |
248 }); | 248 }); |
249 })); | 249 })); |
250 }, onDone: _group.close); | 250 }, onDone: _group.close); |
251 | 251 |
252 return success; | 252 return success; |
253 } | 253 } |
254 | 254 |
255 /// Returns a dummy [LiveTest] for a test marked as "skip". | 255 /// Returns a dummy [LiveTest] for a test marked as "skip". |
256 LiveTest _skippedTest(Suite suite, Test test) { | 256 LiveTest _skippedTest(RunnerSuite suite, Test test) { |
257 var controller; | 257 var controller; |
258 controller = new LiveTestController(suite, test, () { | 258 controller = new LiveTestController(suite, test, () { |
259 controller.setState(const State(Status.running, Result.success)); | 259 controller.setState(const State(Status.running, Result.success)); |
260 controller.setState(const State(Status.complete, Result.success)); | 260 controller.setState(const State(Status.complete, Result.success)); |
261 controller.completer.complete(); | 261 controller.completer.complete(); |
262 }, () {}); | 262 }, () {}); |
263 return controller.liveTest; | 263 return controller.liveTest; |
264 } | 264 } |
265 | 265 |
266 /// Adds listeners for [suite]. | 266 /// Adds listeners for [suite]. |
267 /// | 267 /// |
268 /// Load suites have specific logic apart from normal test suites. | 268 /// Load suites have specific logic apart from normal test suites. |
269 Future<Suite> _addLoadSuite(LoadSuite suite) async { | 269 Future<RunnerSuite> _addLoadSuite(LoadSuite suite) async { |
270 var liveTest = await suite.tests.single.load(suite); | 270 var liveTest = await suite.tests.single.load(suite); |
271 | 271 |
272 _activeLoadTests.add(liveTest); | 272 _activeLoadTests.add(liveTest); |
273 | 273 |
274 // Only surface the load test if there are no other tests currently running. | 274 // Only surface the load test if there are no other tests currently running. |
275 if (_active.isEmpty) { | 275 if (_active.isEmpty) { |
276 _liveTests.add(liveTest); | 276 _liveTests.add(liveTest); |
277 _active.add(liveTest); | 277 _active.add(liveTest); |
278 } | 278 } |
279 | 279 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 325 |
326 // Close the running tests first so that we're sure to wait for them to | 326 // Close the running tests first so that we're sure to wait for them to |
327 // finish before we close their suites and cause them to become unloaded. | 327 // finish before we close their suites and cause them to become unloaded. |
328 var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests); | 328 var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests); |
329 await Future.wait(allLiveTests.map((liveTest) => liveTest.close())); | 329 await Future.wait(allLiveTests.map((liveTest) => liveTest.close())); |
330 | 330 |
331 var allSuites = allLiveTests.map((liveTest) => liveTest.suite).toSet(); | 331 var allSuites = allLiveTests.map((liveTest) => liveTest.suite).toSet(); |
332 await Future.wait(allSuites.map((suite) => suite.close())); | 332 await Future.wait(allSuites.map((suite) => suite.close())); |
333 } | 333 } |
334 } | 334 } |
OLD | NEW |