diff options
Diffstat (limited to 'testing/web-platform/tests/measure-memory')
50 files changed, 1266 insertions, 0 deletions
diff --git a/testing/web-platform/tests/measure-memory/META.yml b/testing/web-platform/tests/measure-memory/META.yml new file mode 100644 index 0000000000..c80aa788b8 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/META.yml @@ -0,0 +1,3 @@ +spec: https://wicg.github.io/performance-measure-memory/ +suggested_reviewers: + - ulan diff --git a/testing/web-platform/tests/measure-memory/README.md b/testing/web-platform/tests/measure-memory/README.md new file mode 100644 index 0000000000..94b298687e --- /dev/null +++ b/testing/web-platform/tests/measure-memory/README.md @@ -0,0 +1,6 @@ +# Tests for performance.measureUserAgentSpecificMemory API + +Tests in this directory are for the performance.measureUserAgentSpecificMemory API: + +- Specification: https://wicg.github.io/performance-measure-memory +- Explainer: https://github.com/WICG/performance-measure-memory diff --git a/testing/web-platform/tests/measure-memory/detached.https.window.js b/testing/web-platform/tests/measure-memory/detached.https.window.js new file mode 100644 index 0000000000..1fcedef54c --- /dev/null +++ b/testing/web-platform/tests/measure-memory/detached.https.window.js @@ -0,0 +1,198 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-site-1', + children: [ + { + id: 'same-origin-2', + }, + { + id: 'same-origin-11', + window_open: true, + }, + ], + }, + { + id: 'same-origin-3', + children: [ + { + id: 'same-origin-4', + }, + { + id: 'same-origin-12', + window_open: true, + }, + ], + }, + { + id: 'cross-origin-5', + children: [ + { + id: 'same-origin-6', + }, + { + id: 'same-origin-13', + window_open: true, + }, + ], + }, + { + id: 'same-origin-7', + window_open: true, + children: [ + { + id: 'same-origin-8', + } + ], + }, + { + id: 'cross-origin-9', + window_open: true, + children: [ + { + id: 'same-origin-10', + } + ], + }, + ]); + const expected = [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-site-1', + src: iframes['cross-site-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: { + id: 'cross-site-1', + src: iframes['cross-site-1'].src, + }, + }, + { + url: windows['same-origin-3'].location.href, + scope: 'Window', + container: { + id: 'same-origin-3', + src: iframes['same-origin-3'].src, + }, + }, + { + url: windows['same-origin-4'].location.href, + scope: 'Window', + container: { + id: 'same-origin-4', + src: iframes['same-origin-4'].src, + }, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-origin-5', + src: iframes['cross-origin-5'].src, + }, + }, + { + url: windows['same-origin-6'].location.href, + scope: 'Window', + container: { + id: 'cross-origin-5', + src: iframes['cross-origin-5'].src, + }, + }, + { + url: windows['same-origin-8'].location.href, + scope: 'Window', + container: { + id: 'same-origin-8', + src: iframes['same-origin-8'].src, + }, + }, + { + url: windows['same-origin-7'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-11'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-12'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-13'].location.href, + scope: 'Window', + container: null, + }, + ]; + const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows)); + // Detach iframes: + // 1) By setting src attribute: + iframes['cross-site-1'].src = + iframes['cross-site-1'].src.replace('iframe.sub', 'iframe.secret.sub'); + // 2) By setting location attribute: + let url = iframes['same-origin-3'].contentWindow.location.href; + url = url.replace('iframe.sub', 'iframe.secret.sub'); + iframes['same-origin-3'].contentWindow.location.href = url; + // 3) By removing from the DOM tree: + iframes['cross-origin-5'].parentNode.removeChild(iframes['cross-origin-5']); + + // Detach windows: + // 1) By setting document.location attribute: + url = windows['same-origin-7'].location.href; + url = url.replace('window.sub', 'window.secret.sub'); + windows['same-origin-7'].location.href = url; + // 2) By closing the window: + windows['same-origin-10'].parent.close(); + + await waitForMessage('cross-site-1'); + await waitForMessage('same-origin-3'); + await waitForMessage('same-origin-7'); + + expected.push({ + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-site-1', + src: iframes['cross-site-1'].src, + }, + }); + + expected.push({ + url: windows['same-origin-3'].location.href, + scope: 'Window', + container: { + id: 'same-origin-3', + src: iframes['same-origin-3'].src, + }, + }); + expected.push({ + url: windows['same-origin-7'].location.href, + scope: 'Window', + container: null, + }); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, expected); +}, 'performance.measureUserAgentSpecificMemory URLs within a cross-site iframe.'); diff --git a/testing/web-platform/tests/measure-memory/detached.https.window.js.headers b/testing/web-platform/tests/measure-memory/detached.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/detached.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/idlharness.window.js b/testing/web-platform/tests/measure-memory/idlharness.window.js new file mode 100644 index 0000000000..3e7589aeb9 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/idlharness.window.js @@ -0,0 +1,15 @@ +// META: global=window,worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://wicg.github.io/performance-measure-memory/ + +idl_test( + ['performance-measure-memory'], + ['hr-time', 'dom'], + async idl_array => { + // Nothing to add. + } +); diff --git a/testing/web-platform/tests/measure-memory/iframe.cross-origin.https.window.js b/testing/web-platform/tests/measure-memory/iframe.cross-origin.https.window.js new file mode 100644 index 0000000000..de256ad83f --- /dev/null +++ b/testing/web-platform/tests/measure-memory/iframe.cross-origin.https.window.js @@ -0,0 +1,50 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-origin-1', + children: [ + { + id: 'same-origin-2', + }, + { + id: 'cross-origin-3', + }, + { + id: 'cross-site-4', + } + ], + }, + ]); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-origin-1', + src: iframes['cross-origin-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: { + id: 'cross-origin-1', + src: iframes['cross-origin-1'].src, + }, + }, + ]); +}, 'performance.measureUserAgentSpecificMemory URLs within a cross-origin iframe.'); diff --git a/testing/web-platform/tests/measure-memory/iframe.cross-origin.https.window.js.headers b/testing/web-platform/tests/measure-memory/iframe.cross-origin.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/iframe.cross-origin.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/iframe.cross-site.https.window.js b/testing/web-platform/tests/measure-memory/iframe.cross-site.https.window.js new file mode 100644 index 0000000000..a4c50a5687 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/iframe.cross-site.https.window.js @@ -0,0 +1,57 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-site-1', + children: [ + { + id: 'same-origin-2', + }, + { + id: 'cross-origin-3', + }, + { + id: 'cross-site-4', + } + ], + }, + ]); + try { + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-site-1', + src: iframes['cross-site-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: { + id: 'cross-site-1', + src: iframes['cross-site-1'].src, + }, + }, + ]); + } catch (error) { + if (!(error instanceof DOMException)) { + throw error; + } + assert_equals(error.name, 'SecurityError'); + } +}, 'performance.measureUserAgentSpecificMemory URLs within a cross-site iframe.'); diff --git a/testing/web-platform/tests/measure-memory/iframe.cross-site.https.window.js.headers b/testing/web-platform/tests/measure-memory/iframe.cross-site.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/iframe.cross-site.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/iframe.same-origin.https.window.js b/testing/web-platform/tests/measure-memory/iframe.same-origin.https.window.js new file mode 100644 index 0000000000..5d710bd1dd --- /dev/null +++ b/testing/web-platform/tests/measure-memory/iframe.same-origin.https.window.js @@ -0,0 +1,44 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'same-origin-1', + children: [ + { + id: 'same-origin-2', + } + ], + }, + ]); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-1'].location.href, + scope: 'Window', + container: { + id: 'same-origin-1', + src: iframes['same-origin-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: { + id: 'same-origin-2', + src: iframes['same-origin-2'].src, + }, + }, + ]); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory with same-origin iframes.'); diff --git a/testing/web-platform/tests/measure-memory/iframe.same-origin.https.window.js.headers b/testing/web-platform/tests/measure-memory/iframe.same-origin.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/iframe.same-origin.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/main-frame-and-worker.https.window.js b/testing/web-platform/tests/measure-memory/main-frame-and-worker.https.window.js new file mode 100644 index 0000000000..a1a5a5a6c3 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/main-frame-and-worker.https.window.js @@ -0,0 +1,27 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const BYTES_PER_WORKER = 10 * 1024 * 1024; + const worker_url = await createWorker(BYTES_PER_WORKER); + const result = await performance.measureUserAgentSpecificMemory(); + assert_greater_than_equal(result.bytes, BYTES_PER_WORKER); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: worker_url, + scope: 'DedicatedWorkerGlobalScope', + container: null, + }, + ]); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory.'); + diff --git a/testing/web-platform/tests/measure-memory/main-frame-and-worker.https.window.js.headers b/testing/web-platform/tests/measure-memory/main-frame-and-worker.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/main-frame-and-worker.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/main-frame.https.window.js b/testing/web-platform/tests/measure-memory/main-frame.https.window.js new file mode 100644 index 0000000000..1119ca4446 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/main-frame.https.window.js @@ -0,0 +1,18 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + ]); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory.'); diff --git a/testing/web-platform/tests/measure-memory/main-frame.https.window.js.headers b/testing/web-platform/tests/measure-memory/main-frame.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/main-frame.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/randomized-breakdown.https.window.js b/testing/web-platform/tests/measure-memory/randomized-breakdown.https.window.js new file mode 100644 index 0000000000..09937d5115 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/randomized-breakdown.https.window.js @@ -0,0 +1,27 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +function indexOfEmptyEntry(result) { + return result.breakdown.findIndex(isEmptyBreakdownEntry); +} + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const initial = await performance.measureUserAgentSpecificMemory(); + let observed_different_order = false; + for (let i = 0; i < 100; ++i) { + const current = await performance.measureUserAgentSpecificMemory(); + if (indexOfEmptyEntry(initial) != indexOfEmptyEntry(current)) { + observed_different_order = true; + } + } + // The order of the breakdown entries must be randomized. + // A conforming implementation may fail the following assert with + // the probability of at most 2^-100 since there are at least two + // entries in the breakdown. + assert_true(observed_different_order); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory.'); diff --git a/testing/web-platform/tests/measure-memory/randomized-breakdown.https.window.js.headers b/testing/web-platform/tests/measure-memory/randomized-breakdown.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/randomized-breakdown.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/redirect.client.https.window.js b/testing/web-platform/tests/measure-memory/redirect.client.https.window.js new file mode 100644 index 0000000000..a78a7ddfdc --- /dev/null +++ b/testing/web-platform/tests/measure-memory/redirect.client.https.window.js @@ -0,0 +1,68 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-origin-1', + redirect: 'client', + children: [ + { + id: 'same-origin-2', + }, + { + id: 'cross-origin-3', + }, + { + id: 'cross-site-4', + } + ], + }, + { + id: 'cross-origin-5', + redirect: 'client', + window_open: true, + children: [ + { + id: 'same-origin-6', + }, + { + id: 'cross-origin-7', + }, + { + id: 'cross-site-8', + } + ], + }, + ]); + const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows)); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-origin-1', + src: frames['cross-origin-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: { + id: 'cross-origin-1', + src: iframes['cross-origin-1'].src, + }, + }, + ]); +}, 'performance.measureUserAgentSpecificMemory does not leak client redirected URL.'); diff --git a/testing/web-platform/tests/measure-memory/redirect.client.https.window.js.headers b/testing/web-platform/tests/measure-memory/redirect.client.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/redirect.client.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/redirect.server.https.window.js b/testing/web-platform/tests/measure-memory/redirect.server.https.window.js new file mode 100644 index 0000000000..98273edec2 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/redirect.server.https.window.js @@ -0,0 +1,68 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-origin-1', + redirect: 'server', + children: [ + { + id: 'same-origin-2', + }, + { + id: 'cross-origin-3', + }, + { + id: 'cross-site-4', + } + ], + }, + { + id: 'cross-origin-5', + redirect: 'server', + window_open: true, + children: [ + { + id: 'same-origin-6', + }, + { + id: 'cross-origin-7', + }, + { + id: 'cross-site-8', + } + ], + }, + ]); + const keep = sameOriginContexts(frames).concat(sameOriginContexts(windows)); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-origin-1', + src: frames['cross-origin-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: { + id: 'cross-origin-1', + src: iframes['cross-origin-1'].src, + }, + }, + ]); +}, 'performance.measureUserAgentSpecificMemory does not leak server redirected URL.'); diff --git a/testing/web-platform/tests/measure-memory/redirect.server.https.window.js.headers b/testing/web-platform/tests/measure-memory/redirect.server.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/redirect.server.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/checker.js b/testing/web-platform/tests/measure-memory/resources/checker.js new file mode 100644 index 0000000000..25487b7b05 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/checker.js @@ -0,0 +1,58 @@ +function checkContainer(actual, expected) { + if (!actual) return true; + if (!expected) return false; + return actual.id == expected.id && actual.src == expected.src; +} + +function checkAttribution(attribution, expected) { + assert_own_property(attribution, 'url'); + assert_own_property(attribution, 'scope'); + let found = false; + for (const e of expected) { + if (attribution.url === e.url && + attribution.scope === e.scope && + checkContainer(attribution.container, e.container)) { + found = true; + e.found = true; + } + } + assert_true(found, JSON.stringify(attribution) + + ' is not found in ' + JSON.stringify(expected) + '.'); +} + +function checkBreakdown(breakdown, expected) { + assert_own_property(breakdown, 'bytes'); + assert_greater_than_equal(breakdown.bytes, 0); + assert_own_property(breakdown, 'types'); + for (const memoryType of breakdown.types) { + assert_equals(typeof memoryType, 'string'); + } + assert_own_property(breakdown, 'attribution'); + for (const attribution of breakdown.attribution) { + checkAttribution(attribution, expected); + } +} + +function isEmptyBreakdownEntry(entry) { + return entry.bytes === 0 && entry.attribution.length === 0 && + entry.types.length === 0; +} + +function checkMeasureMemory(result, expected) { + assert_own_property(result, 'bytes'); + assert_own_property(result, 'breakdown'); + let bytes = 0; + for (let breakdown of result.breakdown) { + checkBreakdown(breakdown, expected); + bytes += breakdown.bytes; + } + assert_equals(bytes, result.bytes); + for (const e of expected) { + if (e.required) { + assert_true(e.found, + JSON.stringify(e) + ' did not appear in the result.'); + } + } + assert_true(result.breakdown.some(isEmptyBreakdownEntry), + 'The result must include an empty breakdown entry.'); +}
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/common.js b/testing/web-platform/tests/measure-memory/resources/common.js new file mode 100644 index 0000000000..4332c6e79c --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/common.js @@ -0,0 +1,178 @@ +const ORIGINS = { + 'same-origin': get_host_info().HTTPS_ORIGIN, + 'cross-origin': get_host_info().HTTPS_REMOTE_ORIGIN, + 'cross-site': get_host_info().HTTPS_NOTSAMESITE_ORIGIN, +} + +function url(params) { + let origin = null; + for (const key of Object.keys(ORIGINS)) { + if (params.id.startsWith(key)) { + origin = ORIGINS[key]; + } + } + const child = params.window_open ? 'window' : 'iframe'; + let file = `measure-memory/resources/${child}.sub.html`; + if (params.redirect) { + file = `measure-memory/resources/${child}.redirect.sub.html`; + } + let url = `${origin}/${file}?id=${params.id}`; + if (params.redirect === 'server') { + url = (`${origin}/measure-memory/resources/redirect.py?` + + `location=${encodeURIComponent(url)}`); + } + return url; +} + +// A simple multiplexor of messages based on iframe ids. +let waitForMessage = (function () { + class Inbox { + constructor() { + this.queue = []; + this.resolve = null; + } + push(value) { + if (this.resolve) { + this.resolve(value); + this.resolve = null; + } else { + this.queue.push(value); + } + } + pop() { + let promise = new Promise(resolve => this.resolve = resolve); + if (this.queue.length > 0) { + this.resolve(this.queue.shift()); + this.resolve = null; + } + return promise; + } + } + const inbox = {}; + + window.onmessage = function (message) { + const id = message.data.id; + const payload = message.data.payload; + inbox[id] = inbox[id] || new Inbox(); + inbox[id].push(payload); + } + return function (id) { + inbox[id] = inbox[id] || new Inbox(); + return inbox[id].pop(); + } +})(); + +function getMainWindow() { + let main = window; + while (true) { + if (main === main.parent) { + if (!main.opener) { + break; + } else { + main = main.opener; + } + } else { + main = main.parent; + } + } + return main; +} + +function isSameOrigin(other) { + try { + other.descendants; + } catch (e) { + // Cross-origin iframe that cannot access the main frame. + return false; + } + return !!other.descendants; +} + +function getId() { + const params = new URLSearchParams(document.location.search); + return params.get('id'); +} + +function getParent() { + if (window.parent == window && window.opener) { + return window.opener; + } + return window.parent; +} + +// Constructs iframes based on their descriptoin. +async function build(children) { + window.descendants = {iframes: {}, windows: {}}; + await Promise.all(children.map(buildChild)); + const result = window.descendants; + return result; +} + +async function buildChild(params) { + let child = null; + function target() { + return params.window_open ? child : child.contentWindow; + } + if (params.window_open) { + child = window.open(url(params)); + if (!params.id.startsWith('same-origin')) { + // Cross-origin windows gets their own browsing context groups with COOP. + // The postMessage calls before would not work for them, so we do not + // wait for them to load. + return; + } + } else { + child = document.createElement('iframe'); + child.src = url(params); + child.id = params.id; + document.body.appendChild(child); + } + const ready = await waitForMessage(params.id); + target().postMessage({id: 'parent', payload: params.children}, '*'); + const done = await waitForMessage(params.id); + if (!params.window_open) { + const main = getMainWindow(); + if (isSameOrigin(main)) { + main.descendants.iframes[params.id] = child; + } + } +} + +// This function runs within an iframe. +// It gets the children descriptions from the parent and constructs them. +async function setupChild() { + const id = getId(); + const main = getMainWindow(); + if (isSameOrigin(main)) { + main.descendants.windows[id] = window; + } + document.getElementById('title').textContent = id; + getParent().postMessage({id : id, payload: 'ready'}, '*'); + const children = await waitForMessage('parent'); + if (children) { + await Promise.all(children.map(buildChild)); + } + getParent().postMessage({id: id, payload: 'done'}, '*'); +} + +function sameOriginContexts(children) { + const result = []; + for (const [id, child] of Object.entries(children)) { + if (id.includes('same-origin')) { + result.push(child.contentWindow + ? child.contentWindow.performance : child.performance); + } + } + return result; +} + +async function createWorker(bytes) { + const worker = new Worker('resources/worker.js'); + let resolve_promise; + const promise = new Promise(resolve => resolve_promise = resolve); + worker.onmessage = function (message) { + resolve_promise(message.data); + } + worker.postMessage({bytes}); + return promise; +}
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/iframe.redirect.sub.html b/testing/web-platform/tests/measure-memory/resources/iframe.redirect.sub.html new file mode 100644 index 0000000000..6eaf557422 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/iframe.redirect.sub.html @@ -0,0 +1,12 @@ +<!doctype html> +<meta charset="utf-8"> +<html> +<script> +window.onload = function () { + document.location.href = document.location.href.replace('redirect', 'secret'); +} +</script> +<body> + Hello from the redirecting iframe: <span id="title"></span> +</body> +</html> diff --git a/testing/web-platform/tests/measure-memory/resources/iframe.redirect.sub.html.headers b/testing/web-platform/tests/measure-memory/resources/iframe.redirect.sub.html.headers new file mode 100644 index 0000000000..4e798cd9f5 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/iframe.redirect.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin diff --git a/testing/web-platform/tests/measure-memory/resources/iframe.secret.sub.html b/testing/web-platform/tests/measure-memory/resources/iframe.secret.sub.html new file mode 100644 index 0000000000..55caa347fb --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/iframe.secret.sub.html @@ -0,0 +1,14 @@ +<!doctype html> +<meta charset="utf-8"> +<html> +<script src="/common/get-host-info.sub.js"></script> +<script src="./common.js"></script> +<script> +window.onload = function () { + setTimeout(setupChild, 0); +} +</script> +<body> + Hello from the secrect iframe: <span id="title"></span> +</body> +</html> diff --git a/testing/web-platform/tests/measure-memory/resources/iframe.secret.sub.html.headers b/testing/web-platform/tests/measure-memory/resources/iframe.secret.sub.html.headers new file mode 100644 index 0000000000..b227e843ae --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/iframe.secret.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/iframe.sub.html b/testing/web-platform/tests/measure-memory/resources/iframe.sub.html new file mode 100644 index 0000000000..96b7b1a839 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/iframe.sub.html @@ -0,0 +1,14 @@ +<!doctype html> +<meta charset="utf-8"> +<html> +<script src="/common/get-host-info.sub.js"></script> +<script src="./common.js"></script> +<script> +window.onload = function() { + setTimeout(setupChild, 0); +} +</script> +<body> + Hello from the iframe: <span id="title"></span> +</body> +</html> diff --git a/testing/web-platform/tests/measure-memory/resources/iframe.sub.html.headers b/testing/web-platform/tests/measure-memory/resources/iframe.sub.html.headers new file mode 100644 index 0000000000..b227e843ae --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/iframe.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: cross-origin
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/redirect.py b/testing/web-platform/tests/measure-memory/resources/redirect.py new file mode 100644 index 0000000000..1e6dbff8a8 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/redirect.py @@ -0,0 +1,21 @@ +def main(request, response): + """Simple handler that causes redirection. + + The request should typically have two query parameters: + status - The status to use for the redirection. Defaults to 302. + location - The resource to redirect to. + """ + status = 302 + if b"status" in request.GET: + try: + status = int(request.GET.first(b"status")) + except ValueError: + pass + + response.status = status + + location = request.GET.first(b"location") + + response.headers.set(b"Location", location) + response.headers.set(b"Cross-Origin-Embedder-Policy", b"require-corp") + response.headers.set(b"Cross-Origin-Resource-Policy", b"cross-origin") diff --git a/testing/web-platform/tests/measure-memory/resources/window.redirect.sub.html b/testing/web-platform/tests/measure-memory/resources/window.redirect.sub.html new file mode 100644 index 0000000000..b339abc54f --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/window.redirect.sub.html @@ -0,0 +1,12 @@ +<!doctype html> +<meta charset="utf-8"> +<html> +<script> +window.onload = function () { + document.location.href = document.location.href.replace('redirect', 'secret'); +} +</script> +<body> + Hello from the redirecting widnow: <span id="title"></span> +</body> +</html> diff --git a/testing/web-platform/tests/measure-memory/resources/window.redirect.sub.html.headers b/testing/web-platform/tests/measure-memory/resources/window.redirect.sub.html.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/window.redirect.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/window.secret.sub.html b/testing/web-platform/tests/measure-memory/resources/window.secret.sub.html new file mode 100644 index 0000000000..99d9d1251b --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/window.secret.sub.html @@ -0,0 +1,14 @@ +<!doctype html> +<meta charset="utf-8"> +<html> +<script src="/common/get-host-info.sub.js"></script> +<script src="./common.js"></script> +<script> +window.onload = function () { + setTimeout(setupChild, 0); +} +</script> +<body> + Hello from the secrect window: <span id="title"></span> +</body> +</html> diff --git a/testing/web-platform/tests/measure-memory/resources/window.secret.sub.html.headers b/testing/web-platform/tests/measure-memory/resources/window.secret.sub.html.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/window.secret.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/window.sub.html b/testing/web-platform/tests/measure-memory/resources/window.sub.html new file mode 100644 index 0000000000..c254094382 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/window.sub.html @@ -0,0 +1,14 @@ +<!doctype html> +<meta charset="utf-8"> +<html> +<script src="/common/get-host-info.sub.js"></script> +<script src="./common.js"></script> +<script> +window.onload = function() { + setTimeout(setupChild, 0); +} +</script> +<body> + Hello from the window: <span id="title"></span> +</body> +</html> diff --git a/testing/web-platform/tests/measure-memory/resources/window.sub.html.headers b/testing/web-platform/tests/measure-memory/resources/window.sub.html.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/window.sub.html.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/resources/worker.js b/testing/web-platform/tests/measure-memory/resources/worker.js new file mode 100644 index 0000000000..000df12729 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/worker.js @@ -0,0 +1,9 @@ +self.onmessage = function(message) { + const length = message.data.bytes; + self.root = new Uint8Array(length); + // Set some elements to disable potential copy-on-write optimizations. + for (let i = 0; i < length; i += 256) { + self.root[i] = 1; + } + postMessage(self.location.href); +} diff --git a/testing/web-platform/tests/measure-memory/resources/worker.js.headers b/testing/web-platform/tests/measure-memory/resources/worker.js.headers new file mode 100644 index 0000000000..a271409661 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/resources/worker.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Embedder-Policy: require-corp +Cross-Origin-Resource-Policy: same-origin
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/service-worker.https.any.js b/testing/web-platform/tests/measure-memory/service-worker.https.any.js new file mode 100644 index 0000000000..c0251114dd --- /dev/null +++ b/testing/web-platform/tests/measure-memory/service-worker.https.any.js @@ -0,0 +1,18 @@ +// META: script=./resources/checker.js +// META: timeout=long +// META: global=serviceworker +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const result = await performance.measureUserAgentSpecificMemory(); + + checkMeasureMemory(result, [ + { + url: self.location.href, + scope: 'ServiceWorkerGlobalScope', + container: null, + }, + ]); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory.'); diff --git a/testing/web-platform/tests/measure-memory/service-worker.https.any.js.headers b/testing/web-platform/tests/measure-memory/service-worker.https.any.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/service-worker.https.any.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/shared-worker.https.any.js b/testing/web-platform/tests/measure-memory/shared-worker.https.any.js new file mode 100644 index 0000000000..4e359ad3fe --- /dev/null +++ b/testing/web-platform/tests/measure-memory/shared-worker.https.any.js @@ -0,0 +1,18 @@ +// META: script=./resources/checker.js +// META: global=sharedworker +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const result = await performance.measureUserAgentSpecificMemory(); + + checkMeasureMemory(result, [ + { + url: self.location.href, + scope: 'SharedWorkerGlobalScope', + container: null, + }, + ]); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory.'); + diff --git a/testing/web-platform/tests/measure-memory/shared-worker.https.any.js.headers b/testing/web-platform/tests/measure-memory/shared-worker.https.any.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/shared-worker.https.any.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/window-open.cross-origin.https.window.js b/testing/web-platform/tests/measure-memory/window-open.cross-origin.https.window.js new file mode 100644 index 0000000000..5305b1c0b0 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.cross-origin.https.window.js @@ -0,0 +1,36 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-origin-1', + window_open: true, + children: [ + { + id: 'same-origin-2', + window_open: true, + }, + { + id: 'same-origin-3', + }, + { + id: 'cross-origin-4', + }, + ] + }, + ]); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + ]); +}, 'performance.measureUserAgentSpecificMemory does not leak URL of cross-origin window.open.'); diff --git a/testing/web-platform/tests/measure-memory/window-open.cross-origin.https.window.js.headers b/testing/web-platform/tests/measure-memory/window-open.cross-origin.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.cross-origin.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/window-open.cross-site.https.window.js b/testing/web-platform/tests/measure-memory/window-open.cross-site.https.window.js new file mode 100644 index 0000000000..3a9481fae6 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.cross-site.https.window.js @@ -0,0 +1,36 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'cross-site-1', + window_open: true, + children: [ + { + id: 'same-origin-2', + window_open: true, + }, + { + id: 'same-origin-3', + }, + { + id: 'cross-origin-4', + }, + ] + }, + ]); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + ]); +}, 'performance.measureUserAgentSpecificMemory does not leak URL of cross-site window.open.'); diff --git a/testing/web-platform/tests/measure-memory/window-open.cross-site.https.window.js.headers b/testing/web-platform/tests/measure-memory/window-open.cross-site.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.cross-site.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/window-open.mix.https.window.js b/testing/web-platform/tests/measure-memory/window-open.mix.https.window.js new file mode 100644 index 0000000000..2b4c9e57aa --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.mix.https.window.js @@ -0,0 +1,136 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'same-origin-1', + children: [ + { + id: 'same-origin-2', + window_open: true, + children: [ + { + id: 'same-origin-3', + window_open: true, + }, + ], + }, + { + id: 'cross-origin-4', + children: [ + { + id: 'same-origin-5', + window_open: true, + }, + ], + }, + { + id: 'cross-site-6', + children: [ + { + id: 'same-origin-7', + window_open: true, + }, + ], + }, + { + id: 'same-origin-8', + children: [ + { + id: 'cross-origin-9', + window_open: true, + children: [ + { + id: 'same-origin-10', + }, + { + id: 'same-origin-11', + window_open: true, + }, + ], + }, + { + id: 'cross-site-12', + window_open: true, + children: [ + { + id: 'same-origin-13', + }, + { + id: 'same-origin-14', + window_open: true, + }, + ], + }, + ], + }, + ] + }, + ]); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-1'].location.href, + scope: 'Window', + container: { + id: 'same-origin-1', + src: iframes['same-origin-1'].src, + }, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-3'].location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-origin-4', + src: iframes['cross-origin-4'].src, + }, + }, + { + url: windows['same-origin-5'].location.href, + scope: 'Window', + container: null, + }, + { + url: 'cross-origin-url', + scope: 'cross-origin-aggregated', + container: { + id: 'cross-site-6', + src: iframes['cross-site-6'].src, + }, + }, + { + url: windows['same-origin-7'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-8'].location.href, + scope: 'Window', + container: { + id: 'same-origin-8', + src: iframes['same-origin-8'].src, + }, + }, + ]); +}, 'performance.measureUserAgentSpecificMemory does not leak URLs in cross-origin iframes and windows.'); diff --git a/testing/web-platform/tests/measure-memory/window-open.mix.https.window.js.headers b/testing/web-platform/tests/measure-memory/window-open.mix.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.mix.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file diff --git a/testing/web-platform/tests/measure-memory/window-open.same-origin.https.window.js b/testing/web-platform/tests/measure-memory/window-open.same-origin.https.window.js new file mode 100644 index 0000000000..f0ff6f2cd7 --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.same-origin.https.window.js @@ -0,0 +1,51 @@ +// META: script=/common/get-host-info.sub.js +// META: script=./resources/checker.js +// META: script=./resources/common.js +// META: timeout=long +'use strict'; + +promise_test(async testCase => { + assert_true(self.crossOriginIsolated); + + const {iframes, windows} = await build([ + { + id: 'same-origin-1', + window_open: true, + children: [ + { + id: 'same-origin-2', + window_open: true, + }, + { + id: 'same-origin-3', + }, + ] + }, + ]); + const result = await performance.measureUserAgentSpecificMemory(); + checkMeasureMemory(result, [ + { + url: window.location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-1'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-2'].location.href, + scope: 'Window', + container: null, + }, + { + url: windows['same-origin-3'].location.href, + scope: 'Window', + container: { + id: 'same-origin-3', + src: iframes['same-origin-3'].src, + }, + }, + ]); +}, 'Well-formed result of performance.measureUserAgentSpecificMemory with same-origin window.open.'); diff --git a/testing/web-platform/tests/measure-memory/window-open.same-origin.https.window.js.headers b/testing/web-platform/tests/measure-memory/window-open.same-origin.https.window.js.headers new file mode 100644 index 0000000000..4fff9d9fba --- /dev/null +++ b/testing/web-platform/tests/measure-memory/window-open.same-origin.https.window.js.headers @@ -0,0 +1,2 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp
\ No newline at end of file |