8a6b48f596
* Added tests for compiling the platform with coverage information * Patched all CFE suites to be able to capture coverage information (e.g. via `out/ReleaseX64/dart pkg/front_end/test/fasta/strong_suite.dart \ --coverage=coverage/` and then merging and showing via `out/ReleaseX64/dart pkg/front_end/tool/coverage_merger.dart \ --coverage=coverage/`) * Added "meta test" that runs all of the cfe et al tests and captures coverage information at the end. * Patched the bulk compiler to be able to capture coverage information (likely only works in non-Windows as it has to hook into signaling to be able to capture data as the process is being killed by the test.py script). * Tool for combining the dumped coverage information. * Meta test that executes everything and combines the result (run via e.g. `out/ReleaseX64/dart-sdk/bin/dart \ pkg/front_end/test/run_all_coverage.dart`) Initially I wanted to (for language tests) have per-test coverage, changed the test.py scripts to run the tests through a special tool that then captured coverage information for the kernel_service isolate which worked well for tests that compiles without error, but doesn't work when there are compile time errors (because dart terminates before coverage can be captured). So the solution - at least for now - was to hook into the batch compilation. The "visualization" of the result currently isn't very good -- mostly just a list of not covered positions -- but the hope is that everything that should be covered (eventually) will be covered, so maybe it's not a big deal. Also still to do is being able to - probably via comments in the covered code - say "this isn't expected to be covered", so we can work towards expecting all (or certain) files to be 100% covered (modulo those comments), e.g. when running the thing on the weekly bot. Change-Id: I6f885f4a9c04fb52a65797a9de790e1e5eacecf1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353103 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
92 lines
2.8 KiB
Dart
92 lines
2.8 KiB
Dart
// 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");
|
|
}
|
|
}
|