Bug 1959614 - [bidi] Update NetworkDecodedBodySizeMap to be synchronous r=webdriver-reviewers,whimboo
The timing difference introduced by the async NetworkDecodedBodySizeMap leads to regressions in playwright tests. I propose to only use a synchronous approach until we have a better understanding of why the playwright routing logic fails in this case. Differential Revision: https://phabricator.services.mozilla.com/D245112
This commit is contained in:
@@ -2,31 +2,35 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This map will return the default value of 0 if the decoded body size for
|
||||
* a given channel was not received yet.
|
||||
*
|
||||
* Bug 1959614: The NetworkDecodedBodySizeMap used to setup promises to wait for
|
||||
* the decoded body size to be ready. However the timing differences from this
|
||||
* change leads to regressions in Playwright tests. The new implementation of
|
||||
* the map is only synchronous and if the size was not received yet, 0 will be
|
||||
* returned. In theory, the decoded body size should be set via
|
||||
* http-on-before-stop-request which should be received before the request is
|
||||
* stopped.
|
||||
*/
|
||||
export class NetworkDecodedBodySizeMap {
|
||||
#authenticationAttemptsMap;
|
||||
#channelIdToBodySizePromiseMap;
|
||||
#channelIdToBodySizeMap;
|
||||
|
||||
constructor() {
|
||||
this.#authenticationAttemptsMap = new Map();
|
||||
this.#channelIdToBodySizePromiseMap = new Map();
|
||||
this.#channelIdToBodySizeMap = new Map();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.#authenticationAttemptsMap = null;
|
||||
this.#channelIdToBodySizePromiseMap = null;
|
||||
this.#channelIdToBodySizeMap = null;
|
||||
}
|
||||
|
||||
async getDecodedBodySize(channelId) {
|
||||
if (!this.#channelIdToBodySizePromiseMap.has(channelId)) {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
this.#channelIdToBodySizePromiseMap.set(channelId, {
|
||||
promise,
|
||||
resolve,
|
||||
});
|
||||
}
|
||||
const mapEntry = this.#channelIdToBodySizePromiseMap.get(channelId);
|
||||
await mapEntry.promise;
|
||||
return mapEntry.decodedBodySize;
|
||||
getDecodedBodySize(channelId) {
|
||||
const decodedBodySize = this.#channelIdToBodySizeMap.get(channelId);
|
||||
return typeof decodedBodySize === "number" ? decodedBodySize : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,22 +76,11 @@ export class NetworkDecodedBodySizeMap {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.#channelIdToBodySizePromiseMap.has(channelId)) {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
this.#channelIdToBodySizePromiseMap.set(channelId, {
|
||||
decodedBodySize,
|
||||
promise,
|
||||
resolve,
|
||||
});
|
||||
}
|
||||
const mapEntry = this.#channelIdToBodySizePromiseMap.get(channelId);
|
||||
|
||||
mapEntry.decodedBodySize = decodedBodySize;
|
||||
mapEntry.resolve(decodedBodySize);
|
||||
this.#channelIdToBodySizeMap.set(channelId, decodedBodySize);
|
||||
}
|
||||
|
||||
delete(channelId) {
|
||||
this.#authenticationAttemptsMap.delete(channelId);
|
||||
this.#channelIdToBodySizePromiseMap.delete(channelId);
|
||||
this.#channelIdToBodySizeMap.delete(channelId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ export class NetworkEventRecord {
|
||||
}
|
||||
}
|
||||
|
||||
#onChannelCompleted = async () => {
|
||||
#onChannelCompleted = () => {
|
||||
if (this.#request.alreadyCompleted) {
|
||||
return;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ export class NetworkEventRecord {
|
||||
// sizes.
|
||||
const sizes = {};
|
||||
if (this.#request.isHttpChannel && !blockedReason) {
|
||||
sizes.decodedBodySize = await this.#decodedBodySizeMap.getDecodedBodySize(
|
||||
sizes.decodedBodySize = this.#decodedBodySizeMap.getDecodedBodySize(
|
||||
this.#request.channel.channelId
|
||||
);
|
||||
sizes.encodedBodySize = this.#request.channel.encodedBodySize;
|
||||
|
||||
@@ -7,123 +7,36 @@ const { NetworkDecodedBodySizeMap } = ChromeUtils.importESModule(
|
||||
"chrome://remote/content/shared/NetworkDecodedBodySizeMap.sys.mjs"
|
||||
);
|
||||
|
||||
add_task(async function test_get_set_delete_decodedBodySize() {
|
||||
add_task(async function test_decodedBodySizeMap() {
|
||||
const map = new NetworkDecodedBodySizeMap();
|
||||
const channelId = 1;
|
||||
let onDecodedBodySize = map.getDecodedBodySize(channelId);
|
||||
|
||||
ok(
|
||||
!(await hasPromiseResolved(onDecodedBodySize)),
|
||||
"onDecodedBodySize has not resolved yet"
|
||||
equal(
|
||||
map.getDecodedBodySize(channelId),
|
||||
0,
|
||||
"By default the decode body size is 0"
|
||||
);
|
||||
|
||||
const expectedBodySize = 12;
|
||||
let expectedBodySize = 12;
|
||||
map.setDecodedBodySize(channelId, expectedBodySize);
|
||||
ok(
|
||||
await hasPromiseResolved(onDecodedBodySize),
|
||||
"onDecodedBodySize has resolved"
|
||||
);
|
||||
|
||||
equal(
|
||||
await onDecodedBodySize,
|
||||
map.getDecodedBodySize(channelId),
|
||||
expectedBodySize,
|
||||
"decodedBodySize has the expected value"
|
||||
"The expected body size was set"
|
||||
);
|
||||
|
||||
// Check that calling getDecodedBodySize for the same channel id resolves
|
||||
// immediately
|
||||
onDecodedBodySize = map.getDecodedBodySize(channelId);
|
||||
ok(
|
||||
await hasPromiseResolved(onDecodedBodySize),
|
||||
"onDecodedBodySize has resolved"
|
||||
);
|
||||
expectedBodySize = 24;
|
||||
map.setDecodedBodySize(channelId, expectedBodySize);
|
||||
equal(
|
||||
await onDecodedBodySize,
|
||||
map.getDecodedBodySize(channelId),
|
||||
expectedBodySize,
|
||||
"decodedBodySize has the expected value"
|
||||
"The expected body size was updated"
|
||||
);
|
||||
|
||||
// Delete the entry for channelId and check that the promise no longer
|
||||
// resolves.
|
||||
map.delete(channelId);
|
||||
onDecodedBodySize = map.getDecodedBodySize(channelId);
|
||||
ok(
|
||||
!(await hasPromiseResolved(onDecodedBodySize)),
|
||||
"onDecodedBodySize has not resolved yet"
|
||||
);
|
||||
|
||||
map.destroy();
|
||||
});
|
||||
|
||||
add_task(async function test_set_other_channel() {
|
||||
const map = new NetworkDecodedBodySizeMap();
|
||||
const channelId = 1;
|
||||
const otherChannelId = 2;
|
||||
const onDecodedBodySize = map.getDecodedBodySize(channelId);
|
||||
|
||||
ok(
|
||||
!(await hasPromiseResolved(onDecodedBodySize)),
|
||||
"onDecodedBodySize has not resolved yet"
|
||||
);
|
||||
|
||||
map.setDecodedBodySize(otherChannelId, 12);
|
||||
|
||||
ok(
|
||||
!(await hasPromiseResolved(onDecodedBodySize)),
|
||||
"onDecodedBodySize has still not resolved"
|
||||
);
|
||||
|
||||
map.destroy();
|
||||
});
|
||||
|
||||
add_task(async function test_get_twice() {
|
||||
const map = new NetworkDecodedBodySizeMap();
|
||||
const channelId = 1;
|
||||
const onDecodedBodySize1 = map.getDecodedBodySize(channelId);
|
||||
|
||||
ok(
|
||||
!(await hasPromiseResolved(onDecodedBodySize1)),
|
||||
"onDecodedBodySize1 has not resolved yet"
|
||||
);
|
||||
|
||||
// Call getDecodedBodySize another time to check we still wait for the promise
|
||||
const onDecodedBodySize2 = map.getDecodedBodySize(channelId);
|
||||
ok(
|
||||
!(await hasPromiseResolved(onDecodedBodySize2)),
|
||||
"onDecodedBodySize2 has not resolved yet"
|
||||
);
|
||||
|
||||
// Set the body size and check that both promises resolved the same value.
|
||||
const expectedBodySize = 12;
|
||||
map.setDecodedBodySize(channelId, expectedBodySize);
|
||||
ok(
|
||||
await hasPromiseResolved(onDecodedBodySize1),
|
||||
"onDecodedBodySize1 has resolved"
|
||||
);
|
||||
ok(
|
||||
await hasPromiseResolved(onDecodedBodySize2),
|
||||
"onDecodedBodySize2 has resolved"
|
||||
);
|
||||
|
||||
equal(
|
||||
await onDecodedBodySize1,
|
||||
expectedBodySize,
|
||||
"decodedBodySize has the expected value"
|
||||
);
|
||||
equal(
|
||||
await onDecodedBodySize2,
|
||||
expectedBodySize,
|
||||
"decodedBodySize has the expected value"
|
||||
);
|
||||
|
||||
// Set another body size and check that further calls to getDecodedBodySize
|
||||
// resolve the new value.
|
||||
const otherBodySize = 42;
|
||||
map.setDecodedBodySize(channelId, otherBodySize);
|
||||
equal(
|
||||
await map.getDecodedBodySize(channelId),
|
||||
otherBodySize,
|
||||
"decodedBodySize has the expected value"
|
||||
equal(
|
||||
map.getDecodedBodySize(channelId),
|
||||
0,
|
||||
"After deleting the channel entry, the size is back to 0"
|
||||
);
|
||||
|
||||
map.destroy();
|
||||
|
||||
Reference in New Issue
Block a user