| 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...) Expand all 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...) Expand all 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 |