Unverified Commit 9ba06b4d authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] handle waitForExtension having no isolates (#74664)

parent 5d8dfa44
......@@ -1450,34 +1450,36 @@ abstract class ResidentRunner {
// Clears the screen.
void clearScreen() => globals.logger.clear();
}
Future<vm_service.Isolate> waitForExtension(vm_service.VmService vmService, String extension) async {
final Completer<void> completer = Completer<void>();
try {
await vmService.streamListen(vm_service.EventStreams.kExtension);
} on Exception {
// do nothing
}
StreamSubscription<vm_service.Event> extensionStream;
extensionStream = vmService.onExtensionEvent.listen((vm_service.Event event) {
if (event.json['extensionKind'] == 'Flutter.FrameworkInitialization') {
// The 'Flutter.FrameworkInitialization' event is sent on hot restart
// as well, so make sure we don't try to complete this twice.
if (!completer.isCompleted) {
completer.complete();
extensionStream.cancel();
}
@visibleForTesting
Future<void> waitForExtension(vm_service.VmService vmService, String extension) async {
final Completer<void> completer = Completer<void>();
try {
await vmService.streamListen(vm_service.EventStreams.kExtension);
} on Exception {
// do nothing
}
StreamSubscription<vm_service.Event> extensionStream;
extensionStream = vmService.onExtensionEvent.listen((vm_service.Event event) {
if (event.json['extensionKind'] == 'Flutter.FrameworkInitialization') {
// The 'Flutter.FrameworkInitialization' event is sent on hot restart
// as well, so make sure we don't try to complete this twice.
if (!completer.isCompleted) {
completer.complete();
extensionStream.cancel();
}
});
final vm_service.IsolateRef isolateRef = (await vmService.getVM()).isolates.first;
}
});
final vm_service.VM vm = await vmService.getVM();
if (vm.isolates.isNotEmpty) {
final vm_service.IsolateRef isolateRef = vm.isolates.first;
final vm_service.Isolate isolate = await vmService.getIsolate(isolateRef.id);
if (isolate.extensionRPCs.contains(extension)) {
return isolate;
return;
}
await completer.future;
return isolate;
}
await completer.future;
}
class OperationResult {
......
......@@ -3001,6 +3001,86 @@ void main() {
expect(nextPlatform('fuchsia', TestFeatureFlags(isMacOSEnabled: true)), 'macOS');
expect(() => nextPlatform('unknown', TestFeatureFlags()), throwsAssertionError);
});
testWithoutContext('wait for extension handles an immediate extension', () {
final vm_service.Isolate isolate = vm_service.Isolate(
id: '1',
pauseEvent: vm_service.Event(
kind: vm_service.EventKind.kResume,
timestamp: 0
),
breakpoints: <vm_service.Breakpoint>[],
exceptionPauseMode: null,
libraries: <vm_service.LibraryRef>[
vm_service.LibraryRef(
id: '1',
uri: 'file:///hello_world/main.dart',
name: '',
),
],
livePorts: 0,
name: 'test',
number: '1',
pauseOnExit: false,
runnable: true,
startTime: 0,
isSystemIsolate: false,
isolateFlags: <vm_service.IsolateFlag>[],
extensionRPCs: <String>['foo']
);
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
method: 'streamListen',
args: <String, Object>{
'streamId': 'Extension',
}
),
FakeVmServiceRequest(method: 'getVM', jsonResponse: fakeVM.toJson()),
FakeVmServiceRequest(
method: 'getIsolate',
jsonResponse: isolate.toJson(),
args: <String, Object>{
'isolateId': '1',
},
),
]);
waitForExtension(fakeVmServiceHost.vmService, 'foo');
});
testWithoutContext('wait for extension handles no isolates', () {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
method: 'streamListen',
args: <String, Object>{
'streamId': 'Extension',
}
),
FakeVmServiceRequest(method: 'getVM', jsonResponse: vm_service.VM(
isolates: <vm_service.IsolateRef>[],
pid: 1,
hostCPU: '',
isolateGroups: <vm_service.IsolateGroupRef>[],
targetCPU: '',
startTime: 0,
name: 'dart',
architectureBits: 64,
operatingSystem: '',
version: '',
systemIsolateGroups: <vm_service.IsolateGroupRef>[],
systemIsolates: <vm_service.IsolateRef>[],
).toJson()),
FakeVmServiceStreamResponse(
streamId: 'Extension',
event: vm_service.Event(
timestamp: 0,
extensionKind: 'Flutter.FrameworkInitialization',
kind: 'test',
),
),
]);
waitForExtension(fakeVmServiceHost.vmService, 'foo');
});
}
class MockFlutterDevice extends Mock implements FlutterDevice {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment