From 73c9fa3addd87eb50bc13129224ee467ad895d4b Mon Sep 17 00:00:00 2001 From: Liang Gong Date: Tue, 16 Jan 2024 10:24:51 -0800 Subject: [PATCH] feat(e2e): support setting Chromium protocol timeout in CLI (#107) Summary: Allow tweaking the Chromium protocol timeout for page crashed with error: 'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'. Differential Revision: D52742549 fbshipit-source-id: 21b5cfb3b4f1d2bd88a478012185f34505b3e453 --- .../cli/src/commands/RunMeasureCommand.ts | 2 + packages/cli/src/commands/WarmupAppCommand.ts | 2 + .../commands/snapshot/TakeSnapshotCommand.ts | 2 + .../e2e/SetChromiumProtocolTimeoutOption.ts | 48 +++++++++++++++++++ .../cli/src/options/lib/OptionConstant.ts | 1 + website/docs/cli/CLI-commands.md | 10 ++++ 6 files changed, 65 insertions(+) create mode 100644 packages/cli/src/options/e2e/SetChromiumProtocolTimeoutOption.ts diff --git a/packages/cli/src/commands/RunMeasureCommand.ts b/packages/cli/src/commands/RunMeasureCommand.ts index f8c21f61d..b29a7faed 100644 --- a/packages/cli/src/commands/RunMeasureCommand.ts +++ b/packages/cli/src/commands/RunMeasureCommand.ts @@ -35,6 +35,7 @@ import DisableWebSecurityOption from '../options/e2e/DisableWebSecurityOption'; import EnableJSRewriteOption from '../options/e2e/EnableJSRewriteOption'; import EnableJSInterceptOption from '../options/e2e/EnableJSInterceptOption'; import SetChromiumBinaryOption from '../options/e2e/SetChromiumBinaryOption'; +import SetChromiumProtocolTimeoutOption from '../options/e2e/SetChromiumProtocolTimeoutOption'; export default class RunMeasureCommand extends BaseCommand { getCommandName(): string { @@ -73,6 +74,7 @@ export default class RunMeasureCommand extends BaseCommand { new RemoteBrowserDebugOption(), new ScenarioFileOption(), new SetChromiumBinaryOption(), + new SetChromiumProtocolTimeoutOption(), new SetDeviceOption(), new SetUserAgentOption(), new DisableXvfbOption(), diff --git a/packages/cli/src/commands/WarmupAppCommand.ts b/packages/cli/src/commands/WarmupAppCommand.ts index 5cb884696..ec3e8e753 100644 --- a/packages/cli/src/commands/WarmupAppCommand.ts +++ b/packages/cli/src/commands/WarmupAppCommand.ts @@ -29,6 +29,7 @@ import DisableWebSecurityOption from '../options/e2e/DisableWebSecurityOption'; import EnableJSRewriteOption from '../options/e2e/EnableJSRewriteOption'; import EnableJSInterceptOption from '../options/e2e/EnableJSInterceptOption'; import SetChromiumBinaryOption from '../options/e2e/SetChromiumBinaryOption'; +import SetChromiumProtocolTimeoutOption from '../options/e2e/SetChromiumProtocolTimeoutOption'; export default class FBWarmupAppCommand extends BaseCommand { getCommandName(): string { @@ -59,6 +60,7 @@ export default class FBWarmupAppCommand extends BaseCommand { new RemoteBrowserDebugOption(), new ScenarioFileOption(), new SetChromiumBinaryOption(), + new SetChromiumProtocolTimeoutOption(), new SetDeviceOption(), new SetUserAgentOption(), new DisableXvfbOption(), diff --git a/packages/cli/src/commands/snapshot/TakeSnapshotCommand.ts b/packages/cli/src/commands/snapshot/TakeSnapshotCommand.ts index 81f6d4bf7..2a24fbf05 100644 --- a/packages/cli/src/commands/snapshot/TakeSnapshotCommand.ts +++ b/packages/cli/src/commands/snapshot/TakeSnapshotCommand.ts @@ -36,6 +36,7 @@ import EnableJSRewriteOption from '../../options/e2e/EnableJSRewriteOption'; import EnableJSInterceptOption from '../../options/e2e/EnableJSInterceptOption'; import TargetWorkerOption from '../../options/e2e/TargetWorkerOption'; import SetChromiumBinaryOption from '../../options/e2e/SetChromiumBinaryOption'; +import SetChromiumProtocolTimeoutOption from '../../options/e2e/SetChromiumProtocolTimeoutOption'; export default class TakeSnapshotCommand extends BaseCommand { getCommandName(): string { @@ -77,6 +78,7 @@ export default class TakeSnapshotCommand extends BaseCommand { new RemoteBrowserDebugOption(), new ScenarioFileOption(), new SetChromiumBinaryOption(), + new SetChromiumProtocolTimeoutOption(), new SetDeviceOption(), new SetUserAgentOption(), new DisableXvfbOption(), diff --git a/packages/cli/src/options/e2e/SetChromiumProtocolTimeoutOption.ts b/packages/cli/src/options/e2e/SetChromiumProtocolTimeoutOption.ts new file mode 100644 index 000000000..7d4fb9cd1 --- /dev/null +++ b/packages/cli/src/options/e2e/SetChromiumProtocolTimeoutOption.ts @@ -0,0 +1,48 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @oncall web_perf_infra + */ +import type {ParsedArgs} from 'minimist'; +import {MemLabConfig} from '@memlab/core'; + +import {info, utils, BaseOption} from '@memlab/core'; +import optionConstants from '../lib/OptionConstant'; + +export default class SetChromiumProtocolTimeoutOption extends BaseOption { + getOptionName(): string { + return optionConstants.optionNames.CHROMIUM_PROTOCOL_TIMEOUT; + } + + getDescription(): string { + return ( + 'set the protocol timeout for chromium connection (in ms). \n' + + 'The current default value is 180000, you may want to increase the ' + + 'timeout via this flag when the heap snapshot is ' + + 'too big (e.g., over 1GB) and the Page crashed with error: ' + + "'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'." + ); + } + + async parse(config: MemLabConfig, args: ParsedArgs): Promise { + const name = this.getOptionName(); + const arg = args[name]; + if (arg) { + const timeout = parseInt(arg, 10); + if (Number.isNaN(timeout)) { + utils.haltOrThrow( + `Invalid Chromium protocol timeout value: ${arg}. ` + + 'It must be a number.', + ); + } + if (config.verbose) { + info.lowLevel(`Set Chromium protocol timeout to ${timeout}.`); + } + config.puppeteerConfig.protocolTimeout = timeout; + } + } +} diff --git a/packages/cli/src/options/lib/OptionConstant.ts b/packages/cli/src/options/lib/OptionConstant.ts index 0d3c5e78f..776fd3dda 100644 --- a/packages/cli/src/options/lib/OptionConstant.ts +++ b/packages/cli/src/options/lib/OptionConstant.ts @@ -18,6 +18,7 @@ const optionNames = { CONTROL_SNAPSHOT: 'control-snapshot', CONTROL_WORK_DIR: 'control-work-dir', CHROMIUM_BINARY: 'chromium-binary', + CHROMIUM_PROTOCOL_TIMEOUT: 'protocol-timeout', DEVICE: 'device', DISABLE_WEB_SECURITY: 'disable-web-security', DISABLE_XVFB: 'disable-xvfb', diff --git a/website/docs/cli/CLI-commands.md b/website/docs/cli/CLI-commands.md index 7c0737a59..fc6a27332 100644 --- a/website/docs/cli/CLI-commands.md +++ b/website/docs/cli/CLI-commands.md @@ -33,6 +33,8 @@ memlab run --scenario /tmp/test-scenario.js --work-dir /tmp/test-1/ * **`--local-puppeteer`**: enable remote browser instance debugging via local puppeteer * **`--scenario`**: set file path loading test scenario * **`--chromium-binary`**: set the chromium binary for E2E run + * **`--protocol-timeout`**: set the protocol timeout for chromium connection (in ms). +The current default value is 180000, you may want to increase the timeout via this flag when the heap snapshot is too big (e.g., over 1GB) and the Page crashed with error: 'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'. * **`--device`**: set the device type to emulate * **`--user-agent`**: set the UserAgent string in browser (for E2E interaction), otherwise it uses the default UserAgent from Chromium * **`--disable-xvfb`**: disable Xvfb (X virtual framebuffer) for simulating headful browser rendering @@ -508,6 +510,8 @@ memlab measure --scenario /tmp/test-scenario.js --work-dir /tmp/test-1/ * **`--local-puppeteer`**: enable remote browser instance debugging via local puppeteer * **`--scenario`**: set file path loading test scenario * **`--chromium-binary`**: set the chromium binary for E2E run + * **`--protocol-timeout`**: set the protocol timeout for chromium connection (in ms). +The current default value is 180000, you may want to increase the timeout via this flag when the heap snapshot is too big (e.g., over 1GB) and the Page crashed with error: 'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'. * **`--device`**: set the device type to emulate * **`--user-agent`**: set the UserAgent string in browser (for E2E interaction), otherwise it uses the default UserAgent from Chromium * **`--disable-xvfb`**: disable Xvfb (X virtual framebuffer) for simulating headful browser rendering @@ -543,6 +547,8 @@ memlab warmup --scenario /tmp/test-scenario.js * **`--local-puppeteer`**: enable remote browser instance debugging via local puppeteer * **`--scenario`**: set file path loading test scenario * **`--chromium-binary`**: set the chromium binary for E2E run + * **`--protocol-timeout`**: set the protocol timeout for chromium connection (in ms). +The current default value is 180000, you may want to increase the timeout via this flag when the heap snapshot is too big (e.g., over 1GB) and the Page crashed with error: 'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'. * **`--device`**: set the device type to emulate * **`--user-agent`**: set the UserAgent string in browser (for E2E interaction), otherwise it uses the default UserAgent from Chromium * **`--disable-xvfb`**: disable Xvfb (X virtual framebuffer) for simulating headful browser rendering @@ -616,6 +622,8 @@ memlab snapshot --scenario /tmp/test-scenario.js --work-dir /tmp/test-1/ * **`--local-puppeteer`**: enable remote browser instance debugging via local puppeteer * **`--scenario`**: set file path loading test scenario * **`--chromium-binary`**: set the chromium binary for E2E run + * **`--protocol-timeout`**: set the protocol timeout for chromium connection (in ms). +The current default value is 180000, you may want to increase the timeout via this flag when the heap snapshot is too big (e.g., over 1GB) and the Page crashed with error: 'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'. * **`--device`**: set the device type to emulate * **`--user-agent`**: set the UserAgent string in browser (for E2E interaction), otherwise it uses the default UserAgent from Chromium * **`--disable-xvfb`**: disable Xvfb (X virtual framebuffer) for simulating headful browser rendering @@ -658,6 +666,8 @@ memlab warmup-and-snapshot --scenario /tmp/test-scenario.js --work-dir /tmp/test * **`--local-puppeteer`**: enable remote browser instance debugging via local puppeteer * **`--scenario`**: set file path loading test scenario * **`--chromium-binary`**: set the chromium binary for E2E run + * **`--protocol-timeout`**: set the protocol timeout for chromium connection (in ms). +The current default value is 180000, you may want to increase the timeout via this flag when the heap snapshot is too big (e.g., over 1GB) and the Page crashed with error: 'ProtocolError: HeapProfiler.takeHeapSnapshot timed out'. * **`--device`**: set the device type to emulate * **`--user-agent`**: set the UserAgent string in browser (for E2E interaction), otherwise it uses the default UserAgent from Chromium * **`--disable-xvfb`**: disable Xvfb (X virtual framebuffer) for simulating headful browser rendering