summaryrefslogtreecommitdiffstats
path: root/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js')
-rw-r--r--devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js70
1 files changed, 70 insertions, 0 deletions
diff --git a/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js b/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js
new file mode 100644
index 0000000000..557d14380a
--- /dev/null
+++ b/devtools/shared/commands/resource/tests/browser_resources_target_resources_race.js
@@ -0,0 +1,70 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Test initial target resources are correctly retrieved even when several calls
+ * to watchResources are made simultaneously.
+ *
+ * This checks a race condition which occurred when calling watchResources
+ * simultaneously. This made the "second" call to watchResources miss existing
+ * resources (in case those are emitted from the target instead of the watcher).
+ * See Bug 1663896.
+ */
+add_task(async function () {
+ // Disable the preloaded process as it creates processes intermittently
+ // which forces the emission of RDP requests we aren't correctly waiting for.
+ await pushPref("dom.ipc.processPrelaunch.enabled", false);
+
+ const { client, resourceCommand, targetCommand } =
+ await initMultiProcessResourceCommand();
+
+ const expectedPlatformMessage = "expectedMessage";
+
+ info("Log a message *before* calling ResourceCommand.watchResources");
+ Services.console.logStringMessage(expectedPlatformMessage);
+
+ info("Call watchResources from 2 separate call sites consecutively");
+
+ // Empty onAvailable callback for CSS MESSAGES, we only want to check that
+ // the second resource we watch correctly provides existing resources.
+ const onCssMessageAvailable = resources => {};
+
+ // First call to watchResources.
+ // We do not await on `watchPromise1` here, in order to simulate simultaneous
+ // calls to watchResources (which could come from 2 separate modules in a real
+ // scenario).
+ const initialWatchPromise = resourceCommand.watchResources(
+ [resourceCommand.TYPES.CSS_MESSAGE],
+ {
+ onAvailable: onCssMessageAvailable,
+ }
+ );
+
+ // `waitForNextResource` will trigger another call to `watchResources`.
+ const { onResource: onMessageReceived } =
+ await resourceCommand.waitForNextResource(
+ resourceCommand.TYPES.PLATFORM_MESSAGE,
+ {
+ ignoreExistingResources: false,
+ predicate: r => r.message === expectedPlatformMessage,
+ }
+ );
+
+ info("Waiting for the expected message to be received");
+ await onMessageReceived;
+ ok(true, "All the expected messages were received");
+
+ info("Wait for the other watchResources promise to finish");
+ await initialWatchPromise;
+
+ // Unwatch all resources.
+ resourceCommand.unwatchResources([resourceCommand.TYPES.CSS_MESSAGE], {
+ onAvailable: onCssMessageAvailable,
+ });
+
+ Services.console.reset();
+ targetCommand.destroy();
+ await client.close();
+});