Unverified Commit ad540e4f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] retry chrome launch up to 3 times (#85162)

parent e67113c1
......@@ -249,7 +249,9 @@ class ChromiumLauncher {
// Keep attempting to launch the browser until one of:
// - Chrome launched successfully, in which case we just return from the loop.
// - The tool detected an unretriable Chrome error, in which case we throw ToolExit.
// - The tool reached the maximum retry count, in which case we throw ToolExit.
const int kMaxRetries = 3;
int retry = 0;
while (true) {
final Process process = await _processManager.start(args);
......@@ -263,6 +265,7 @@ class ChromiumLauncher {
// Wait until the DevTools are listening before trying to connect. This is
// only required for flutter_test --platform=chrome and not flutter run.
bool hitGlibcBug = false;
bool shouldRetry = false;
await process.stderr
.transform(utf8.decoder)
.transform(const LineSplitter())
......@@ -270,6 +273,7 @@ class ChromiumLauncher {
_logger.printTrace('[CHROME]:$line');
if (line.contains(_kGlibcError)) {
hitGlibcBug = true;
shouldRetry = true;
}
return line;
})
......@@ -282,17 +286,22 @@ class ChromiumLauncher {
// Return value unused.
return '';
}
_logger.printTrace('Failed to launch browser. Command used to launch it: ${args.join(' ')}');
if (retry >= kMaxRetries) {
_logger.printTrace('Failed to launch browser after $kMaxRetries tries. Command used to launch it: ${args.join(' ')}');
throw ToolExit(
'Failed to launch browser. Make sure you are using an up-to-date '
'Chrome or Edge. Otherwise, consider using -d web-server instead '
'and filing an issue at https://github.com/flutter/flutter/issues.',
);
}
shouldRetry = true;
return '';
});
if (!hitGlibcBug) {
if (!hitGlibcBug && !shouldRetry) {
return process;
}
retry += 1;
// A precaution that avoids accumulating browser processes, in case the
// glibc bug doesn't cause the browser to quit and we keep looping and
......
......@@ -461,7 +461,45 @@ void main() {
);
});
testWithoutContext('gives up retrying when a non-glibc error happens', () async {
testWithoutContext('can retry launch when chrome fails to start', () async {
const List<String> args = <String>[
'example_chrome',
'--user-data-dir=/.tmp_rand0/flutter_tools_chrome_device.rand0',
'--remote-debugging-port=12345',
...kChromeArgs,
'--headless',
'--disable-gpu',
'--no-sandbox',
'--window-size=2400,1800',
'example_url',
];
// Pretend to random error 3 times.
for (int i = 0; i < 3; i++) {
processManager.addCommand(const FakeCommand(
command: args,
stderr: 'BLAH BLAH',
));
}
// Succeed on the 4th try.
processManager.addCommand(const FakeCommand(
command: args,
stderr: kDevtoolsStderr,
));
expect(
() async => chromeLauncher.launch(
'example_url',
skipCheck: true,
headless: true,
),
returnsNormally,
);
});
testWithoutContext('gives up retrying when an error happens more than 3 times', () async {
for (int i = 0; i < 4; i++) {
processManager.addCommand(const FakeCommand(
command: <String>[
'example_chrome',
......@@ -476,6 +514,7 @@ void main() {
],
stderr: 'nothing in the std error indicating glibc error',
));
}
expect(
() async => chromeLauncher.launch(
......
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