75 lines
3 KiB
JavaScript
75 lines
3 KiB
JavaScript
// META: script=/common/get-host-info.sub.js
|
|
// META: script=/common/utils.js
|
|
// META: script=/common/dispatcher/dispatcher.js
|
|
// META: script=/html/cross-origin-embedder-policy/credentialless/resources/common.js
|
|
// META: script=./resources/common.js
|
|
|
|
// A script acquiring a lock. It can be released using window.releaseLocks
|
|
const acquire_script = (key, response) => `
|
|
window.releaseLocks ||= [];
|
|
navigator.locks.request("${key}", async lock => {
|
|
send("${response}", "locked")
|
|
await new Promise(r => releaseLocks.push(r));
|
|
send("${response}", "unlocked");
|
|
});
|
|
`;
|
|
|
|
const release_script = (response) => `
|
|
for (release of releaseLocks)
|
|
release();
|
|
`;
|
|
|
|
// Assert that |context| holds |expected_keys|.
|
|
const assertHeldKeys = async (context, expected_keys) => {
|
|
const queue = token();
|
|
send(context, `
|
|
const list = await navigator.locks.query();
|
|
send("${queue}", JSON.stringify(list));
|
|
`);
|
|
const state = JSON.parse(await receive(queue));
|
|
const held = state.held.map(x => x.name);
|
|
assert_equals(held.length, expected_keys.length);
|
|
assert_array_equals(held.sort(), expected_keys.sort());
|
|
}
|
|
|
|
promise_test(async test => {
|
|
const origin = get_host_info().HTTPS_REMOTE_ORIGIN;
|
|
const key_1 = token();
|
|
const key_2 = token();
|
|
|
|
// 2 actors: A credentialless iframe and a normal one.
|
|
const iframe_credentialless = newIframeCredentialless(origin);
|
|
const iframe_normal = newIframe(origin);
|
|
const response_queue_1 = token();
|
|
const response_queue_2 = token();
|
|
|
|
// 1. Hold two different locks on both sides.
|
|
send(iframe_credentialless, acquire_script(key_1, response_queue_1));
|
|
send(iframe_normal, acquire_script(key_2, response_queue_2));
|
|
assert_equals(await receive(response_queue_1), "locked");
|
|
assert_equals(await receive(response_queue_2), "locked");
|
|
await assertHeldKeys(iframe_credentialless, [key_1]);
|
|
await assertHeldKeys(iframe_normal, [key_2]);
|
|
|
|
// 2. Try to acquire the lock with the same key on the opposite side. It
|
|
// shouldn't block, because they are partitioned.
|
|
send(iframe_credentialless , acquire_script(key_2, response_queue_1));
|
|
send(iframe_normal, acquire_script(key_1, response_queue_2));
|
|
assert_equals(await receive(response_queue_1), "locked");
|
|
assert_equals(await receive(response_queue_2), "locked");
|
|
await assertHeldKeys(iframe_credentialless, [key_1, key_2]);
|
|
await assertHeldKeys(iframe_normal, [key_1, key_2]);
|
|
|
|
// 3. Cleanup: release the 4 locks (2 on each sides).
|
|
send(iframe_credentialless, release_script(response_queue_1));
|
|
assert_equals(await receive(response_queue_1), "unlocked");
|
|
assert_equals(await receive(response_queue_1), "unlocked");
|
|
await assertHeldKeys(iframe_credentialless, []);
|
|
await assertHeldKeys(iframe_normal, [key_1, key_2]);
|
|
|
|
send(iframe_normal, release_script(response_queue_2));
|
|
assert_equals(await receive(response_queue_2), "unlocked");
|
|
assert_equals(await receive(response_queue_2), "unlocked");
|
|
await assertHeldKeys(iframe_credentialless, []);
|
|
await assertHeldKeys(iframe_normal, []);
|
|
})
|