Files
sdk/pkg/testing/lib/src/stdio_process.dart
T
Johnni Winther 9ce4f5dfec [cfe] Report distinct error codes in incremental_load_from_dill testing
This changes the reported failure from Crash to something more specific
to the encounter error, like ExpectationFileMismatch. Validation errors
for the .yaml file still produce Crash, and so does a couple of the
checks on Component integrity that were also used outside
incremental_load_from_dill_suite.dart

Change-Id: I48aa8cb25198d24e986b0f354db2b370dc9b8ac8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167565
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
2020-10-14 21:21:48 +00:00

88 lines
2.8 KiB
Dart

// 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();
Future<List<String>> stderrFuture = stderrStream.toList();
int exitCode = await process.exitCode;
timer?.cancel();
sb.writeAll(await stdoutFuture);
sb.writeAll(await stderrFuture);
await closeFuture;
return new StdioProcess(exitCode, "$sb");
}
}