Commit f379a019 authored by Adam Barth's avatar Adam Barth

Handle subprocess crashes during testing

parent 76a51409
......@@ -82,42 +82,59 @@ void main() {
}
''');
Completer completer = new Completer();
Process process = await _startProcess(listenerFile.path,
packageRoot: p.absolute(config.packageRoot));
JSONSocket socket = new JSONSocket(await info.socket);
await tempDir.delete(recursive: true);
void shutdown() {
process.kill();
info.server.close(force: true);
Future cleanupTempDirectory() async {
if (tempDir == null)
return;
Directory dirToDelete = tempDir;
tempDir = null;
await dirToDelete.delete(recursive: true);
}
var completer = new Completer();
StreamSubscription subscription;
subscription = socket.stream.listen((response) {
if (response["type"] == "print") {
print(response["line"]);
} else if (response["type"] == "loadException") {
shutdown();
completer.completeError(
new LoadException(path, response["message"]),
new Trace.current());
} else if (response["type"] == "error") {
shutdown();
var asyncError = RemoteException.deserialize(response["error"]);
process.exitCode.then((int exitCode) async {
info.server.close(force: true);
await cleanupTempDirectory();
if (!completer.isCompleted) {
String error = await process.stderr.transform(UTF8.decoder).first;
completer.completeError(
new LoadException(path, asyncError.error),
asyncError.stackTrace);
} else {
assert(response["type"] == "success");
subscription.cancel();
completer.complete(response["tests"]);
new LoadException(path, error), new Trace.current());
}
});
Future<JSONSocket> socket = (() async {
return new JSONSocket(await info.socket);
})();
socket.then((JSONSocket socket) async {
await cleanupTempDirectory();
StreamSubscription subscription;
subscription = socket.stream.listen((response) {
if (response["type"] == "print") {
print(response["line"]);
} else if (response["type"] == "loadException") {
process.kill();
completer.completeError(
new LoadException(path, response["message"]),
new Trace.current());
} else if (response["type"] == "error") {
process.kill();
AsyncError asyncError = RemoteException.deserialize(response["error"]);
completer.completeError(
new LoadException(path, asyncError.error),
asyncError.stackTrace);
} else {
assert(response["type"] == "success");
subscription.cancel();
completer.complete(response["tests"]);
}
});
});
return new RunnerSuite(const VMEnvironment(),
(await completer.future).map((test) {
var testMetadata = new Metadata.deserialize(test['metadata']);
......@@ -127,5 +144,5 @@ void main() {
path: path,
platform: TestPlatform.vm,
os: currentOS,
onClose: shutdown);
onClose: process.kill);
}
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:test/src/backend/live_test.dart';
import 'package:test/src/backend/live_test_controller.dart';
import 'package:test/src/backend/metadata.dart';
......@@ -16,23 +18,24 @@ class RemoteTest implements Test {
final String name;
final Metadata metadata;
final JSONSocket _socket;
final Future<JSONSocket> _socket;
final int _index;
RemoteTest(this.name, this.metadata, this._socket, this._index);
LiveTest load(Suite suite) {
var controller;
var subscription;
LiveTestController controller;
StreamSubscription subscription;
controller = new LiveTestController(suite, this, () {
controller = new LiveTestController(suite, this, () async {
controller.setState(const State(Status.running, Result.success));
_socket.send({'command': 'run', 'index': _index});
JSONSocket socket = await _socket;
socket.send({'command': 'run', 'index': _index});
subscription = _socket.stream.listen((message) {
subscription = socket.stream.listen((message) {
if (message['type'] == 'error') {
var asyncError = RemoteException.deserialize(message['error']);
AsyncError asyncError = RemoteException.deserialize(message['error']);
controller.addError(asyncError.error, asyncError.stackTrace);
} else if (message['type'] == 'state-change') {
controller.setState(
......@@ -48,8 +51,9 @@ class RemoteTest implements Test {
controller.completer.complete();
}
});
}, () {
_socket.send({'command': 'close'});
}, () async {
JSONSocket socket = await _socket;
socket.send({'command': 'close'});
if (subscription != null) {
subscription.cancel();
subscription = null;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment