diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/measure-memory/resources | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/measure-memory/resources')
17 files changed, 360 insertions, 0 deletions
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 |