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:collection/collection.dart'; |
10 import 'package:pool/pool.dart'; | 11 import 'package:pool/pool.dart'; |
11 | 12 |
12 import '../backend/live_test.dart'; | 13 import '../backend/live_test.dart'; |
13 import '../backend/live_test_controller.dart'; | 14 import '../backend/live_test_controller.dart'; |
14 import '../backend/state.dart'; | 15 import '../backend/state.dart'; |
15 import '../backend/suite.dart'; | 16 import '../backend/suite.dart'; |
16 import '../backend/test.dart'; | 17 import '../backend/test.dart'; |
17 import '../utils.dart'; | 18 import '../utils.dart'; |
18 | 19 |
19 /// An [Engine] manages a run that encompasses multiple test suites. | 20 /// An [Engine] manages a run that encompasses multiple test suites. |
(...skipping 28 matching lines...) Loading... |
48 /// This allows test suites to be run in parallel without running multiple | 49 /// This allows test suites to be run in parallel without running multiple |
49 /// tests in the same suite at once. | 50 /// tests in the same suite at once. |
50 final List<List<LiveTest>> _liveTestsBySuite; | 51 final List<List<LiveTest>> _liveTestsBySuite; |
51 | 52 |
52 /// A stream that emits each [LiveTest] as it's about to start running. | 53 /// A stream that emits each [LiveTest] as it's about to start running. |
53 /// | 54 /// |
54 /// This is guaranteed to fire before [LiveTest.onStateChange] first fires. | 55 /// This is guaranteed to fire before [LiveTest.onStateChange] first fires. |
55 Stream<LiveTest> get onTestStarted => _onTestStartedController.stream; | 56 Stream<LiveTest> get onTestStarted => _onTestStartedController.stream; |
56 final _onTestStartedController = new StreamController<LiveTest>.broadcast(); | 57 final _onTestStartedController = new StreamController<LiveTest>.broadcast(); |
57 | 58 |
| 59 /// The set of tests that have completed and been marked as passing. |
| 60 Set<LiveTest> get passed => new UnmodifiableSetView(_passed); |
| 61 final _passed = new Set<LiveTest>(); |
| 62 |
| 63 /// The set of tests that have completed and been marked as skipped. |
| 64 Set<LiveTest> get skipped => new UnmodifiableSetView(_skipped); |
| 65 final _skipped = new Set<LiveTest>(); |
| 66 |
| 67 /// The set of tests that have completed and been marked as failing or error. |
| 68 Set<LiveTest> get failed => new UnmodifiableSetView(_failed); |
| 69 final _failed = new Set<LiveTest>(); |
| 70 |
| 71 /// The tests that are still running, in the order they begain running. |
| 72 List<LiveTest> get active => new UnmodifiableListView(_active); |
| 73 final _active = new List<LiveTest>(); |
| 74 |
58 /// Returns the tests in [suites] grouped by suite. | 75 /// Returns the tests in [suites] grouped by suite. |
59 /// | 76 /// |
60 /// Also replaces tests marked as "skip" with dummy [LiveTest]s. | 77 /// Also replaces tests marked as "skip" with dummy [LiveTest]s. |
61 static List<List<LiveTest>> _computeLiveTestsBySuite(Iterable<Suite> suites) { | 78 static List<List<LiveTest>> _computeLiveTestsBySuite(Iterable<Suite> suites) { |
62 return suites.map((suite) { | 79 return suites.map((suite) { |
63 return suite.tests.map((test) { | 80 return suite.tests.map((test) { |
64 return test.metadata.skip | 81 return test.metadata.skip |
65 ? _skippedTest(suite, test) | 82 ? _skippedTest(suite, test) |
66 : test.load(suite); | 83 : test.load(suite); |
67 }).toList(); | 84 }).toList(); |
(...skipping 29 matching lines...) Loading... |
97 _runCalled = true; | 114 _runCalled = true; |
98 | 115 |
99 await Future.wait(_liveTestsBySuite.map((suite) { | 116 await Future.wait(_liveTestsBySuite.map((suite) { |
100 return _pool.withResource(() { | 117 return _pool.withResource(() { |
101 if (_closed) return null; | 118 if (_closed) return null; |
102 | 119 |
103 // TODO(nweiz): Use a real for loop when issue 23394 is fixed. | 120 // TODO(nweiz): Use a real for loop when issue 23394 is fixed. |
104 return Future.forEach(suite, (liveTest) async { | 121 return Future.forEach(suite, (liveTest) async { |
105 // TODO(nweiz): Just "return;" when issue 23200 is fixed. | 122 // TODO(nweiz): Just "return;" when issue 23200 is fixed. |
106 if (_closed) return null; | 123 if (_closed) return null; |
| 124 |
| 125 _active.add(liveTest); |
| 126 |
| 127 liveTest.onStateChange.listen((state) { |
| 128 if (state.status != Status.complete) return; |
| 129 _active.remove(liveTest); |
| 130 |
| 131 if (state.result != Result.success) { |
| 132 _passed.remove(liveTest); |
| 133 _failed.add(liveTest); |
| 134 } else if (liveTest.test.metadata.skip) { |
| 135 _skipped.add(liveTest); |
| 136 } else { |
| 137 _passed.add(liveTest); |
| 138 } |
| 139 }); |
| 140 |
107 _onTestStartedController.add(liveTest); | 141 _onTestStartedController.add(liveTest); |
108 | 142 |
109 // First, schedule a microtask to ensure that [onTestStarted] fires | 143 // First, schedule a microtask to ensure that [onTestStarted] fires |
110 // before the first [LiveTest.onStateChange] event. Once the test | 144 // before the first [LiveTest.onStateChange] event. Once the test |
111 // finishes, use [new Future] to do a coarse-grained event loop pump | 145 // finishes, use [new Future] to do a coarse-grained event loop pump |
112 // to avoid starving the DOM or other non-microtask events. | 146 // to avoid starving the DOM or other non-microtask events. |
113 await new Future.microtask(liveTest.run); | 147 await new Future.microtask(liveTest.run); |
114 await new Future(() {}); | 148 await new Future(() {}); |
115 }); | 149 }); |
116 }); | 150 }); |
117 })); | 151 })); |
118 | 152 |
119 return liveTests.every( | 153 return liveTests.every( |
120 (liveTest) => liveTest.state.result == Result.success); | 154 (liveTest) => liveTest.state.result == Result.success); |
121 } | 155 } |
122 | 156 |
123 /// Signals that the caller is done paying attention to test results and the | 157 /// Signals that the caller is done paying attention to test results and the |
124 /// engine should release any resources it has allocated. | 158 /// engine should release any resources it has allocated. |
125 /// | 159 /// |
126 /// Any actively-running tests are also closed. VM tests are allowed to finish | 160 /// Any actively-running tests are also closed. VM tests are allowed to finish |
127 /// running so that any modifications they've made to the filesystem can be | 161 /// running so that any modifications they've made to the filesystem can be |
128 /// cleaned up. | 162 /// cleaned up. |
129 Future close() { | 163 Future close() { |
130 _closed = true; | 164 _closed = true; |
131 return Future.wait(liveTests.map((liveTest) => liveTest.close())); | 165 return Future.wait(liveTests.map((liveTest) => liveTest.close())); |
132 } | 166 } |
133 } | 167 } |
OLD | NEW |