mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
ensure test isolate is paused before collecting coverage (#35188)
This commit is contained in:
parent
919dcf53f3
commit
c9b283386b
@ -47,16 +47,16 @@ class CoverageCollector extends TestWatcher {
|
||||
/// has been run to completion so that all coverage data has been recorded.
|
||||
///
|
||||
/// The returned [Future] completes when the coverage is collected.
|
||||
Future<void> collectCoverageIsolate(Uri observatoryUri) async {
|
||||
Future<void> collectCoverageIsolate(Uri observatoryUri, String debugName) async {
|
||||
assert(observatoryUri != null);
|
||||
printTrace('collecting coverage data from $observatoryUri...');
|
||||
print('collecting coverage data from $observatoryUri...');
|
||||
final Map<String, dynamic> data = await collect(observatoryUri, (String libraryName) {
|
||||
// If we have a specified coverage directory or could not find the package name, then
|
||||
// accept all libraries.
|
||||
return (coverageDirectory != null)
|
||||
|| (flutterProject == null)
|
||||
|| libraryName.contains(flutterProject.manifest.appName);
|
||||
});
|
||||
}, waitPaused: true, debugName: debugName);
|
||||
if (data == null) {
|
||||
throw Exception('Failed to collect coverage.');
|
||||
}
|
||||
@ -185,13 +185,39 @@ class CoverageCollector extends TestWatcher {
|
||||
}
|
||||
|
||||
Future<VMService> _defaultConnect(Uri serviceUri) {
|
||||
return VMService.connect(serviceUri, compression: CompressionOptions.compressionOff);
|
||||
return VMService.connect(
|
||||
serviceUri, compression: CompressionOptions.compressionOff);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> collect(Uri serviceUri, bool Function(String) libraryPredicate,
|
||||
[Future<VMService> Function(Uri) connector = _defaultConnect]) async {
|
||||
Future<Map<String, dynamic>> collect(Uri serviceUri, bool Function(String) libraryPredicate, {
|
||||
bool waitPaused = false,
|
||||
String debugName,
|
||||
Future<VMService> Function(Uri) connector = _defaultConnect,
|
||||
}) async {
|
||||
final VMService vmService = await connector(serviceUri);
|
||||
await vmService.getVM();
|
||||
final Isolate isolate = vmService.vm.isolates.firstWhere((Isolate isolate) => isolate.name == debugName);
|
||||
if (!waitPaused) {
|
||||
return _getAllCoverage(vmService, libraryPredicate);
|
||||
}
|
||||
const int kPollAttempts = 20;
|
||||
int i = 0;
|
||||
while (i < kPollAttempts) {
|
||||
await isolate.load();
|
||||
if (isolate.pauseEvent?.kind == ServiceEvent.kPauseStart) {
|
||||
break;
|
||||
}
|
||||
await Future<void>.delayed(const Duration(milliseconds: 50));
|
||||
i += 1;
|
||||
}
|
||||
if (i == kPollAttempts) {
|
||||
print('Isolate $debugName was never paused, refusing to collect coverage');
|
||||
return const <String, dynamic>{
|
||||
'type': 'CodeCoverage',
|
||||
'coverage': <Object>[]
|
||||
};
|
||||
}
|
||||
print('isolate is paused, collecting coverage...');
|
||||
return _getAllCoverage(vmService, libraryPredicate);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ void main() {
|
||||
.thenAnswer((Invocation invocation) async {
|
||||
return <String, Object>{'type': 'Sentinel', 'kind': 'Collected', 'valueAsString': '<collected>'};
|
||||
});
|
||||
final Map<String, Object> result = await collect(null, (String predicate) => true, (Uri uri) async {
|
||||
final Map<String, Object> result = await collect(null, (String predicate) => true, connector: (Uri uri) async {
|
||||
return mockVMService;
|
||||
});
|
||||
|
||||
|
@ -77,8 +77,10 @@ class VMPlatform extends PlatformPlugin {
|
||||
final dynamic channel = IsolateChannel<Object>.connectReceive(receivePort)
|
||||
.transformStream(StreamTransformer<Object, Object>.fromHandlers(handleDone: (EventSink<Object> sink) async {
|
||||
try {
|
||||
// Pause the isolate so it is ready for coverage collection.
|
||||
isolate.pause();
|
||||
// this will throw if collection fails.
|
||||
await coverageCollector.collectCoverageIsolate(info.serverUri);
|
||||
await coverageCollector.collectCoverageIsolate(info.serverUri, path);
|
||||
} finally {
|
||||
isolate.kill(priority: Isolate.immediate);
|
||||
isolate = null;
|
||||
@ -115,6 +117,7 @@ class VMPlatform extends PlatformPlugin {
|
||||
return await Isolate.spawnUri(p.toUri(testPath), <String>[], message,
|
||||
packageConfig: p.toUri('.packages'),
|
||||
checked: true,
|
||||
debugName: path,
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user