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 { ...@@ -1450,34 +1450,36 @@ abstract class ResidentRunner {
// Clears the screen. // Clears the screen.
void clearScreen() => globals.logger.clear(); void clearScreen() => globals.logger.clear();
}
Future<vm_service.Isolate> waitForExtension(vm_service.VmService vmService, String extension) async { @visibleForTesting
final Completer<void> completer = Completer<void>(); Future<void> waitForExtension(vm_service.VmService vmService, String extension) async {
try { final Completer<void> completer = Completer<void>();
await vmService.streamListen(vm_service.EventStreams.kExtension); try {
} on Exception { await vmService.streamListen(vm_service.EventStreams.kExtension);
// do nothing } on Exception {
} // do nothing
StreamSubscription<vm_service.Event> extensionStream; }
extensionStream = vmService.onExtensionEvent.listen((vm_service.Event event) { StreamSubscription<vm_service.Event> extensionStream;
if (event.json['extensionKind'] == 'Flutter.FrameworkInitialization') { extensionStream = vmService.onExtensionEvent.listen((vm_service.Event event) {
// The 'Flutter.FrameworkInitialization' event is sent on hot restart if (event.json['extensionKind'] == 'Flutter.FrameworkInitialization') {
// as well, so make sure we don't try to complete this twice. // The 'Flutter.FrameworkInitialization' event is sent on hot restart
if (!completer.isCompleted) { // as well, so make sure we don't try to complete this twice.
completer.complete(); if (!completer.isCompleted) {
extensionStream.cancel(); 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); final vm_service.Isolate isolate = await vmService.getIsolate(isolateRef.id);
if (isolate.extensionRPCs.contains(extension)) { if (isolate.extensionRPCs.contains(extension)) {
return isolate; return;
} }
await completer.future;
return isolate;
} }
await completer.future;
} }
class OperationResult { class OperationResult {
......
...@@ -3001,6 +3001,86 @@ void main() { ...@@ -3001,6 +3001,86 @@ void main() {
expect(nextPlatform('fuchsia', TestFeatureFlags(isMacOSEnabled: true)), 'macOS'); expect(nextPlatform('fuchsia', TestFeatureFlags(isMacOSEnabled: true)), 'macOS');
expect(() => nextPlatform('unknown', TestFeatureFlags()), throwsAssertionError); 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 {} 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