blob: 627a8617f9fa890e2b68ab942eeaa633def7d86d [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:test/test.dart';
import 'package:bazel_worker/bazel_worker.dart';
import 'package:bazel_worker/testing.dart';
void main() {
group('SyncWorkerLoop', () {
runTests(
() => TestStdinSync(),
(Stdin stdinStream, Stdout stdoutStream) =>
TestSyncWorkerConnection(stdinStream, stdoutStream),
(TestSyncWorkerConnection connection) =>
TestSyncWorkerLoop(connection));
});
group('AsyncWorkerLoop', () {
runTests(
() => TestStdinAsync(),
(Stdin stdinStream, Stdout stdoutStream) =>
TestAsyncWorkerConnection(stdinStream, stdoutStream),
(TestAsyncWorkerConnection connection) =>
TestAsyncWorkerLoop(connection));
});
group('SyncWorkerLoopWithPrint', () {
runTests(
() => TestStdinSync(),
(Stdin stdinStream, Stdout stdoutStream) =>
TestSyncWorkerConnection(stdinStream, stdoutStream),
(TestSyncWorkerConnection connection) =>
TestSyncWorkerLoop(connection, printMessage: 'Goodbye!'));
});
group('AsyncWorkerLoopWithPrint', () {
runTests(
() => TestStdinAsync(),
(Stdin stdinStream, Stdout stdoutStream) =>
TestAsyncWorkerConnection(stdinStream, stdoutStream),
(TestAsyncWorkerConnection connection) =>
TestAsyncWorkerLoop(connection, printMessage: 'Goodbye!'));
});
}
void runTests<T extends TestWorkerConnection>(
TestStdin Function() stdinFactory,
T Function(Stdin, Stdout) workerConnectionFactory,
TestWorkerLoop Function(T) workerLoopFactory) {
late TestStdin stdinStream;
late TestStdoutStream stdoutStream;
late T connection;
late TestWorkerLoop workerLoop;
setUp(() {
stdinStream = stdinFactory();
stdoutStream = TestStdoutStream();
connection = workerConnectionFactory(stdinStream, stdoutStream);
workerLoop = workerLoopFactory(connection);
});
test('basic', () async {
var request = WorkRequest();
request.arguments.addAll(['--foo=bar']);
stdinStream.addInputBytes(protoToDelimitedBuffer(request));
stdinStream.close();
var response = WorkResponse()..output = 'Hello World';
workerLoop.enqueueResponse(response);
// Make sure `print` never gets called in the parent zone.
var printMessages = <String>[];
await runZoned(() => workerLoop.run(), zoneSpecification:
ZoneSpecification(print: (self, parent, zone, message) {
printMessages.add(message);
}));
expect(printMessages, isEmpty,
reason: 'The worker loop should hide all print calls from the parent '
'zone.');
expect(connection.responses, hasLength(1));
expect(connection.responses[0], response);
if (workerLoop.printMessage != null) {
expect(response.output, endsWith(workerLoop.printMessage!),
reason: 'Print messages should get appended to the response output.');
}
// Check that a serialized version was written to std out.
expect(stdoutStream.writes, hasLength(1));
expect(stdoutStream.writes[0], protoToDelimitedBuffer(response));
});
test('Exception in the worker.', () async {
var request = WorkRequest();
request.arguments.addAll(['--foo=bar']);
stdinStream.addInputBytes(protoToDelimitedBuffer(request));
stdinStream.close();
// Didn't enqueue a response, so this will throw inside of `performRequest`.
await workerLoop.run();
expect(connection.responses, hasLength(1));
var response = connection.responses[0];
expect(response.exitCode, EXIT_CODE_ERROR);
// Check that a serialized version was written to std out.
expect(stdoutStream.writes, hasLength(1));
expect(stdoutStream.writes[0], protoToDelimitedBuffer(response));
});
test('Stops at EOF', () async {
stdinStream.addInputBytes([-1]);
stdinStream.close();
await workerLoop.run();
});
test('Stops if stdin gives an error instead of EOF', () async {
if (stdinStream is TestStdinSync) {
// Reading will now cause an error as pendingBytes is empty.
(stdinStream as TestStdinSync).pendingBytes.clear();
await workerLoop.run();
} else if (stdinStream is TestStdinAsync) {
var done = Completer();
workerLoop.run().then((_) => done.complete(null));
(stdinStream as TestStdinAsync).controller.addError('Error!!');
await done.future;
}
});
}