1550d390cb
improvise-qnpi: `pr-reviews --wait` checked its deadline before the first re-poll, so a second boundary between two reads of the clock skipped the only poll (exit 1 with polls=1, reproduced under CPU load). The deadline is now checked after each poll. A new case drives it with a PATH shim whose `date` ticks one second per read, so it fails deterministically on the old loop rather than under load. improvise-mkbp: harness/opfs-contract/Cargo.lock pinned pest 2.9.1 while its path deps require 2.9.2, so every build rewrote it. The resolved lock is committed and build.sh starts with `cargo metadata --locked`; the wasm-pack `-- --locked` route was tried and does not work (wasm-pack re-resolves first). opfs.spec.js now names the fix when harness/serve/opfs is missing, which is what running web/assemble.sh alone leaves. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
104 lines
3.9 KiB
JavaScript
104 lines
3.9 KiB
JavaScript
// `storage_contract` against `OpfsFs`, in a browser (improvise-vvl3/xf1). The
|
|
// assertions here are about *the report*: context/test-evidence/clients.md.
|
|
|
|
import { test, expect } from "@playwright/test";
|
|
|
|
/** Run one entry point in the harness worker. */
|
|
async function run(page, cmd) {
|
|
return JSON.parse(await page.evaluate((c) => window.opfs(c), cmd));
|
|
}
|
|
|
|
/** The checks the report must contain, in order. Named here as well as in Rust
|
|
* on purpose — see context/test-evidence/clients.md. */
|
|
const EXPECTED = [
|
|
"open_and_refresh_see_an_origin_root_holding_no_documents",
|
|
"an_attached_but_unwritten_entry_is_not_a_document",
|
|
"a_directory_entry_is_not_a_document",
|
|
"refresh_walks_every_key_and_sorts_them",
|
|
"read_and_write_are_absolute_at_offset_zero",
|
|
'storage_contract_at_""',
|
|
'storage_contract_at_"docs"',
|
|
"a_delete_is_visible_at_once_and_lands_on_commit",
|
|
];
|
|
|
|
test.describe("OpfsFs in a real browser", () => {
|
|
test.beforeEach(async ({ page, browserName }, testInfo) => {
|
|
const served = await page.goto("/opfs/index.html");
|
|
expect(
|
|
served?.ok(),
|
|
"harness/serve/opfs is missing: re-run harness/build.sh, not web/assemble.sh alone",
|
|
).toBe(true);
|
|
|
|
// The skip is conditional on the PROBE, not on the browser name, so it
|
|
// cannot quietly swallow a real regression. See clients.md.
|
|
const opfs = await page.evaluate(async () => {
|
|
try {
|
|
await navigator.storage.getDirectory();
|
|
return "yes";
|
|
} catch (err) {
|
|
return String(err?.name ?? err);
|
|
}
|
|
});
|
|
if (opfs !== "yes") {
|
|
expect(
|
|
browserName,
|
|
`${browserName} lost OPFS (${opfs}) — that is a regression, not a known gap`,
|
|
).toBe("webkit");
|
|
testInfo.skip(true, `this WebKit build provides no OPFS (${opfs})`);
|
|
}
|
|
});
|
|
|
|
// Check the checker, and do it first: a green run against a worker that
|
|
// never started is the failure this repo has a doctrine about.
|
|
test("the harness can see a failure", async ({ page }) => {
|
|
const report = await run(page, "run_canary");
|
|
expect(report).toHaveLength(1);
|
|
expect(report[0].name).toBe("the_canary_must_fail");
|
|
expect(report[0].ok).toBe(false);
|
|
expect(report[0].detail).toContain("the harness can see a failure");
|
|
});
|
|
|
|
test("every check in the battery runs and passes", async ({ page }) => {
|
|
const report = await run(page, "run_checks");
|
|
|
|
// The battery is complete before any of it is believed.
|
|
expect(report.map((c) => c.name)).toEqual(EXPECTED);
|
|
|
|
const failed = report.filter((c) => !c.ok);
|
|
expect(
|
|
failed,
|
|
`failing checks:\n${failed.map((c) => ` ${c.name}: ${c.detail}`).join("\n")}`,
|
|
).toEqual([]);
|
|
});
|
|
|
|
// Measurements, not contracts: the read-only boot path (improvise-1wft,
|
|
// i0v9) is decided on these, so they run per engine and say which.
|
|
test("the probes the read-only boot design rests on", async ({ page }, testInfo) => {
|
|
const report = await run(page, "run_probes");
|
|
expect(report.map((c) => c.name)).toEqual([
|
|
"getfile_reads_a_document_under_a_foreign_sync_handle",
|
|
"a_dedicated_worker_satisfies_the_narrow_scope_guard",
|
|
]);
|
|
const failed = report.filter((c) => !c.ok);
|
|
expect(
|
|
failed,
|
|
`failing probes:\n${failed.map((c) => ` ${c.name}: ${c.detail}`).join("\n")}`,
|
|
).toEqual([]);
|
|
// The measurement is the point, so it is attached rather than only asserted.
|
|
await testInfo.attach("opfs-probes.json", {
|
|
body: JSON.stringify(report, null, 2),
|
|
contentType: "application/json",
|
|
});
|
|
});
|
|
|
|
// The one thing no in-page check can establish: "commit_deletes actually
|
|
// removed it" is only answered by a fresh page.
|
|
test("what OPFS held survives a reload, and a committed delete does not", async ({
|
|
page,
|
|
}) => {
|
|
expect(await page.evaluate(() => window.opfs("before_reload"))).toBe("staged");
|
|
await page.reload();
|
|
expect(await page.evaluate(() => window.opfs("after_reload"))).toBe("survived");
|
|
});
|
|
});
|