Unverified Commit 0889e143 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] increase stopApp timeout for FlutterDevice.exitApps (#55984)

parent 1e150c5d
...@@ -251,14 +251,15 @@ class FlutterDevice { ...@@ -251,14 +251,15 @@ class FlutterDevice {
return _views; return _views;
} }
Future<void> exitApps() async { Future<void> exitApps({
@visibleForTesting Duration timeoutDelay = const Duration(seconds: 10),
}) async {
if (!device.supportsFlutterExit) { if (!device.supportsFlutterExit) {
await device.stopApp(package); return device.stopApp(package);
return;
} }
await refreshViews(); await refreshViews();
if (views == null || views.isEmpty) { if (views == null || views.isEmpty) {
return; return device.stopApp(package);
} }
// If any of the flutter views are paused, we might not be able to // If any of the flutter views are paused, we might not be able to
// cleanly exit since the service extension may not have been registered. // cleanly exit since the service extension may not have been registered.
...@@ -269,8 +270,7 @@ class FlutterDevice { ...@@ -269,8 +270,7 @@ class FlutterDevice {
continue; continue;
} }
if (isPauseEvent(isolate.pauseEvent.kind)) { if (isPauseEvent(isolate.pauseEvent.kind)) {
await device.stopApp(package); return device.stopApp(package);
return;
} }
} }
for (final FlutterView view in views) { for (final FlutterView view in views) {
...@@ -288,11 +288,12 @@ class FlutterDevice { ...@@ -288,11 +288,12 @@ class FlutterDevice {
stackTrace: stackTrace, stackTrace: stackTrace,
); );
}) })
.timeout(const Duration(seconds: 2), onTimeout: () { .timeout(timeoutDelay, onTimeout: () {
// TODO(jonahwilliams): this only seems to fail on CI in the // TODO(jonahwilliams): this only seems to fail on CI in the
// flutter_attach_android_test. This log should help verify this // flutter_attach_android_test. This log should help verify this
// is where the tool is getting stuck. // is where the tool is getting stuck.
globals.logger.printTrace('error: vm service shutdown failed'); globals.logger.printTrace('error: vm service shutdown failed');
return device.stopApp(package);
}); });
} }
......
...@@ -676,6 +676,7 @@ extension FlutterVmService on vm_service.VmService { ...@@ -676,6 +676,7 @@ extension FlutterVmService on vm_service.VmService {
'ext.flutter.exit', 'ext.flutter.exit',
isolateId: isolateId, isolateId: isolateId,
).catchError((dynamic error, StackTrace stackTrace) { ).catchError((dynamic error, StackTrace stackTrace) {
globals.logger.printTrace('Failure in ext.flutter.exit: $error\n$stackTrace');
// Do nothing on sentinel or exception, the isolate already exited. // Do nothing on sentinel or exception, the isolate already exited.
}, test: (dynamic error) => error is vm_service.SentinelException || error is vm_service.RPCError); }, test: (dynamic error) => error is vm_service.SentinelException || error is vm_service.RPCError);
} }
......
...@@ -815,6 +815,51 @@ void main() { ...@@ -815,6 +815,51 @@ void main() {
expect(fakeVmServiceHost.hasRemainingExpectations, false); expect(fakeVmServiceHost.hasRemainingExpectations, false);
})); }));
test('FlutterDevice will call stopApp if the exit request times out', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: '_flutter.listViews',
args: null,
jsonResponse: <String, Object>{
'views': <Object>[
fakeFlutterView.toJson(),
],
},
),
FakeVmServiceRequest(
id: '2',
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
},
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
id: '3',
method: 'ext.flutter.exit',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
},
// Intentionally do not close isolate.
close: false,
)
]);
final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice,
<FlutterView>[ fakeFlutterView ],
);
flutterDevice.vmService = fakeVmServiceHost.vmService;
when(mockDevice.supportsFlutterExit).thenReturn(true);
await flutterDevice.exitApps(
timeoutDelay: Duration.zero,
);
verify(mockDevice.stopApp(any)).called(1);
expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('FlutterDevice will exit an un-paused isolate', () => testbed.run(() async { test('FlutterDevice will exit an un-paused isolate', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
FakeVmServiceRequest( FakeVmServiceRequest(
......
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