Make sure all isolates start during flutter driver tests. (#61841)
This commit is contained in:
parent
d1411a1626
commit
5fa5701d72
@ -127,27 +127,6 @@ class VMServiceFlutterDriver extends FlutterDriver {
|
||||
|
||||
driver._dartVmReconnectUrl = dartVmServiceUrl;
|
||||
|
||||
// Attempts to resume the isolate, but does not crash if it fails because
|
||||
// the isolate is already resumed. There could be a race with other tools,
|
||||
// such as a debugger, any of which could have resumed the isolate.
|
||||
Future<dynamic> resumeLeniently() {
|
||||
_log('Attempting to resume isolate');
|
||||
return isolate.resume().catchError((dynamic e) {
|
||||
const int vmMustBePausedCode = 101;
|
||||
if (e is rpc.RpcException && e.code == vmMustBePausedCode) {
|
||||
// No biggie; something else must have resumed the isolate
|
||||
_log(
|
||||
'Attempted to resume an already resumed isolate. This may happen '
|
||||
'when we lose a race with another tool (usually a debugger) that '
|
||||
'is connected to the same isolate.'
|
||||
);
|
||||
} else {
|
||||
// Failed to resume due to another reason. Fail hard.
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Waits for a signal from the VM service that the extension is registered.
|
||||
///
|
||||
/// Looks at the list of loaded extensions for the current [isolateRef], as
|
||||
@ -195,11 +174,18 @@ class VMServiceFlutterDriver extends FlutterDriver {
|
||||
});
|
||||
}
|
||||
|
||||
// The Dart VM may be running with --pause-isolates-on-start.
|
||||
// Set a listener to unpause new isolates as they are ready to run,
|
||||
// otherwise they'll hang indefinitely.
|
||||
client.onIsolateRunnable.listen((VMIsolateRef isolateRef) async {
|
||||
_resumeLeniently(await isolateRef.load());
|
||||
});
|
||||
|
||||
// Attempt to resume isolate if it was paused
|
||||
if (isolate.pauseEvent is VMPauseStartEvent) {
|
||||
_log('Isolate is paused at start.');
|
||||
|
||||
await resumeLeniently();
|
||||
await _resumeLeniently(isolate);
|
||||
} else if (isolate.pauseEvent is VMPauseExitEvent ||
|
||||
isolate.pauseEvent is VMPauseBreakpointEvent ||
|
||||
isolate.pauseEvent is VMPauseExceptionEvent ||
|
||||
@ -207,7 +193,7 @@ class VMServiceFlutterDriver extends FlutterDriver {
|
||||
// If the isolate is paused for any other reason, assume the extension is
|
||||
// already there.
|
||||
_log('Isolate is paused mid-flight.');
|
||||
await resumeLeniently();
|
||||
await _resumeLeniently(isolate);
|
||||
} else if (isolate.pauseEvent is VMResumeEvent) {
|
||||
_log('Isolate is not paused. Assuming application is ready.');
|
||||
} else {
|
||||
@ -240,6 +226,27 @@ class VMServiceFlutterDriver extends FlutterDriver {
|
||||
return driver;
|
||||
}
|
||||
|
||||
/// Attempts to resume the isolate, but does not crash if it fails because
|
||||
/// the isolate is already resumed. There could be a race with other tools,
|
||||
/// such as a debugger, any of which could have resumed the isolate.
|
||||
static Future<dynamic> _resumeLeniently(VMIsolate isolate) {
|
||||
_log('Attempting to resume isolate');
|
||||
return isolate.resume().catchError((dynamic e) {
|
||||
const int vmMustBePausedCode = 101;
|
||||
if (e is rpc.RpcException && e.code == vmMustBePausedCode) {
|
||||
// No biggie; something else must have resumed the isolate
|
||||
_log(
|
||||
'Attempted to resume an already resumed isolate. This may happen '
|
||||
'when we lose a race with another tool (usually a debugger) that '
|
||||
'is connected to the same isolate.'
|
||||
);
|
||||
} else {
|
||||
// Failed to resume due to another reason. Fail hard.
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static int _nextDriverId = 0;
|
||||
|
||||
static const String _flutterExtensionMethodName = 'ext.flutter.driver';
|
||||
|
@ -35,6 +35,7 @@ void main() {
|
||||
MockVM mockVM;
|
||||
MockIsolate mockIsolate;
|
||||
MockPeer mockPeer;
|
||||
MockIsolate otherIsolate;
|
||||
|
||||
void expectLogContains(String message) {
|
||||
expect(log, anyElement(contains(message)));
|
||||
@ -45,8 +46,12 @@ void main() {
|
||||
mockClient = MockVMServiceClient();
|
||||
mockVM = MockVM();
|
||||
mockIsolate = MockIsolate();
|
||||
otherIsolate = MockIsolate();
|
||||
mockPeer = MockPeer();
|
||||
when(mockClient.getVM()).thenAnswer((_) => Future<MockVM>.value(mockVM));
|
||||
when(mockClient.onIsolateRunnable).thenAnswer((Invocation invocation) {
|
||||
return Stream<VMIsolateRef>.fromIterable(<VMIsolateRef>[otherIsolate]);
|
||||
});
|
||||
when(mockVM.isolates).thenReturn(<VMRunnableIsolate>[mockIsolate]);
|
||||
when(mockIsolate.loadRunnable()).thenAnswer((_) => Future<MockIsolate>.value(mockIsolate));
|
||||
when(mockIsolate.extensionRpcs).thenReturn(<String>[]);
|
||||
@ -60,6 +65,10 @@ void main() {
|
||||
VMServiceClientConnection(mockClient, mockPeer)
|
||||
);
|
||||
};
|
||||
when(otherIsolate.load()).thenAnswer((_) => Future<MockIsolate>.value(otherIsolate));
|
||||
when(otherIsolate.resume()).thenAnswer((Invocation invocation) {
|
||||
return Future<dynamic>.value(null);
|
||||
});
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
@ -77,15 +86,20 @@ void main() {
|
||||
connectionLog.add('resume');
|
||||
return Future<dynamic>.value(null);
|
||||
});
|
||||
when(otherIsolate.pauseEvent).thenReturn(MockVMPauseStartEvent());
|
||||
when(mockIsolate.onExtensionAdded).thenAnswer((Invocation invocation) {
|
||||
connectionLog.add('onExtensionAdded');
|
||||
return Stream<String>.fromIterable(<String>['ext.flutter.driver']);
|
||||
});
|
||||
when(otherIsolate.resume()).thenAnswer((Invocation invocation) {
|
||||
connectionLog.add('other-resume');
|
||||
return Future<dynamic>.value(null);
|
||||
});
|
||||
|
||||
final FlutterDriver driver = await FlutterDriver.connect(dartVmServiceUrl: '');
|
||||
expect(driver, isNotNull);
|
||||
expectLogContains('Isolate is paused at start');
|
||||
expect(connectionLog, <String>['resume', 'streamListen', 'onExtensionAdded']);
|
||||
expect(connectionLog, <String>['resume', 'streamListen', 'other-resume', 'onExtensionAdded']);
|
||||
});
|
||||
|
||||
test('connects to isolate paused mid-flight', () async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user