Commit f7d62aaa authored by Yegor's avatar Yegor Committed by GitHub

fix driver connection flakiness (#9968)

parent abaf2901
...@@ -212,11 +212,25 @@ class FlutterDriver { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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 {
......
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