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

Unified Diff: lib/src/runner/engine.dart

Issue 1196413003: Add a LoadSuite class. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: lib/src/runner/engine.dart
diff --git a/lib/src/runner/engine.dart b/lib/src/runner/engine.dart
index f50fd4885c924f3952d129f597759c701bbb8c09..30053ba14aa0d091dde5ea845891e2b66618e657 100644
--- a/lib/src/runner/engine.dart
+++ b/lib/src/runner/engine.dart
@@ -17,14 +17,33 @@ import '../backend/state.dart';
import '../backend/suite.dart';
import '../backend/test.dart';
import '../util/delegating_sink.dart';
+import 'load_suite.dart';
/// An [Engine] manages a run that encompasses multiple test suites.
///
+/// Test suites are provided by passing them into [suiteSink]. Once all suites
+/// have been provided, the user should close [suiteSink] to indicate this.
+/// [run] won't terminate until [suiteSink] is closed. Suites will be run in the
+/// order they're provided to [suiteSink]. Tests within those suites will
+/// likewise be run in the order of [Suite.tests].
+///
/// The current status of every test is visible via [liveTests]. [onTestStarted]
/// can also be used to be notified when a test is about to be run.
///
-/// Suites will be run in the order they're provided to [new Engine]. Tests
-/// within those suites will likewise be run in the order of [Suite.tests].
+/// The engine has some special logic for [LoadSuite]s and the tests they
+/// contain, referred to as "load tests". Load tests exist to provide visibility
+/// into the process of loading test files, but as long as that process is
+/// proceeding normally users usually don't care about it, so the engine only
+/// surfaces running load tests (that is, includes them in [liveTests] and other
+/// collections) under specific circumstances.
+///
+/// If only load tests are running, exactly one load test will be in [active]
+/// and [liveTests]. If this test passes, it will be removed from both [active]
+/// and [liveTests] and *will not* be added to [passed]. If at any point a load
+/// test fails, it will be added to [failed] and [liveTests].
+///
+/// Load tests will always be emitted through [onTestStarted] so users can watch
+/// their event streams once they start running.
class Engine {
/// Whether [run] has been called yet.
var _runCalled = false;
@@ -97,7 +116,13 @@ class Engine {
/// The tests that are still running, in the order they begain running.
List<LiveTest> get active => new UnmodifiableListView(_active);
- final _active = new List<LiveTest>();
+ final _active = new QueueList<LiveTest>();
+
+ /// The tests from [LoadSuite]s that are still running, in the order they
+ /// began running.
+ ///
+ /// This is separate from [active] because load tests aren't always surfaced.
+ final _activeLoadTests = new List<LiveTest>();
/// Creates an [Engine] that will run all tests provided via [suiteSink].
///
@@ -135,6 +160,11 @@ class Engine {
_runCalled = true;
_suiteController.stream.listen((suite) {
+ if (suite is LoadSuite) {
+ _group.add(_addLoadSuite(suite));
+ return;
+ }
+
_group.add(_pool.withResource(() {
if (_closed) return null;
@@ -148,10 +178,23 @@ class Engine {
_liveTests.add(liveTest);
_active.add(liveTest);
+ // If there were no active non-load tests, the current active test
+ // would have been a load test. In that case, remove it, since now we
+ // have a non-load test to add.
+ if (_active.isNotEmpty && _active.first.suite is LoadSuite) {
+ _liveTests.remove(_active.removeFirst());
+ }
+
liveTest.onStateChange.listen((state) {
if (state.status != Status.complete) return;
_active.remove(liveTest);
+ // If we're out of non-load tests, surface a load test.
+ if (_active.isEmpty && _activeLoadTests.isNotEmpty) {
+ _active.add(_activeLoadTests.first);
+ _liveTests.add(_activeLoadTests.first);
+ }
+
if (state.result != Result.success) {
_passed.remove(liveTest);
_failed.add(liveTest);
@@ -188,6 +231,49 @@ class Engine {
return controller.liveTest;
}
+ /// Adds listeners for [suite].
+ ///
+ /// Load suites have specific logic apart from normal test suites.
+ Future _addLoadSuite(LoadSuite suite) async {
+ var liveTest = await suite.tests.single.load(suite);
+
+ _activeLoadTests.add(liveTest);
+
+ // Only surface the load test if there are no other tests currently running.
+ if (_active.isEmpty) {
+ _liveTests.add(liveTest);
+ _active.add(liveTest);
+ }
+
+ liveTest.onStateChange.listen((state) {
+ if (state.status != Status.complete) return;
+ _activeLoadTests.remove(liveTest);
+
+ // Only one load test will be active at any given time, and it will always
+ // be the only active test. Remove it and, if possible, surface another
+ // load test.
+ if (_active.isNotEmpty && _active.first.suite == suite) {
+ _active.remove(liveTest);
+ _liveTests.remove(liveTest);
+
+ if (_activeLoadTests.isNotEmpty) {
+ _active.add(_activeLoadTests.last);
+ _liveTests.add(_activeLoadTests.last);
+ }
+ }
+
+ // Surface the load test if it fails so that the user can see the failure.
+ if (state.result == Result.success) return;
+ _failed.add(liveTest);
+ _liveTests.add(liveTest);
+ });
+
+ // Run the test immediately. We don't want loading to be blocked on suites
+ // that are already running.
+ _onTestStartedController.add(liveTest);
+ await liveTest.run();
+ }
+
/// Signals that the caller is done paying attention to test results and the
/// engine should release any resources it has allocated.
///
@@ -203,6 +289,7 @@ class Engine {
if (_closedBeforeDone == null) _closedBeforeDone = true;
_suiteController.close();
- return Future.wait(liveTests.map((liveTest) => liveTest.close()));
+ var allLiveTests = liveTests.toSet()..addAll(_activeLoadTests);
+ return Future.wait(allLiveTests.map((liveTest) => liveTest.close()));
}
}

Powered by Google App Engine
This is Rietveld 408576698