blob: 5807b70d497af80c1599bf88785dd78e8e8b5808 [file] [log] [blame]
// Copyright (c) 2021, 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' show Future;
import 'dart:convert' show LineSplitter, utf8;
import 'dart:io' show File, Platform, Process, ProcessResult;
Future<void> main(List<String> args) async {
// General idea: Launch - in separate processes - whatever we want to run
// concurrently, capturing the stdout and stderr, printing it with some
// prepended identification.
// When all runs are done, fail if any fails.
// Later we might be able to move it to the "testRunner"-system, if that
// offers any advantages.
print(
"NOTE: This machine has ${Platform.numberOfProcessors} processors!"
"\n\n",
);
List<WrappedProcess> startedProcesses = [];
List<String> missingScripts = [];
void noteMissingScript(String message) {
missingScripts.add(message);
print(message);
}
{
// Very slow: Leak-test.
Uri leakTester = Platform.script.resolve(
"flutter_gallery_leak_tester.dart",
);
if (!new File.fromUri(leakTester).existsSync()) {
noteMissingScript("Couldn't find $leakTester");
} else {
// The tools/bots/flutter/compile_flutter.sh script passes `--path`
// --- we'll just pass everything along.
startedProcesses.add(
await run([leakTester.toString(), ...args], "leak test"),
);
}
}
{
// Strong suite with fuzzing.
Uri strongSuite = Platform.script.resolve("strong_suite.dart");
if (!new File.fromUri(strongSuite).existsSync()) {
noteMissingScript("Couldn't find $strongSuite");
} else {
startedProcesses.add(
await run([strongSuite.toString(), "-DsemiFuzz=true"], "strong suite"),
);
}
}
{
// Leak tests of incremental suite tests.
Uri incrementalLeakTest = Platform.script.resolve(
"vm_service_for_leak_detection.dart",
);
if (!new File.fromUri(incrementalLeakTest).existsSync()) {
noteMissingScript("Couldn't find $incrementalLeakTest");
} else {
startedProcesses.add(
await run([
incrementalLeakTest.toString(),
"--weekly",
], "incremental leak test"),
);
}
}
{
// Expression suite with fuzzing.
Uri expressionSuite = Platform.script.resolve("expression_suite.dart");
if (!new File.fromUri(expressionSuite).existsSync()) {
noteMissingScript("Couldn't find $expressionSuite");
} else {
startedProcesses.add(
await run([
expressionSuite.toString(),
"-Dfuzz=true",
], "expression suite"),
);
}
}
// Wait for everything to finish.
bool shouldThrow = false;
List<int> exitCodes = await Future.wait(
startedProcesses.map((e) => e.process.exitCode),
);
if (exitCodes.where((e) => e != 0).isNotEmpty) {
shouldThrow = true;
print("\n\nFound failures!:\n");
// At least one failed.
for (WrappedProcess p in startedProcesses) {
int pExitCode = await p.process.exitCode;
if (pExitCode != 0) {
print("${p.id} failed with exist-code $pExitCode");
}
}
}
if (missingScripts.isNotEmpty) {
print("\n\nThere were missing scripts!");
for (String message in missingScripts) {
print(" - $message");
}
shouldThrow = true;
}
// Now run all coverage and print a diff.
WrappedProcess coverageProcess = await run([
Platform.script.resolve("run_all_coverage_update.dart").toString(),
], "coverage update");
await coverageProcess.process.exitCode;
ProcessResult coverageDiffResult = Process.runSync("git", ["diff"]);
print(coverageDiffResult.stdout);
if (shouldThrow) throw "There were failures!";
}
Future<WrappedProcess> run(List<String> args, String id) async {
Stopwatch stopwatch = new Stopwatch()..start();
Process process = await Process.start(Platform.resolvedExecutable, [
"--enable-asserts",
...args,
]);
List<String> observatoryLines = [];
process.stderr.transform(utf8.decoder).transform(new LineSplitter()).listen((
line,
) {
print("$id stderr> $line");
if (line.contains("The Dart VM service is listening on")) {
observatoryLines.add(line);
}
});
process.stdout.transform(utf8.decoder).transform(new LineSplitter()).listen((
line,
) {
print("$id stdout> $line");
if (line.contains("The Dart VM service is listening on")) {
observatoryLines.add(line);
}
});
// ignore: unawaited_futures
process.exitCode.then((int exitCode) {
stopwatch.stop();
print(
"$id finished in ${stopwatch.elapsed.toString()} "
"with exit code $exitCode",
);
});
return new WrappedProcess(process, id, observatoryLines);
}
class WrappedProcess {
final Process process;
final String id;
final List<String> observatoryLines;
WrappedProcess(this.process, this.id, this.observatoryLines);
}