Skip to content

Commit

Permalink
compute pressure: Convert remaining web tests to test_driver
Browse files Browse the repository at this point in the history
The purpose of this change is start using WebDriver and remove mock
code. WebDriver commands for Compute Pressure are defined in
https://www.w3.org/TR/compute-pressure/#automation

In general, this involves renaming `*.any.js` tests to `*.window.js`
ones to continue being able to test windows and dedicated workers from
the same file (see README.md for a longer explanation of how this works
around test_driver limitations) as well as replacing the mock
PressureService calls with test_driver ones.

While here, a few other changes had to be made:
- compute_pressure_basic.https.window.js: Stop passing async functions
  to Promise constructors. async functions do not make much sense in
  this context, and we can just call reject() when some function calls
  fail and avoid having to explicitly wait for them because by the time
  we reach the PressureObserver callbacks they will by definition have
  finished running.
- compute_pressure_rate_obfuscation_mitigation_not_triggered.https.window.js:
  The promise wrapping the majority of the test has been removed because
  it is not necessary.
- compute_pressure_rate_obfuscation_mitigation_triggered.https.window.js:
  The wrapping promise has been removed for the same reason. The wait
  the code was structured also made the entire test exit early when
  resolve() was called, and we never got to test the loop conditions and
  the final assertion in this case. Now that we do, fix the checks in
  the loop (we need an AND, not an OR) and adjust the description of the
  final assert_true() call.

Co-authored with [email protected]

Bug: 347031400
Change-Id: I289292bd4d35f7f26d4531252e64c0aba571124e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5898734
Reviewed-by: Reilly Grant <[email protected]>
Commit-Queue: Raphael Kubo Da Costa <[email protected]>
Auto-Submit: Raphael Kubo Da Costa <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1362281}
  • Loading branch information
