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

Unified Diff: pkg/scheduled_test/lib/src/schedule.dart

Issue 12377093: Add a ScheduledProcess class to pkg/scheduled_test. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 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: pkg/scheduled_test/lib/src/schedule.dart
diff --git a/pkg/scheduled_test/lib/src/schedule.dart b/pkg/scheduled_test/lib/src/schedule.dart
index 17ab86adfdba4f4363a4e41c5ea8f69dbfbeed3d..2a73e8eccd3ab0d1d7e75026f10541152556056b 100644
--- a/pkg/scheduled_test/lib/src/schedule.dart
+++ b/pkg/scheduled_test/lib/src/schedule.dart
@@ -60,7 +60,6 @@ class Schedule {
ScheduleState _state = ScheduleState.SET_UP;
// TODO(nweiz): make this a read-only view once issue 8321 is fixed.
-
/// Errors thrown by the task queues.
///
/// When running tasks in [tasks], this will always be empty. If an error
@@ -74,6 +73,10 @@ class Schedule {
/// added to this list.
final errors = <ScheduleError>[];
+ // TODO(nweiz): make this a read-only view once issue 8321 is fixed.
+ /// Additional debugging info registered via [addDebugInfo].
+ final debugInfo = <String>[];
+
/// The task queue that's currently being run. One of [tasks], [onException],
/// or [onComplete]. This starts as [tasks], and can only be `null` after the
/// schedule is done.
@@ -185,6 +188,12 @@ class Schedule {
}
}
+ /// Adds [info] to the debugging output that will be printed if the test
+ /// fails. Unlike [signalError], this won't cause the test to fail, nor will
+ /// it short-circuit the current [TaskQueue]; it's just useful for providing
+ /// additional information that may not fit cleanly into an existing error.
+ void addDebugInfo(String info) => debugInfo.add(info);
+
/// Notifies the schedule of an error that occurred in a task or out-of-band
/// callback after the appropriate queue has timed out. If this schedule is
/// still running, the error will be added to the errors list to be shown
@@ -272,10 +281,18 @@ class Schedule {
/// Returns a string representation of all errors registered on this schedule.
String errorString() {
if (errors.isEmpty) return "The schedule had no errors.";
- if (errors.length == 1) return errors.first.toString();
- var errorStrings = errors.map((e) => e.toString()).join("\n================"
- "================================================================\n");
- return "The schedule had ${errors.length} errors:\n$errorStrings";
+ if (errors.length == 1 && debugInfo.isEmpty) return errors.first.toString();
+
+ var border = "\n==========================================================="
+ "=====================\n";
+ var errorStrings = errors.map((e) => e.toString()).join(border);
+ var message = "The schedule had ${errors.length} errors:\n$errorStrings";
+
+ if (!debugInfo.isEmpty) {
+ message = "$message$border\nDebug info:\n${debugInfo.join(border)}";
+ }
+
+ return message;
}
/// Notifies the schedule that progress is being made on an asynchronous task.
@@ -371,7 +388,20 @@ class TaskQueue {
/// null if no task is currently running.
SubstituteFuture _taskFuture;
- TaskQueue._(this.name, this._schedule);
+ /// A [Future] that completes when the tasks in [this] are all complete. If an
+ /// error occurs while running this queue, the returned [Future] will complete
+ /// with that error.
+ ///
+ /// The returned [Future] can complete before outstanding out-of-band
+ /// callbacks have finished running.
+ Future get onTasksComplete => _onTasksCompleteCompleter.future;
+ final _onTasksCompleteCompleter = new Completer();
+
+ TaskQueue._(this.name, this._schedule) {
+ // Avoid top-leveling errors that are passed to onTasksComplete if there are no
Bob Nystrom 2013/03/04 23:52:00 Long line.
nweiz 2013/03/05 02:16:09 Done.
+ // listeners.
+ onTasksComplete.catchError((_) {});
+ }
/// Whether this queue is currently running.
bool get isRunning => _schedule.state == ScheduleState.RUNNING &&
@@ -403,7 +433,11 @@ class TaskQueue {
return task.runChild(wrappedFn, description);
}
- var task = new Task(fn, description, this);
+ var task = new Task(() {
+ return new Future.of(fn).catchError((e) {
+ throw new ScheduleError.from(_schedule, e);
+ });
+ }, description, this);
_contents.add(task);
return task.result;
}
@@ -421,14 +455,27 @@ class TaskQueue {
_taskFuture = null;
_schedule.heartbeat();
}).catchError((e) {
- if (_error != null) _schedule._addError(_error);
- throw new ScheduleError.from(_schedule, e);
+ var error = new ScheduleError.from(_schedule, e);
+ _signalError(error);
+ throw _error;
});
+ }).then((_) {
+ _onTasksCompleteCompleter.complete();
+ }).catchError((e) {
+ _onTasksCompleteCompleter.completeError(e);
+ throw e;
}).whenComplete(() {
_schedule._currentTask = null;
- return _schedule._awaitNoPendingCallbacks();
- }).then((_) {
+ return _schedule._awaitNoPendingCallbacks().catchError((e) {
+ // Signal the error rather than passing it through directly so that if a
+ // timeout happens after an in-task error, both are reported.
+ _signalError(new ScheduleError.from(_schedule, e));
+ });
+ }).whenComplete(() {
_schedule.heartbeat();
+ // If the tasks were otherwise successful, make sure we throw any
+ // out-of-band errors. If a task failed, make sure we throw the most
+ // recent error.
if (_error != null) throw _error;
});
}

Powered by Google App Engine
This is Rietveld 408576698