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>
87 lines
2.4 KiB
Dart
87 lines
2.4 KiB
Dart
// Copyright (c) 2024, 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 'dart:io';
|
|
|
|
import '../test/coverage_helper.dart';
|
|
import '../test/vm_service_helper.dart';
|
|
|
|
Uri? coverageUri;
|
|
|
|
Future<void> main(final List<String> args) async {
|
|
String? coverage = Platform.environment["CFE_COVERAGE"];
|
|
if (coverage != null) {
|
|
coverageUri = Uri.base.resolveUri(Uri.file(coverage));
|
|
} else {
|
|
throw "Set coverage path via 'CFE_COVERAGE' environment!";
|
|
}
|
|
|
|
MyLaunchingVMServiceHelper launchingHelper =
|
|
new MyLaunchingVMServiceHelper(args);
|
|
await launchingHelper.start(
|
|
[
|
|
"--pause_isolates_on_exit",
|
|
"--disable-dart-dev",
|
|
...args,
|
|
],
|
|
pauseIsolateOnStart: false,
|
|
);
|
|
await launchingHelper.exitCompleter.future;
|
|
}
|
|
|
|
class MyLaunchingVMServiceHelper extends LaunchingVMServiceHelper {
|
|
final List<String> args;
|
|
final Completer<int> exitCompleter = new Completer<int>();
|
|
|
|
MyLaunchingVMServiceHelper(this.args);
|
|
|
|
@override
|
|
void processExited(int code) {
|
|
exitCode = code;
|
|
exitCompleter.complete(code);
|
|
}
|
|
|
|
@override
|
|
Future<void> run() async {
|
|
// TODO(jensj): Get coverage for the isolate paused at exit, then resume
|
|
// that one, continue until there's no more isolates left.
|
|
// E.g. for pkg/front_end/tool/coverage_runner.dart.
|
|
await waitUntilSomeIsolatePausedAtExit();
|
|
|
|
Coverage? coverage = await collectCoverageWithHelper(
|
|
helper: this,
|
|
getKernelServiceCoverageToo: true,
|
|
displayName: args.join(" "),
|
|
);
|
|
if (coverage != null) {
|
|
File f = new File.fromUri(coverageUri!.resolve("coverage_run_"
|
|
"${DateTime.now().microsecondsSinceEpoch}_"
|
|
"${process.pid}.coverage"));
|
|
coverage.writeToFile(f);
|
|
}
|
|
|
|
await resumeAllIsolates();
|
|
try {
|
|
while (true) {
|
|
VM vm = await serviceClient.getVM();
|
|
List<IsolateRef> isolates = vm.isolates!;
|
|
if (isolates.isEmpty) break;
|
|
for (IsolateRef isolate in isolates) {
|
|
try {
|
|
if (await isPaused(isolate.id!) == true) {
|
|
await serviceClient.resume(isolate.id!);
|
|
}
|
|
} catch (e) {
|
|
// It might exit at some point so we can't expect to get
|
|
// a good result.
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// Assume this is a good thing.
|
|
}
|
|
}
|
|
}
|