fix driver connection flakiness (#9968)
This commit is contained in:
parent
abaf290119
commit
f7d62aaa9e
@ -212,11 +212,25 @@ class FlutterDriver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tells the Dart VM Service to notify us about "Isolate" events.
|
||||||
|
///
|
||||||
|
/// This is a workaround for an issue in package:vm_service_client, which
|
||||||
|
/// subscribes to the "Isolate" stream lazily upon subscription, which
|
||||||
|
/// results in lost events.
|
||||||
|
///
|
||||||
|
/// Details: https://github.com/dart-lang/vm_service_client/issues/17
|
||||||
|
Future<Null> enableIsolateStreams() async {
|
||||||
|
await connection.peer.sendRequest('streamListen', <String, String>{
|
||||||
|
'streamId': 'Isolate',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// If the isolate is paused at the start, e.g. via the --start-paused
|
// If the isolate is paused at the start, e.g. via the --start-paused
|
||||||
// option, then the VM service extension is not registered yet. Wait for
|
// option, then the VM service extension is not registered yet. Wait for
|
||||||
// it to be registered.
|
// it to be registered.
|
||||||
final Future<dynamic> whenResumed = resumeLeniently();
|
await enableIsolateStreams();
|
||||||
final Future<dynamic> whenServiceExtensionReady = waitForServiceExtension();
|
final Future<dynamic> whenServiceExtensionReady = waitForServiceExtension();
|
||||||
|
final Future<dynamic> whenResumed = resumeLeniently();
|
||||||
await whenResumed;
|
await whenResumed;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -24,6 +24,7 @@ void main() {
|
|||||||
MockVMServiceClient mockClient;
|
MockVMServiceClient mockClient;
|
||||||
MockVM mockVM;
|
MockVM mockVM;
|
||||||
MockIsolate mockIsolate;
|
MockIsolate mockIsolate;
|
||||||
|
MockPeer mockPeer;
|
||||||
|
|
||||||
void expectLogContains(String message) {
|
void expectLogContains(String message) {
|
||||||
expect(log.map((LogRecord r) => '$r'), anyElement(contains(message)));
|
expect(log.map((LogRecord r) => '$r'), anyElement(contains(message)));
|
||||||
@ -35,6 +36,7 @@ void main() {
|
|||||||
mockClient = new MockVMServiceClient();
|
mockClient = new MockVMServiceClient();
|
||||||
mockVM = new MockVM();
|
mockVM = new MockVM();
|
||||||
mockIsolate = new MockIsolate();
|
mockIsolate = new MockIsolate();
|
||||||
|
mockPeer = new MockPeer();
|
||||||
when(mockClient.getVM()).thenReturn(mockVM);
|
when(mockClient.getVM()).thenReturn(mockVM);
|
||||||
when(mockVM.isolates).thenReturn(<VMRunnableIsolate>[mockIsolate]);
|
when(mockVM.isolates).thenReturn(<VMRunnableIsolate>[mockIsolate]);
|
||||||
when(mockIsolate.loadRunnable()).thenReturn(mockIsolate);
|
when(mockIsolate.loadRunnable()).thenReturn(mockIsolate);
|
||||||
@ -42,7 +44,7 @@ void main() {
|
|||||||
.thenReturn(makeMockResponse(<String, dynamic>{'status': 'ok'}));
|
.thenReturn(makeMockResponse(<String, dynamic>{'status': 'ok'}));
|
||||||
vmServiceConnectFunction = (String url) {
|
vmServiceConnectFunction = (String url) {
|
||||||
return new Future<VMServiceClientConnection>.value(
|
return new Future<VMServiceClientConnection>.value(
|
||||||
new VMServiceClientConnection(mockClient, null)
|
new VMServiceClientConnection(mockClient, mockPeer)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -53,13 +55,25 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('connects to isolate paused at start', () async {
|
test('connects to isolate paused at start', () async {
|
||||||
|
final List<String> connectionLog = <String>[];
|
||||||
|
when(mockPeer.sendRequest('streamListen', any)).thenAnswer((_) {
|
||||||
|
connectionLog.add('streamListen');
|
||||||
|
return null;
|
||||||
|
});
|
||||||
when(mockIsolate.pauseEvent).thenReturn(new MockVMPauseStartEvent());
|
when(mockIsolate.pauseEvent).thenReturn(new MockVMPauseStartEvent());
|
||||||
when(mockIsolate.resume()).thenReturn(new Future<Null>.value());
|
when(mockIsolate.resume()).thenAnswer((_) {
|
||||||
when(mockIsolate.onExtensionAdded).thenReturn(new Stream<String>.fromIterable(<String>['ext.flutter.driver']));
|
connectionLog.add('resume');
|
||||||
|
return new Future<Null>.value();
|
||||||
|
});
|
||||||
|
when(mockIsolate.onExtensionAdded).thenAnswer((_) {
|
||||||
|
connectionLog.add('onExtensionAdded');
|
||||||
|
return new Stream<String>.fromIterable(<String>['ext.flutter.driver']);
|
||||||
|
});
|
||||||
|
|
||||||
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
||||||
expect(driver, isNotNull);
|
expect(driver, isNotNull);
|
||||||
expectLogContains('Isolate is paused at start');
|
expectLogContains('Isolate is paused at start');
|
||||||
|
expect(connectionLog, <String>['streamListen', 'onExtensionAdded', 'resume']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('connects to isolate paused mid-flight', () async {
|
test('connects to isolate paused mid-flight', () async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user