-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1920254 [wpt PR 48298] - Convert compute_pressure_basic web tests…
… to test_driver, a=testonly Automatic update from web-platform-tests Convert compute_pressure_basic web tests to test_driver The purpose of this change is start using WebDriver. WebDriver commands for Compute Pressure are defined in https://www.w3.org/TR/compute-pressure/#automation Dedicated workers need to manipulate virtual pressure sources, but testdriver calls can only be made in the embedded window, so the existing solution of having '.any.js' files with `META: global=window,dedicatedworker` does not work anymore. The solution is to use message passing so that workers make the embedder window invoke the virtual pressure source calls and use WPT's variants concept to run the same test under multiple configurations. Due to this limitation '.any.js' files needs to be converted to '.window.js'. README.md has been updated to include a detailed guide for creating tests. WebDriver endpoints and virtual pressure sources work in Window and Dedicated Worker scopes, but not shared worker ones: we store virtual pressure source information in WebContentsUserData, which does not integrate well with shared workers. Bug: 347031400 Change-Id: I3cb482c0a689e84012735acd6bc9d33981a7d2f9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5873130 Reviewed-by: Raphael Kubo Da Costa <[email protected]> Commit-Queue: Raphael Kubo Da Costa <[email protected]> Reviewed-by: Reilly Grant <[email protected]> Auto-Submit: Juha J Vainio <[email protected]> Cr-Commit-Position: refs/heads/main@{#1358424} -- wpt-commits: 5a2cfec4558912fd7896472593d420054ae967ff wpt-pr: 48298
- Loading branch information
1 parent
4aad8f1
commit 2f8fb8e
Showing
4 changed files
with
298 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,61 @@ | ||
This directory contains (tentative) tests for the | ||
This directory contains tests for the | ||
[Compute Pressure](https://w3c.github.io/compute-pressure/) specification. | ||
|
||
## How to write tests | ||
### Tests that only need to run on a window | ||
To test this API, one needs to be able to control the pressure data that will | ||
be reported to script. At a high level, this is done by calling certain | ||
[WebDriver endpoints](https://w3c.github.io/compute-pressure/#automation) via | ||
their corresponding | ||
[testdriver](https://web-platform-tests.org/writing-tests/testdriver.html#compute-pressure) | ||
wrappers. | ||
|
||
### Tests that need to run on windows and dedicated workers | ||
Certain [testdriver | ||
limitations](https://web-platform-tests.org/writing-tests/testdriver.html#using-test-driver-in-other-browsing-contexts) | ||
require calls to be made from the top-level test context, which effectively | ||
prevents us from simply [running the same test from multiple globals with | ||
any.js](https://web-platform-tests.org/writing-tests/testharness.html#tests-for-other-or-multiple-globals-any-js). | ||
|
||
What we do instead is [write all tests for the Window | ||
global](https://web-platform-tests.org/writing-tests/testharness.html#window-tests), | ||
use | ||
[variants](https://web-platform-tests.org/writing-tests/testharness.html#specifying-test-variants) | ||
for specifying different globals and using the `pressure_test()` and | ||
`mark_as_done()` helpers. | ||
|
||
In short, the boilerplate for a new test `foo.https.window.js` looks like this: | ||
|
||
``` js | ||
// META: variant=?globalScope=window | ||
// META: variant=?globalScope=dedicated_worker | ||
// META: script=/resources/testdriver.js | ||
// META: script=/resources/testdriver-vendor.js | ||
// META: script=/common/utils.js | ||
// META: script=/common/dispatcher/dispatcher.js | ||
// META: script=./resources/common.js | ||
|
||
pressure_test(async t => { | ||
}, 'my test'); | ||
|
||
mark_as_done(); | ||
``` | ||
|
||
- The variants specify which global context the tests should run on. The only | ||
two options are `window` and `dedicated_worker`. | ||
- We need to include all those scripts for the testdriver and | ||
[RemoteContext](../common/dispatcher/README.md) infrastructure to work. | ||
- `pressure_test()` is a wrapper around a `promise_test()` that takes care of | ||
running the test either in the current context (when `globalScope=window`) or | ||
in a dedicated worker via `RemoteContext` and `fetch_tests_from_worker()` | ||
(when `globalScope=dedicated_worker`). | ||
- `mark_as_done()` is a no-op when `globalScope=window`, but is necessary when | ||
`globalScope=dedicated_worker` to ensure that all tests have run and that | ||
[`done()`](https://web-platform-tests.org/writing-tests/testharness-api.html#Test.done) | ||
is called in the worker context. | ||
|
||
### Shared workers | ||
Since custom pressure states are stored in a top-level navigables, they are | ||
currently not integrated with shared workers (see [spec issue | ||
285](https://github.com/w3c/compute-pressure/issues/285)) and support for | ||
testing shared workers is limited. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
testing/web-platform/tests/compute-pressure/resources/common.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
'use strict'; | ||
|
||
// Dependencies: | ||
// * /common/utils.js | ||
// * /common/dispatcher/dispatcher.js | ||
// | ||
// This file contains the required infrastructure to run Compute Pressure tests | ||
// in both window and worker scopes transparently. | ||
// | ||
// We cannot just use the '.any.js' mechanism with "META: global=window,etc" | ||
// because we need the worker needs to manipulate virtual pressure sources, and | ||
// we can only do that by posting a message to the embedder window to do it due | ||
// to testdriver's limitations and operation model. | ||
// | ||
// See README.md for how to use pressure_test() and other functions within this | ||
// file. | ||
// | ||
// Example: | ||
// - /compute-pressure/foo.https.window.js | ||
// // META: variant=?globalScope=window | ||
// // META: variant=?globalScope=dedicated_worker | ||
// // META: script=/resources/testdriver.js | ||
// // META: script=/resources/testdriver-vendor.js | ||
// // META: script=/common/utils.js | ||
// // META: script=/common/dispatcher/dispatcher.js | ||
// // META: script=./resources/common.js | ||
// | ||
// pressure_test(async t => { | ||
// await create_virtual_pressure_source("cpu"); | ||
// t.add_cleanup(async () => { | ||
// await remove_virtual_pressure_source("cpu") | ||
// }); | ||
// /* rest of the test */ | ||
// }, "my test"); | ||
// | ||
// pressure_test(async t => { /* ... */ }); | ||
// | ||
// mark_as_done(); | ||
|
||
class WindowHelper { | ||
constructor() { | ||
setup({explicit_done: true}); | ||
|
||
// These are the calls made by tests that use pressure_test(). We do not | ||
// invoke the actual virtual pressure functions directly because of | ||
// compatibility with the dedicated workers case, where these calls are | ||
// done via postMessage (see resources/worker-support.js). | ||
globalThis.create_virtual_pressure_source = | ||
test_driver.create_virtual_pressure_source.bind(test_driver); | ||
globalThis.remove_virtual_pressure_source = | ||
test_driver.remove_virtual_pressure_source.bind(test_driver); | ||
globalThis.update_virtual_pressure_source = | ||
test_driver.update_virtual_pressure_source.bind(test_driver); | ||
} | ||
|
||
mark_as_done() { | ||
done(); | ||
} | ||
|
||
pressure_test(test_func, description) { | ||
promise_test(test_func, description); | ||
} | ||
} | ||
|
||
class DedicatedWorkerHelper { | ||
constructor() { | ||
this.token = token(); | ||
|
||
this.worker = new Worker( | ||
`/compute-pressure/resources/worker-support.js?uuid=${this.token}`); | ||
this.worker.onmessage = async (e) => { | ||
if (!e.data.command) { | ||
return; | ||
} | ||
|
||
switch (e.data.command) { | ||
case 'create': | ||
await test_driver.create_virtual_pressure_source(...e.data.params); | ||
break; | ||
|
||
case 'remove': | ||
await test_driver.remove_virtual_pressure_source(...e.data.params); | ||
break; | ||
|
||
case 'update': | ||
await test_driver.update_virtual_pressure_source(...e.data.params); | ||
break; | ||
|
||
default: | ||
throw new Error(`Unexpected command '${e.data.command}'`); | ||
} | ||
|
||
this.worker.postMessage({ | ||
command: e.data.command, | ||
id: e.data.id, | ||
}); | ||
}; | ||
|
||
// We need to call this here so that the testharness RemoteContext | ||
// infrastructure is set up before pressure_test() is called, as each test | ||
// will be added after the worker scaffolding code has loaded. | ||
this.fetch_tests_promise = fetch_tests_from_worker(this.worker); | ||
|
||
this.ctx = new RemoteContext(this.token); | ||
|
||
this.pending_tests = []; | ||
} | ||
|
||
async mark_as_done() { | ||
await Promise.all(this.pending_tests); | ||
await this.ctx.execute_script(() => { | ||
done(); | ||
}); | ||
await this.fetch_tests_from_worker; | ||
} | ||
|
||
async pressure_test(test_func, description) { | ||
this.pending_tests.push(this.ctx.execute_script( | ||
` | ||
(description) => promise_test(${test_func}, description); | ||
`, | ||
[description])); | ||
} | ||
} | ||
|
||
let _pressureTestHelper; | ||
const _globalScope = new URLSearchParams(location.search).get('globalScope'); | ||
switch (_globalScope) { | ||
case 'window': | ||
_pressureTestHelper = new WindowHelper(); | ||
break; | ||
case 'dedicated_worker': | ||
_pressureTestHelper = new DedicatedWorkerHelper(); | ||
break; | ||
default: | ||
throw new Error(`Invalid variant '${_globalScope}'`); | ||
} | ||
|
||
const pressure_test = | ||
_pressureTestHelper.pressure_test.bind(_pressureTestHelper); | ||
const mark_as_done = _pressureTestHelper.mark_as_done.bind(_pressureTestHelper); |
48 changes: 48 additions & 0 deletions
48
testing/web-platform/tests/compute-pressure/resources/worker-support.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
'use strict'; | ||
|
||
importScripts('/resources/testharness.js'); | ||
importScripts('/common/utils.js'); | ||
importScripts('/common/dispatcher/dispatcher.js'); | ||
|
||
function send_message(message) { | ||
return new Promise((resolve, reject) => { | ||
const id = token(); | ||
message.id = id; | ||
|
||
addEventListener('message', function listener(e) { | ||
if (!e.data.command || e.data.id !== id) { | ||
return; | ||
} | ||
|
||
removeEventListener('message', listener); | ||
|
||
if (e.data.command !== message.command) { | ||
reject(`Expected reply with command '${message.command}', got '${ | ||
e.data.command}' instead`); | ||
return; | ||
} | ||
if (e.data.error) { | ||
reject(e.data.error); | ||
return; | ||
} | ||
resolve(); | ||
}); | ||
|
||
postMessage(message); | ||
}); | ||
} | ||
|
||
function create_virtual_pressure_source(source, options = {}) { | ||
return send_message({command: 'create', params: [source, options]}); | ||
} | ||
|
||
function remove_virtual_pressure_source(source) { | ||
return send_message({command: 'remove', params: [source]}); | ||
} | ||
|
||
function update_virtual_pressure_source(source, state) { | ||
return send_message({command: 'update', params: [source, state]}); | ||
} | ||
|
||
const uuid = new URLSearchParams(location.search).get('uuid'); | ||
const executor = new Executor(uuid); |