Unverified Commit 283ec9e2 authored by Yegor's avatar Yegor Committed by GitHub

Do not wait for connections after process has exited (#54497)

parent d119e5f1
......@@ -40,12 +40,20 @@ Future<Map<String, dynamic>> runTask(
bool runnerFinished = false;
final Completer<Uri> uri = Completer<Uri>();
runner.exitCode.whenComplete(() {
if (!uri.isCompleted) {
// The runner process exited prematurely.
uri.completeError(Exception(
'The task runner process exited before opening a VM service connection. '
'A common cause for this is when a task script does not actually create '
'a task.',
));
}
runnerFinished = true;
});
final Completer<Uri> uri = Completer<Uri>();
final StreamSubscription<String> stdoutSub = runner.stdout
.transform<String>(const Utf8Decoder())
.transform<String>(const LineSplitter())
......@@ -68,7 +76,7 @@ Future<Map<String, dynamic>> runTask(
});
try {
final VMIsolateRef isolate = await _connectToRunnerIsolate(await uri.future);
final VMIsolateRef isolate = await _connectToRunnerIsolate(await uri.future, () => !runnerFinished);
final Map<String, dynamic> taskResult = await isolate.invokeExtension('ext.cocoonRunTask') as Map<String, dynamic>;
await runner.exitCode;
return taskResult;
......@@ -81,7 +89,7 @@ Future<Map<String, dynamic>> runTask(
}
}
Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri, bool Function() keepTrying) async {
final List<String> pathSegments = <String>[
// Add authentication code.
if (vmServiceUri.pathSegments.isNotEmpty) vmServiceUri.pathSegments[0],
......@@ -91,7 +99,7 @@ Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
pathSegments).toString();
final Stopwatch stopwatch = Stopwatch()..start();
while (true) {
while (keepTrying()) {
try {
// Make sure VM server is up by successfully opening and closing a socket.
await (await WebSocket.connect(url)).close();
......@@ -110,6 +118,8 @@ Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
await Future<void>.delayed(const Duration(milliseconds: 50));
}
}
throw Exception('Failed to connect to Dart VM service.');
}
Future<void> cleanupSystem() async {
......
......@@ -24,43 +24,43 @@ void main() {
return scriptProcess;
}
Future<void> expectScriptResult(List<String> testNames, int expectedExitCode) async {
Future<void> expectScriptResult(List<String> testNames, { bool expectSuccess }) async {
final ProcessResult result = await runScript(testNames);
expect(result.exitCode, expectedExitCode,
expect(result.exitCode, expectSuccess ? 0 : isNot(equals(0)),
reason: '[ stderr from test process ]\n\n${result.stderr}\n\n[ end of stderr ]'
'\n\n[ stdout from test process ]\n\n${result.stdout}\n\n[ end of stdout ]');
}
test('exits with code 0 when succeeds', () async {
await expectScriptResult(<String>['smoke_test_success'], 0);
await expectScriptResult(<String>['smoke_test_success'], expectSuccess: true);
});
test('accepts file paths', () async {
await expectScriptResult(<String>['bin/tasks/smoke_test_success.dart'], 0);
await expectScriptResult(<String>['bin/tasks/smoke_test_success.dart'], expectSuccess: true);
});
test('rejects invalid file paths', () async {
await expectScriptResult(<String>['lib/framework/adb.dart'], 1);
await expectScriptResult(<String>['lib/framework/adb.dart'], expectSuccess: false);
});
test('exits with code 1 when task throws', () async {
await expectScriptResult(<String>['smoke_test_throws'], 1);
await expectScriptResult(<String>['smoke_test_throws'], expectSuccess: false);
});
test('exits with code 1 when fails', () async {
await expectScriptResult(<String>['smoke_test_failure'], 1);
await expectScriptResult(<String>['smoke_test_failure'], expectSuccess: false);
});
test('exits with code 1 when fails to connect', () async {
await expectScriptResult(<String>['smoke_test_setup_failure'], 1);
}, skip: true); // https://github.com/flutter/flutter/issues/53707
await expectScriptResult(<String>['smoke_test_setup_failure'], expectSuccess: false);
});
test('exits with code 1 when results are mixed', () async {
await expectScriptResult(<String>[
'smoke_test_failure',
'smoke_test_success',
],
1,
expectSuccess: false,
);
});
});
......
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