Bug 1719139 [wpt PR 29575] - Reland "[COEP] Fix flaky reporting tests for COEP:require-corp.", a=testonly

Automatic update from web-platform-tests
Reland "[COEP] Fix flaky reporting tests for COEP:require-corp."

This is a reland of 93e7378c0b1270c5973d9b63af77caa8a7fb41d5

Original change's description:
> [COEP] Fix flaky reporting tests for COEP:require-corp.
>
> Fixed reporting-navigation and reporting-subresource-corp tests.
>
> Bug: 1218825, 1091665
> Change-Id: I7aaf7e1436373a5a6cd0a8f1d947957b31822cbc
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2980597
> Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
> Commit-Queue: Yifan Luo <lyf@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#898086}

Bug: 1218825, 1091665
Change-Id: I580b13b18b6f14d909dd6fa9fbaa20a7e803e9f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3005344
Reviewed-by: Yifan Luo <lyf@chromium.org>
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Yifan Luo <lyf@chromium.org>
Cr-Commit-Position: refs/heads/master@{#900404}

--

wpt-commits: 2160b7ee5fb13d5bd76b180d54b8a3f6322c8ea9
wpt-pr: 29575
This commit is contained in:
Yifan Luo 2021-07-17 09:48:36 +00:00 коммит произвёл moz-wptsync-bot
Родитель 161ecf6d40
Коммит 6fc17e4536
2 изменённых файлов: 85 добавлений и 71 удалений

Просмотреть файл

@ -5,6 +5,7 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="./credentialless/resources/common.js"></script>
<script>
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();
const COEP = '|header(cross-origin-embedder-policy,require-corp)';
@ -67,16 +68,25 @@ async function loadFrames(test, parentSuffix, withEmptyFrame, targetUrl) {
return parent;
}
async function observeReports(global) {
async function observeReports(global, expected_count) {
const reports = [];
const observer = new global.ReportingObserver((rs) => {
for (const r of rs) {
reports.push(r.toJSON());
}
});
observer.observe();
const receivedEveryReports = new Promise(resolve => {
if (expected_count == 0)
resolve();
// Wait 5000ms for reports to settle.
const observer = new global.ReportingObserver((rs) => {
for (const r of rs) {
reports.push(r.toJSON());
}
if (expected_count <= reports.length)
resolve();
});
observer.observe();
});
// Wait 5000 ms more to catch additionnal unexpected reports.
await receivedEveryReports;
await new Promise(r => step_timeout(r, 5000));
return reports;
}
@ -125,30 +135,31 @@ for (const testcase of CASES) {
loadFrames(t, testcase.parent, withEmptyFrame, targetUrl)
.then(t.step_func(parent => {
const contextUrl = parent.src ? parent.src : 'about:blank';
observeReports(parent.contentWindow).then(t.step_func(reports => {
assert_equals(reports.length, testcase.reports.length);
for (let i = 0; i < reports.length; i += 1) {
const report = reports[i];
switch (testcase.reports[i]) {
case 'CORP':
checkCorpReport(report, contextUrl, targetUrl, 'enforce');
break;
case 'CORP-RO':
checkCorpReport(report, contextUrl, targetUrl, 'reporting');
break;
case 'NAV':
checkCoepMismatchReport(report, contextUrl, targetUrl, 'enforce');
break;
case 'NAV-RO':
checkCoepMismatchReport(report, contextUrl, targetUrl, 'reporting');
break;
default:
assert_unreached(
'Unexpected report expeaction: ' + testcase.reports[i]);
observeReports(parent.contentWindow, testcase.reports.length)
.then(t.step_func(reports => {
assert_equals(reports.length, testcase.reports.length);
for (let i = 0; i < reports.length; i += 1) {
const report = reports[i];
switch (testcase.reports[i]) {
case 'CORP':
checkCorpReport(report, contextUrl, targetUrl, 'enforce');
break;
case 'CORP-RO':
checkCorpReport(report, contextUrl, targetUrl, 'reporting');
break;
case 'NAV':
checkCoepMismatchReport(report, contextUrl, targetUrl, 'enforce');
break;
case 'NAV-RO':
checkCoepMismatchReport(report, contextUrl, targetUrl, 'reporting');
break;
default:
assert_unreached(
'Unexpected report expeaction: ' + testcase.reports[i]);
}
}
}
t.done();
})).catch(t.step_func(e => { throw e; }));
t.done();
})).catch(t.step_func(e => { throw e; }));
})).catch(t.step_func(e => { throw e; }));
}, `parent: ${desc(testcase.parent)}, target: ${desc(testcase.target)}, ` +
`with empty frame: ${withEmptyFrame}`);

Просмотреть файл

@ -20,8 +20,27 @@ const REPORTING_FRAME_URL = `${ORIGIN}${BASE}/reporting-empty-frame.html` +
'?pipe=header(cross-origin-embedder-policy,require-corp)' +
`|header(cross-origin-embedder-policy-report-only,require-corp)`;
function wait(ms) {
return new Promise(resolve => step_timeout(resolve, ms));
async function observeReports(global, expected_count) {
const reports = [];
const receivedEveryReports = new Promise(resolve => {
if (expected_count == 0)
resolve();
const observer = new global.ReportingObserver((rs) => {
for (const r of rs) {
reports.push(r.toJSON());
}
if (expected_count <= reports.length)
resolve();
});
observer.observe();
});
await receivedEveryReports;
// Wait 500ms more to catch additionnal unexpected reports.
await new Promise(r => step_timeout(r, 500));
return reports;
}
function checkReport(report, contextUrl, blockedUrl, disposition, destination) {
@ -33,23 +52,15 @@ function checkReport(report, contextUrl, blockedUrl, disposition, destination) {
assert_equals(report.body.destination, destination);
}
async function fetchInFrame(t, frameUrl, url) {
const reports = [];
async function fetchInFrame(t, frameUrl, url, expected_count) {
const frame = await with_iframe(frameUrl);
t.add_cleanup(() => frame.remove());
const observer = new frame.contentWindow.ReportingObserver((rs) => {
for (const report of rs) {
reports.push(report.toJSON());
}
});
observer.observe();
const init = { mode: 'no-cors', cache: 'no-store' };
let future_reports = observeReports(frame.contentWindow, expected_count);
await frame.contentWindow.fetch(url, init).catch(() => {});
// Wait 200ms for reports to settle.
await wait(200);
return reports;
return await future_reports;
}
async function fetchInWorker(workerOrPort, url) {
@ -84,13 +95,13 @@ async function fetchInWorker(workerOrPort, url) {
const ENVIRONMENTS = [{
tag: 'document',
contextUrl: FRAME_URL,
run: async (test, url) => {
return await fetchInFrame(test, FRAME_URL, url);
run: async (test, url, expected_count) => {
return await fetchInFrame(test, FRAME_URL, url, expected_count);
},
}, {
tag: 'dedicated worker',
contextUrl: WORKER_URL,
run: async (test, url) => {
run: async (test, url, expected_count) => {
const worker = new Worker(WORKER_URL);
worker.addEventListener('error', test.unreached_func('Worker.onerror'));
test.add_cleanup(() => worker.terminate());
@ -99,7 +110,7 @@ const ENVIRONMENTS = [{
}, {
tag: 'shared worker',
contextUrl: WORKER_URL,
run: async (test, url) => {
run: async (test, url, expected_count) => {
const worker = new SharedWorker(WORKER_URL);
worker.addEventListener('error', test.unreached_func('Worker.onerror'));
return await fetchInWorker(worker.port, url);
@ -107,7 +118,7 @@ const ENVIRONMENTS = [{
}, {
tag: 'service worker',
contextUrl: WORKER_URL,
run: async (test, url) => {
run: async (test, url, expected_count) => {
// As we don't want the service worker to control any page, generate a
// one-time scope.
const SCOPE = new URL(`resources/${token()}.html`, location).pathname;
@ -121,7 +132,7 @@ const ENVIRONMENTS = [{
}, {
tag: 'between service worker and page',
contextUrl: REPORTING_FRAME_URL,
run: async (test, url) => {
run: async (test, url, expected_count) => {
// Here we use a Service Worker without COEP.
const WORKER_URL = `${ORIGIN}${BASE}/sw.js`;
const reg = await service_worker_unregister_and_register(
@ -130,36 +141,34 @@ const ENVIRONMENTS = [{
const worker = reg.installing || reg.waiting || reg.active;
worker.addEventListener('error', test.unreached_func('Worker.onerror'));
return await fetchInFrame(
test, REPORTING_FRAME_URL, url);
test, REPORTING_FRAME_URL, url, expected_count);
},
}];
const CASES = [{
name: 'same-origin',
url: '/common/text-plain.txt',
check: (reports, url, contextUrl) => {
assert_equals(reports.length, 0);
}
expected_count: 0,
check: (reports, url, contextUrl) => {}
}, {
name: 'blocked by CORP: same-origin',
url: `${REMOTE_ORIGIN}${BASE}/nothing-same-origin-corp.txt`,
check: (reports, url, contextUrl) => {
assert_equals(reports.length, 0);
}
expected_count: 0,
check: (reports, url, contextUrl) => {}
}, {
name: 'blocked due to COEP',
url: `${REMOTE_ORIGIN}/common/text-plain.txt`,
expected_count: 2,
check: (reports, contextUrl, url) => {
assert_equals(reports.length, 2);
checkReport(reports[0], contextUrl, url, 'reporting', '');
checkReport(reports[1], contextUrl, url, 'enforce', '');
}
}, {
name: 'blocked during redirect',
url: `${ORIGIN}/common/redirect.py?location=` +
encodeURIComponent(`${REMOTE_ORIGIN}/common/text-plain.txt`),
encodeURIComponent(`${REMOTE_ORIGIN}/common/text-plain.txt`),
expected_count: 2,
check: (reports, contextUrl, url) => {
assert_equals(reports.length, 2);
checkReport(reports[0], contextUrl, url, 'reporting', '');
checkReport(reports[1], contextUrl, url, 'enforce', '');
},
@ -168,8 +177,10 @@ const CASES = [{
for (const env of ENVIRONMENTS) {
for (const testcase of CASES) {
promise_test(async (t) => {
const reports = await env.run(t, testcase.url);
const reports = await env.run(
t, testcase.url, testcase.expected_count);
assert_equals(reports.length, testcase.expected_count);
testcase.check(reports, env.contextUrl, testcase.url);
}, `[${env.tag}] ${testcase.name}`);
}
@ -177,24 +188,16 @@ for (const env of ENVIRONMENTS) {
// A test for a non-empty destination.
promise_test(async (t) => {
const reports = [];
const frame = await with_iframe(FRAME_URL);
t.add_cleanup(() => frame.remove());
const observer = new frame.contentWindow.ReportingObserver((rs) => {
for (const report of rs) {
reports.push(report.toJSON());
}
});
observer.observe();
const url = `${REMOTE_ORIGIN}/common/utils.js`;
const script = frame.contentDocument.createElement('script');
script.src = url;
const future_reports = observeReports(frame.contentWindow, 2);
frame.contentDocument.body.appendChild(script);
// Wait 200ms for reports to settle.
await wait(200);
const reports = await future_reports;
assert_equals(reports.length, 2);
checkReport(reports[0], FRAME_URL, url, 'reporting', 'script');
checkReport(reports[1], FRAME_URL, url, 'enforce', 'script');