Raphael Kubo da Costa authored and chromium-wpt-export-bot committed Oct 1, 2024
1 parent 47ff969 commit 3b5b938
Show file tree
Hide file tree
Showing 30 changed files with 624 additions and 661 deletions.
11 changes: 11 additions & 0 deletions compute-pressure/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
This directory contains tests for the
[Compute Pressure](https://w3c.github.io/compute-pressure/) specification.

## Notes to implementors
`compute_pressure_rate_obfuscation_mitigation_*`, which test the spec's [rate
obfuscation
sections](https://w3c.github.io/compute-pressure/#rate-obfuscation), need to
send and wait for dozens of updates.

Some tests may need to send over 90 changes and then wait up to 10 seconds for
the next update. At 1 change per second, this would by far exceed WPT's timeout
limits, so implementations need to be able to dispatch updates at a higher rate
than usual for these tests to pass.

## 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
Expand Down
43 changes: 18 additions & 25 deletions compute-pressure/compute_pressure_basic.https.window.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ pressure_test(async (t) => {
await remove_virtual_pressure_source('cpu');
});

const changes = await new Promise(async (resolve) => {
const changes = await new Promise((resolve, reject) => {
const observer = new PressureObserver(resolve);
t.add_cleanup(() => observer.disconnect());
await update_virtual_pressure_source('cpu', 'critical');
await observer.observe('cpu');
observer.observe('cpu').catch(reject);
update_virtual_pressure_source('cpu', 'critical').catch(reject);
});
assert_equals(1, changes.length);
assert_equals(changes[0].state, 'critical');
Expand Down Expand Up @@ -84,32 +84,25 @@ pressure_test(async (t) => {
await remove_virtual_pressure_source('cpu');
});

const observer1_changes = [];
await new Promise(async (resolve) => {
const observer1 = new PressureObserver(changes => {
observer1_changes.push(changes);
resolve();
});
t.add_cleanup(() => observer1.disconnect());
await update_virtual_pressure_source('cpu', 'critical');
await observer1.observe('cpu');
const observer1_promise = new Promise((resolve, reject) => {
const observer = new PressureObserver(resolve);
t.add_cleanup(() => observer.disconnect());
observer.observe('cpu').catch(reject);
});
await update_virtual_pressure_source('cpu', 'critical');
const observer1_changes = await observer1_promise;
assert_equals(1, observer1_changes.length);
assert_equals(observer1_changes[0][0].source, 'cpu');
assert_equals(observer1_changes[0][0].state, 'critical');

const observer2_changes = [];
await new Promise(resolve => {
const observer2 = new PressureObserver(changes => {
observer2_changes.push(changes);
resolve();
});
t.add_cleanup(() => observer2.disconnect());
observer2.observe('cpu');
assert_equals(observer1_changes[0].source, 'cpu');
assert_equals(observer1_changes[0].state, 'critical');

const observer2_changes = await new Promise((resolve, reject) => {
const observer = new PressureObserver(resolve);
t.add_cleanup(() => observer.disconnect());
observer.observe('cpu').catch(reject);
});
assert_equals(1, observer2_changes.length);
assert_equals(observer2_changes[0][0].source, 'cpu');
assert_equals(observer2_changes[0][0].state, 'critical');
assert_equals(observer2_changes[0].source, 'cpu');
assert_equals(observer2_changes[0].state, 'critical');
}, 'Starting a new observer after an observer has started works');

mark_as_done();
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
<!doctype html>
<meta charset="utf-8">
<title>PressureObserver on DOMWindow of detached iframe</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/test-only-api.js"></script>
<script src="resources/pressure-helpers.js"></script>
<body>
<script>
// META: variant=?globalScope=window
// 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

'use strict';

test(() => {
Expand All @@ -33,7 +31,12 @@
observer.observe('cpu'));
}, 'PressureObserver.observe() on detached frame rejects');

promise_test(async t => {
pressure_test(async t => {
await create_virtual_pressure_source('cpu');
t.add_cleanup(async () => {
await remove_virtual_pressure_source('cpu');
});

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const frame_window = iframe.contentWindow;
Expand All @@ -48,7 +51,11 @@
observer.disconnect();
}, 'PressureObserver.disconnect() on detached frame returns');

pressure_test(async (t, mockPressureService) => {
pressure_test(async t => {
await create_virtual_pressure_source('cpu');
t.add_cleanup(async () => {
await remove_virtual_pressure_source('cpu');
});
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const frame_window = iframe.contentWindow;
Expand All @@ -68,13 +75,17 @@
const observer = new PressureObserver(resolve);
t.add_cleanup(() => observer.disconnect());
observer.observe('cpu').catch(reject);
mockPressureService.setPressureUpdate('cpu', 'critical');
mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200);
update_virtual_pressure_source('cpu', 'critical').catch(reject);
});
assert_equals(changes[0].state, 'critical');
}, 'Detaching frame while PressureObserver.observe() settles');

pressure_test(async (t, mockPressureService) => {
pressure_test(async t => {
await create_virtual_pressure_source('cpu');
t.add_cleanup(async () => {
await remove_virtual_pressure_source('cpu');
});

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const frame_window = iframe.contentWindow;
Expand All @@ -83,13 +94,11 @@
});

await observer.observe('cpu');
mockPressureService.setPressureUpdate('cpu', 'critical');
mockPressureService.startPlatformCollector(/*sampleInterval=*/ 200);

const updatePromise = update_virtual_pressure_source('cpu', 'critical');
iframe.remove();
await updatePromise;

return new Promise(resolve => t.step_timeout(resolve, 1000));
}, 'PressureObserver on detached frame returns with no callback');

</script>
</body>
mark_as_done();
44 changes: 0 additions & 44 deletions compute-pressure/compute_pressure_disconnect.https.any.js

This file was deleted.

50 changes: 50 additions & 0 deletions compute-pressure/compute_pressure_disconnect.https.window.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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

'use strict';

pressure_test(async t => {
const observer = new PressureObserver(() => {
assert_unreached('The observer callback should not be called');
});
t.add_cleanup(() => observer.disconnect());
observer.disconnect();
}, 'Calling disconnect() immediately should not crash');

pressure_test(async t => {
await create_virtual_pressure_source('cpu');
t.add_cleanup(async () => {
await remove_virtual_pressure_source('cpu');
});

const observer1_changes = [];
const observer1 = new PressureObserver(change => {
observer1_changes.push(change);
});
t.add_cleanup(() => observer1.disconnect());
// Ensure that observer1's schema gets registered before observer2 starts.
await observer1.observe('cpu');
observer1.disconnect();

const observer2_promise = new Promise((resolve, reject) => {
const observer = new PressureObserver(resolve);
t.add_cleanup(() => observer.disconnect());
observer.observe('cpu').catch(reject);
});
await update_virtual_pressure_source('cpu', 'critical');
const observer2_changes = await observer2_promise;

assert_equals(
observer1_changes.length, 0,
'disconnected observers should not receive callbacks');

assert_equals(observer2_changes.length, 1);
assert_equals(observer2_changes[0].state, 'critical');
}, 'Stopped PressureObserver do not receive changes');

mark_as_done();

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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

'use strict';

pressure_test(async t => {
await create_virtual_pressure_source('cpu');
t.add_cleanup(async () => {
await remove_virtual_pressure_source('cpu');
});

const observer1_changes = [];
const observer1 = new PressureObserver(changes => {
observer1_changes.push(changes);
});
t.add_cleanup(() => observer1.disconnect());
// Ensure that observer1's schema gets registered before observer2 starts.
const promise = observer1.observe('cpu');
observer1.disconnect();
observer1.disconnect();
await promise_rejects_dom(t, 'AbortError', promise);

const observer2_promise = new Promise((resolve, reject) => {
const observer = new PressureObserver(resolve);
t.add_cleanup(() => observer.disconnect());
observer.observe('cpu').catch(reject);
});
await update_virtual_pressure_source('cpu', 'critical');
const observer2_changes = await observer2_promise;

assert_equals(
observer1_changes.length, 0,
'stopped observers should not receive callbacks');

assert_equals(observer2_changes.length, 1);
assert_equals(observer2_changes[0].state, 'critical');
}, 'Stopped PressureObserver do not receive changes');

mark_as_done();
Loading

0 comments on commit 3b5b938

Please sign in to comment.