Skip to content

Commit 5fa5701

Browse files
authoredJul 24, 2020
Make sure all isolates start during flutter driver tests. (flutter#61841)
1 parent d1411a1 commit 5fa5701

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed
 

‎packages/flutter_driver/lib/src/driver/vmservice_driver.dart

+30-23
Original file line numberDiff line numberDiff line change
@@ -127,27 +127,6 @@ class VMServiceFlutterDriver extends FlutterDriver {
127127

128128
driver._dartVmReconnectUrl = dartVmServiceUrl;
129129

130-
// Attempts to resume the isolate, but does not crash if it fails because
131-
// the isolate is already resumed. There could be a race with other tools,
132-
// such as a debugger, any of which could have resumed the isolate.
133-
Future<dynamic> resumeLeniently() {
134-
_log('Attempting to resume isolate');
135-
return isolate.resume().catchError((dynamic e) {
136-
const int vmMustBePausedCode = 101;
137-
if (e is rpc.RpcException && e.code == vmMustBePausedCode) {
138-
// No biggie; something else must have resumed the isolate
139-
_log(
140-
'Attempted to resume an already resumed isolate. This may happen '
141-
'when we lose a race with another tool (usually a debugger) that '
142-
'is connected to the same isolate.'
143-
);
144-
} else {
145-
// Failed to resume due to another reason. Fail hard.
146-
throw e;
147-
}
148-
});
149-
}
150-
151130
/// Waits for a signal from the VM service that the extension is registered.
152131
///
153132
/// Looks at the list of loaded extensions for the current [isolateRef], as
@@ -195,19 +174,26 @@ class VMServiceFlutterDriver extends FlutterDriver {
195174
});
196175
}
197176

177+
// The Dart VM may be running with --pause-isolates-on-start.
178+
// Set a listener to unpause new isolates as they are ready to run,
179+
// otherwise they'll hang indefinitely.
180+
client.onIsolateRunnable.listen((VMIsolateRef isolateRef) async {
181+
_resumeLeniently(await isolateRef.load());
182+
});
183+
198184
// Attempt to resume isolate if it was paused
199185
if (isolate.pauseEvent is VMPauseStartEvent) {
200186
_log('Isolate is paused at start.');
201187

202-
await resumeLeniently();
188+
await _resumeLeniently(isolate);
203189
} else if (isolate.pauseEvent is VMPauseExitEvent ||
204190
isolate.pauseEvent is VMPauseBreakpointEvent ||
205191
isolate.pauseEvent is VMPauseExceptionEvent ||
206192
isolate.pauseEvent is VMPauseInterruptedEvent) {
207193
// If the isolate is paused for any other reason, assume the extension is
208194
// already there.
209195
_log('Isolate is paused mid-flight.');
210-
await resumeLeniently();
196+
await _resumeLeniently(isolate);
211197
} else if (isolate.pauseEvent is VMResumeEvent) {
212198
_log('Isolate is not paused. Assuming application is ready.');
213199
} else {
@@ -240,6 +226,27 @@ class VMServiceFlutterDriver extends FlutterDriver {
240226
return driver;
241227
}
242228

229+
/// Attempts to resume the isolate, but does not crash if it fails because
230+
/// the isolate is already resumed. There could be a race with other tools,
231+
/// such as a debugger, any of which could have resumed the isolate.
232+
static Future<dynamic> _resumeLeniently(VMIsolate isolate) {
233+
_log('Attempting to resume isolate');
234+
return isolate.resume().catchError((dynamic e) {
235+
const int vmMustBePausedCode = 101;
236+
if (e is rpc.RpcException && e.code == vmMustBePausedCode) {
237+
// No biggie; something else must have resumed the isolate
238+
_log(
239+
'Attempted to resume an already resumed isolate. This may happen '
240+
'when we lose a race with another tool (usually a debugger) that '
241+
'is connected to the same isolate.'
242+
);
243+
} else {
244+
// Failed to resume due to another reason. Fail hard.
245+
throw e;
246+
}
247+
});
248+
}
249+
243250
static int _nextDriverId = 0;
244251

245252
static const String _flutterExtensionMethodName = 'ext.flutter.driver';

‎packages/flutter_driver/test/flutter_driver_test.dart

+15-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ void main() {
3535
MockVM mockVM;
3636
MockIsolate mockIsolate;
3737
MockPeer mockPeer;
38+
MockIsolate otherIsolate;
3839

3940
void expectLogContains(String message) {
4041
expect(log, anyElement(contains(message)));
@@ -45,8 +46,12 @@ void main() {
4546
mockClient = MockVMServiceClient();
4647
mockVM = MockVM();
4748
mockIsolate = MockIsolate();
49+
otherIsolate = MockIsolate();
4850
mockPeer = MockPeer();
4951
when(mockClient.getVM()).thenAnswer((_) => Future<MockVM>.value(mockVM));
52+
when(mockClient.onIsolateRunnable).thenAnswer((Invocation invocation) {
53+
return Stream<VMIsolateRef>.fromIterable(<VMIsolateRef>[otherIsolate]);
54+
});
5055
when(mockVM.isolates).thenReturn(<VMRunnableIsolate>[mockIsolate]);
5156
when(mockIsolate.loadRunnable()).thenAnswer((_) => Future<MockIsolate>.value(mockIsolate));
5257
when(mockIsolate.extensionRpcs).thenReturn(<String>[]);
@@ -60,6 +65,10 @@ void main() {
6065
VMServiceClientConnection(mockClient, mockPeer)
6166
);
6267
};
68+
when(otherIsolate.load()).thenAnswer((_) => Future<MockIsolate>.value(otherIsolate));
69+
when(otherIsolate.resume()).thenAnswer((Invocation invocation) {
70+
return Future<dynamic>.value(null);
71+
});
6372
});
6473

6574
tearDown(() async {
@@ -77,15 +86,20 @@ void main() {
7786
connectionLog.add('resume');
7887
return Future<dynamic>.value(null);
7988
});
89+
when(otherIsolate.pauseEvent).thenReturn(MockVMPauseStartEvent());
8090
when(mockIsolate.onExtensionAdded).thenAnswer((Invocation invocation) {
8191
connectionLog.add('onExtensionAdded');
8292
return Stream<String>.fromIterable(<String>['ext.flutter.driver']);
8393
});
94+
when(otherIsolate.resume()).thenAnswer((Invocation invocation) {
95+
connectionLog.add('other-resume');
96+
return Future<dynamic>.value(null);
97+
});
8498

8599
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
86100
expect(driver, isNotNull);
87101
expectLogContains('Isolate is paused at start');
88-
expect(connectionLog, <String>['resume', 'streamListen', 'onExtensionAdded']);
102+
expect(connectionLog, <String>['resume', 'streamListen', 'other-resume', 'onExtensionAdded']);
89103
});
90104

91105
test('connects to isolate paused mid-flight', () async {

0 commit comments

Comments
 (0)
Please sign in to comment.