blob: 587a07f570d89cfa4249b0d3be8768cf9179b9c8 [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.md file.
library testing.stdio_process;
import 'dart:async' show EventSink, Future, Stream, StreamTransformer, Timer;
import 'dart:convert' show utf8;
import 'dart:io' show Process, ProcessSignal, Stdout;
import 'dart:io' as io show stderr, stdout;
import 'chain.dart' show Result;
import 'expectation.dart' show ExpectationSet;
class StdioProcess {
final int exitCode;
final String output;
StdioProcess(this.exitCode, this.output);
Result<int> toResult({int expected: 0}) {
if (exitCode == expected) {
return new Result<int>.pass(exitCode);
} else {
return new Result<int>(
exitCode, ExpectationSet.Default["RuntimeError"], output);
}
}
static StreamTransformer<String, String> transformToStdio(Stdout stdio) {
return new StreamTransformer<String, String>.fromHandlers(
handleData: (String data, EventSink<String> sink) {
sink.add(data);
stdio.write(data);
});
}
static Future<StdioProcess> run(String executable, List<String> arguments,
{String? input,
Duration? timeout: const Duration(seconds: 60),
bool suppressOutput: true,
bool runInShell: false}) async {
Process process =
await Process.start(executable, arguments, runInShell: runInShell);
Timer? timer;
StringBuffer sb = new StringBuffer();
if (timeout != null) {
timer = new Timer(timeout, () {
sb.write("Process timed out: ");
sb.write(executable);
sb.write(" ");
sb.writeAll(arguments, " ");
sb.writeln();
sb.writeln("Sending SIGTERM to process");
process.kill();
timer = new Timer(const Duration(seconds: 10), () {
sb.writeln("Sending SIGKILL to process");
process.kill(ProcessSignal.sigkill);
});
});
}
if (input != null) {
process.stdin.write(input);
await process.stdin.flush();
}
Future closeFuture = process.stdin.close();
Stream stdoutStream = process.stdout.transform(utf8.decoder);
Stream stderrStream = process.stderr.transform(utf8.decoder);
if (!suppressOutput) {
stdoutStream = stdoutStream.transform(transformToStdio(io.stdout));
stderrStream = stderrStream.transform(transformToStdio(io.stderr));
}
Future<List<String>> stdoutFuture = stdoutStream.toList() as Future<List<String>>;
Future<List<String>> stderrFuture = stderrStream.toList() as Future<List<String>>;
int exitCode = await process.exitCode;
timer?.cancel();
sb.writeAll(await stdoutFuture);
sb.writeAll(await stderrFuture);
await closeFuture;
return new StdioProcess(exitCode, "$sb");
}
}