blob: f42b8e76bd59c84296d969ebf94129d3c202f1aa [file] [log] [blame]
// Copyright (c) 2020, 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 'coverage_helper.dart';
import 'vm_service_helper.dart' as vmService;
Future<void> main(List<String> args) async {
CoverageHelper coverageHelper = new CoverageHelper();
List<String> allArgs = <String>[];
allArgs.addAll([
"--disable-dart-dev",
"--enable-asserts",
"--pause_isolates_on_exit",
]);
allArgs.addAll(args);
await coverageHelper.start(allArgs);
}
class CoverageHelper extends vmService.LaunchingVMServiceHelper {
final bool forceCompilation;
final bool printHits;
CoverageHelper({this.forceCompilation = false, this.printHits = true});
@override
Future<void> run() async {
vmService.VM vm = await serviceClient.getVM();
if (vm.isolates!.length != 1) {
throw "Expected 1 isolate, got ${vm.isolates!.length}";
}
vmService.IsolateRef isolateRef = vm.isolates!.single;
await waitUntilIsolateIsRunnable(isolateRef.id!);
await serviceClient.resume(isolateRef.id!);
Completer<String> cTimeout = new Completer();
Timer timer = new Timer(new Duration(minutes: 20), () {
cTimeout.complete("Timeout");
killProcess();
});
Completer<String> cRunDone = new Completer();
// ignore: unawaited_futures
waitUntilPaused(isolateRef.id!).then((value) => cRunDone.complete("Done"));
await Future.any([cRunDone.future, cTimeout.future, cProcessExited.future]);
timer.cancel();
if (!await isPausedAtExit(isolateRef.id!)) {
killProcess();
throw "Expected to be paused at exit, but is just paused!";
}
// Get and process coverage information.
Stopwatch stopwatch = new Stopwatch()..start();
vmService.SourceReport sourceReport = await serviceClient.getSourceReport(
isolateRef.id!, [vmService.SourceReportKind.kCoverage],
forceCompile: forceCompilation);
print("Got source report from VM in ${stopwatch.elapsedMilliseconds} ms");
stopwatch.reset();
Coverage coverage =
getCoverageFromSourceReport([sourceReport], includeCoverageFor);
// It's paused at exit, so resuming should allow us to exit.
await serviceClient.resume(isolateRef.id!);
coverage.printCoverage(printHits);
}
bool includeCoverageFor(Uri uri) {
if (uri.isScheme("dart")) {
return false;
}
if (uri.isScheme("package")) {
return uri.pathSegments.first == "front_end" ||
uri.pathSegments.first == "_fe_analyzer_shared" ||
uri.pathSegments.first == "kernel";
}
return true;
}
Completer<String> cProcessExited = new Completer();
@override
void processExited(int exitCode) {
cProcessExited.complete("Exit");
}
}