import assert from "node:assert/strict";
|
import {pathToFileURL} from "node:url";
|
|
const runtime = await import(pathToFileURL(process.argv[2]));
|
const TARGET = "https://space.bilibili.com/1420210197/dynamic";
|
|
function listenerSet() {
|
const listeners = new Set();
|
return {
|
addListener(listener) { listeners.add(listener); },
|
emit(value) { for (const listener of [...listeners]) listener(value); },
|
get size() { return listeners.size; }
|
};
|
}
|
|
function fakeChrome({createStatus = "complete", driftOnGet = false, markerMode = "normal"} = {}) {
|
const tabs = new Map([[1, {id: 1, windowId: 1, status: "complete", url: "https://example.com/user", marker: null}]]);
|
const sessionStorage = new Map();
|
const localStorage = new Map();
|
const stats = {created: 0, removed: 0, updated: 0, closeAttempts: 0};
|
let nextTab = 10;
|
let failRemove = false;
|
let driftPending = driftOnGet;
|
function storageArea(storage) {
|
return {
|
async get(key) { return storage.has(key) ? {[key]: storage.get(key)} : {}; },
|
async set(value) { for (const [key, item] of Object.entries(value)) storage.set(key, structuredClone(item)); },
|
async remove(key) { storage.delete(key); }
|
};
|
}
|
return {
|
tabs: {
|
async create({url, active}) {
|
assert.equal(false, active);
|
const tab = {id: nextTab++, windowId: 2, status: createStatus, url, marker: null};
|
tabs.set(tab.id, tab);
|
stats.created += 1;
|
return {...tab};
|
},
|
async get(id) {
|
if (!tabs.has(id)) throw new Error("missing");
|
if (driftPending && id !== 1) {
|
driftPending = false;
|
tabs.get(id).url = "https://example.com/drifted";
|
}
|
return {...tabs.get(id)};
|
},
|
async remove(id) {
|
stats.closeAttempts += 1;
|
if (failRemove) throw new Error("remove failed");
|
if (!tabs.delete(id)) throw new Error("missing");
|
stats.removed += 1;
|
},
|
async update() { stats.updated += 1; throw new Error("forbidden"); }
|
},
|
scripting: {
|
async executeScript({target, func, args = []}) {
|
const tab = tabs.get(target.tabId);
|
if (!tab) throw new Error("missing");
|
if (func.name === "setOwnershipMarker") {
|
if (markerMode === "throw") throw new Error("injected marker failure");
|
tab.marker = args[0];
|
return [{result: markerMode === "mismatch" ? "mismatch" : tab.marker}];
|
}
|
if (func.name === "readOwnershipMarker") return [{result: tab.marker}];
|
return [{result: {schema_version: 1, final_url: tab.url}}];
|
}
|
},
|
storage: {session: storageArea(sessionStorage), local: storageArea(localStorage)},
|
_tabs: tabs,
|
_storage: sessionStorage,
|
_local: localStorage,
|
_stats: stats,
|
_setFailRemove(value) { failRemove = value; }
|
};
|
}
|
|
function fakePort(mode = "open") {
|
const onMessage = listenerSet();
|
const onDisconnect = listenerSet();
|
const stats = {writes: 0, disconnects: 0};
|
let disconnected = mode === "before";
|
return {
|
onMessage,
|
onDisconnect,
|
postMessage() {
|
if (disconnected) throw new Error("peer closed");
|
stats.writes += 1;
|
if (mode === "during") {
|
disconnected = true;
|
onDisconnect.emit();
|
}
|
},
|
disconnect() {
|
if (disconnected) return;
|
disconnected = true;
|
stats.disconnects += 1;
|
onDisconnect.emit();
|
},
|
closeFromPeer() {
|
if (disconnected) return;
|
disconnected = true;
|
onDisconnect.emit();
|
},
|
stats
|
};
|
}
|
|
const chrome = fakeChrome();
|
const lifecycle = new runtime.OwnedTabLifecycle(chrome, {
|
randomHex: () => "ab".repeat(16),
|
delay: async () => undefined,
|
maxPolls: 1
|
});
|
|
// One hundred independent scheduled slots leave no tab, storage, or global
|
// process-like handle behind and never touch the user's pre-existing tab.
|
for (let index = 0; index < 100; index += 1) {
|
const slot = index.toString(16).padStart(64, "0");
|
const created = await lifecycle.create(slot, TARGET);
|
assert.equal(runtime.FIXED_LIFECYCLE.CLOSED, await lifecycle.cleanup(created.record));
|
assert.deepEqual([...chrome._tabs.keys()], [1]);
|
assert.equal(0, chrome._storage.size);
|
}
|
assert.deepEqual(chrome._stats, {created: 100, removed: 100, updated: 0, closeAttempts: 100});
|
|
// Every post-create failure is closed inside create's unescaped capability.
|
// The ordinary recovery path below remains marker-bound and fail closed.
|
for (const [options, pattern] of [
|
[{createStatus: "loading"}, /E_TAB_TIMEOUT/u],
|
[{driftOnGet: true}, /E_TAB_IDENTITY/u],
|
[{markerMode: "throw"}, /injected marker failure/u],
|
[{markerMode: "mismatch"}, /E_TAB_MARKER/u]
|
]) {
|
const failedChrome = fakeChrome(options);
|
const failedLifecycle = new runtime.OwnedTabLifecycle(failedChrome, {
|
randomHex: () => "ba".repeat(16), delay: async () => undefined, maxPolls: 1
|
});
|
await assert.rejects(failedLifecycle.create("a".repeat(64), TARGET), pattern);
|
assert.deepEqual([...failedChrome._tabs.keys()], [1]);
|
assert.equal(0, failedChrome._storage.size);
|
assert.deepEqual(failedChrome._stats, {created: 1, removed: 1, updated: 0, closeAttempts: 1});
|
}
|
|
// A removed tab is idempotent success.
|
const missing = await lifecycle.create("f".repeat(64), TARGET);
|
chrome._tabs.delete(missing.record.tab_id);
|
assert.equal(runtime.FIXED_LIFECYCLE.ALREADY_CLOSED, await lifecycle.cleanup(missing.record));
|
|
// A same-id, same-URL user replacement cannot satisfy the unforgeable marker.
|
const drift = await lifecycle.create("e".repeat(64), TARGET);
|
chrome._tabs.set(drift.record.tab_id, {
|
id: drift.record.tab_id, windowId: drift.record.window_id,
|
status: "complete", url: TARGET, marker: "user-replacement"
|
});
|
const removesBeforeDrift = chrome._stats.closeAttempts;
|
assert.equal(runtime.FIXED_LIFECYCLE.IDENTITY_DRIFT, await lifecycle.cleanup(drift.record));
|
assert.equal(removesBeforeDrift, chrome._stats.closeAttempts);
|
assert.equal(0, chrome._stats.updated);
|
|
// A remove failure retires ownership and performs no retry or about:blank fallback.
|
const failed = await lifecycle.create("d".repeat(64), TARGET);
|
chrome._setFailRemove(true);
|
assert.equal(runtime.FIXED_LIFECYCLE.CLOSE_FAILED, await lifecycle.cleanup(failed.record));
|
assert.equal(0, chrome._storage.size);
|
const attemptsAfterFailure = chrome._stats.closeAttempts;
|
assert.equal(runtime.FIXED_LIFECYCLE.ALREADY_CLOSED, await lifecycle.cleanup());
|
assert.equal(attemptsAfterFailure, chrome._stats.closeAttempts);
|
assert.equal(0, chrome._stats.updated);
|
chrome._setFailRemove(false);
|
|
// Service-worker restart recovery uses the durable marker-bound record once.
|
const recoverable = await lifecycle.create("c".repeat(64), TARGET);
|
const restarted = new runtime.OwnedTabLifecycle(chrome, {
|
randomHex: () => "cd".repeat(16), delay: async () => undefined, maxPolls: 1
|
});
|
assert.equal(runtime.FIXED_LIFECYCLE.CLOSED, await restarted.cleanup());
|
assert.equal(false, chrome._tabs.has(recoverable.record.tab_id));
|
|
// Native-port handlers exist before the first write, writes serialize, and
|
// peer exits before/during/after a write become one fixed sanitized error.
|
for (const mode of ["before", "during"]) {
|
const port = fakePort(mode);
|
const transport = new runtime.NativePortTransport(port);
|
assert.equal(1, port.onMessage.size);
|
assert.equal(1, port.onDisconnect.size);
|
await assert.rejects(transport.send({schema_version: 1}), /E_NATIVE_PEER_CLOSED/u);
|
}
|
const afterPort = fakePort();
|
const after = new runtime.NativePortTransport(afterPort);
|
await after.send({sequence: 1});
|
afterPort.closeFromPeer();
|
await assert.rejects(after.send({sequence: 2}), /E_NATIVE_PEER_CLOSED/u);
|
assert.equal(1, afterPort.stats.writes);
|
|
const serializedPort = fakePort();
|
const serialized = new runtime.NativePortTransport(serializedPort);
|
await Promise.all([serialized.send({sequence: 1}), serialized.send({sequence: 2})]);
|
assert.equal(2, serializedPort.stats.writes);
|
serialized.disconnect();
|
serialized.disconnect();
|
assert.equal(1, serializedPort.stats.disconnects);
|
|
function hashSlot(material) {
|
const match = /^dynamic-slot:([0-9]+)$/u.exec(material);
|
assert.ok(match);
|
return Promise.resolve(BigInt(match[1]).toString(16).padStart(64, "0"));
|
}
|
|
function successfulCoordinator(testChrome, {connectStats = {count: 0}, control = null} = {}) {
|
const slotStore = new runtime.SlotStateStore(testChrome, {randomHex: () => "ef".repeat(16)});
|
const slotLifecycle = new runtime.OwnedTabLifecycle(testChrome, {
|
randomHex: () => "de".repeat(16), delay: async () => undefined, maxPolls: 1
|
});
|
return {
|
slotStore,
|
coordinator: new runtime.SlotCoordinator({
|
lifecycle: slotLifecycle,
|
slotStore,
|
hashSlot,
|
collectPage: () => ({schema_version: 1}),
|
connect() {
|
connectStats.count += 1;
|
const port = fakePort();
|
const original = port.postMessage.bind(port);
|
port.postMessage = (message) => {
|
original(message);
|
if (message?.type === "CLIENT_HELLO") {
|
if (control?.onHello) control.onHello();
|
queueMicrotask(() => port.onMessage.emit({
|
type: "HOST_ACTION", action_id: "action-1", kind: "goto", url: TARGET
|
}));
|
} else if (message?.type === "CLIENT_ACTION_RESULT") {
|
if (control?.onOutcome) control.onOutcome();
|
const release = control?.commitRelease || Promise.resolve();
|
void Promise.resolve(release).then(() => {
|
queueMicrotask(() => port.onMessage.emit({type: "HOST_COMMIT_RESULT", result: {accepted: true}}));
|
});
|
}
|
};
|
return new runtime.NativePortTransport(port, {timeoutMilliseconds: 1000});
|
},
|
createSession(api) {
|
return {
|
helloFrame() { return {type: "CLIENT_HELLO"}; },
|
async accept(message) {
|
if (message?.type === "HOST_ACTION") {
|
const prepared = await api.prepare(message);
|
const dispatched = await api.dispatch(prepared);
|
await api.observe(dispatched);
|
return {type: "CLIENT_ACTION_RESULT"};
|
}
|
return null;
|
}
|
};
|
}
|
})
|
};
|
}
|
|
// A durable terminal suppresses serial replay, a fresh service-worker instance,
|
// and duplicate-alarm delivery before any Native connection or browser action.
|
const slotChrome = fakeChrome();
|
const connectStats = {count: 0};
|
const firstWorker = successfulCoordinator(slotChrome, {connectStats});
|
assert.equal("COMPLETE", (await firstWorker.coordinator.run("dynamic-slot:100")).status);
|
const afterFirst = {...slotChrome._stats, connects: connectStats.count};
|
assert.equal("SKIPPED_TERMINAL", (await firstWorker.coordinator.run("dynamic-slot:100")).status);
|
const secondWorker = successfulCoordinator(slotChrome, {connectStats});
|
assert.equal("SKIPPED_TERMINAL", (await secondWorker.coordinator.run("dynamic-slot:100")).status);
|
assert.equal("SKIPPED_TERMINAL", (await secondWorker.coordinator.run("dynamic-slot:100")).status);
|
assert.deepEqual({...slotChrome._stats, connects: connectStats.count}, afterFirst);
|
|
// Restart before terminal resumes only the same lease for cleanup and records a
|
// fixed interrupted terminal; it never creates another tab or Native session.
|
const slot101Id = await hashSlot("dynamic-slot:101");
|
const interruptedClaim = await secondWorker.slotStore.claim("dynamic-slot:101", slot101Id);
|
assert.equal("CLAIMED", interruptedClaim.disposition);
|
const interruptedLifecycle = secondWorker.coordinator.lifecycle;
|
await interruptedLifecycle.create(slot101Id, TARGET, interruptedClaim.entry.lease_id);
|
const beforeResume = {...slotChrome._stats, connects: connectStats.count};
|
const thirdWorker = successfulCoordinator(slotChrome, {connectStats});
|
assert.deepEqual(await thirdWorker.coordinator.run("dynamic-slot:101"), {
|
status: "FAILED", error_code: "E_SLOT_INTERRUPTED"
|
});
|
assert.equal(beforeResume.created, slotChrome._stats.created);
|
assert.equal(beforeResume.connects, connectStats.count);
|
assert.equal(beforeResume.removed + 1, slotChrome._stats.removed);
|
assert.equal("SKIPPED_TERMINAL", (await thirdWorker.coordinator.run("dynamic-slot:101")).status);
|
|
// The production startup path terminalizes an old STARTED lease before a
|
// different, normally scheduled next slot is claimed. Cover no-tab, exact-tab,
|
// and one-shot cleanup-failure recovery without any Native action for the old
|
// lease or a permanent BUSY state.
|
const startupChrome = fakeChrome();
|
const startupConnects = {count: 0};
|
let startupWorker = successfulCoordinator(startupChrome, {connectStats: startupConnects});
|
const old200Id = await hashSlot("dynamic-slot:200");
|
assert.equal("CLAIMED", (await startupWorker.slotStore.claim("dynamic-slot:200", old200Id)).disposition);
|
assert.equal("E_SLOT_INTERRUPTED", (await startupWorker.coordinator.recover()).result_code);
|
assert.equal(0, startupConnects.count);
|
assert.equal("COMPLETE", (await startupWorker.coordinator.run("dynamic-slot:201")).status);
|
|
const old202Id = await hashSlot("dynamic-slot:202");
|
const old202 = await startupWorker.slotStore.claim("dynamic-slot:202", old202Id);
|
await startupWorker.coordinator.lifecycle.create(old202Id, TARGET, old202.entry.lease_id);
|
const removesBeforeStartup = startupChrome._stats.removed;
|
startupWorker = successfulCoordinator(startupChrome, {connectStats: startupConnects});
|
assert.equal("E_SLOT_INTERRUPTED", (await startupWorker.coordinator.recover()).result_code);
|
assert.equal(removesBeforeStartup + 1, startupChrome._stats.removed);
|
assert.equal("COMPLETE", (await startupWorker.coordinator.run("dynamic-slot:203")).status);
|
|
const old204Id = await hashSlot("dynamic-slot:204");
|
const old204 = await startupWorker.slotStore.claim("dynamic-slot:204", old204Id);
|
await startupWorker.coordinator.lifecycle.create(old204Id, TARGET, old204.entry.lease_id);
|
startupChrome._setFailRemove(true);
|
const failedCloseRecovery = await successfulCoordinator(startupChrome, {connectStats: startupConnects}).coordinator.recover();
|
assert.equal(runtime.FIXED_LIFECYCLE.CLOSE_FAILED, failedCloseRecovery.lifecycle_code);
|
startupChrome._setFailRemove(false);
|
assert.equal("COMPLETE", (await successfulCoordinator(startupChrome, {connectStats: startupConnects}).coordinator.run("dynamic-slot:205")).status);
|
|
// Terminal state/result pairs are semantic, not merely syntactic. Every cross
|
// pair, null, unknown, and wrong-type value fails strict read with mutation0.
|
for (const [state, result_code] of [
|
["COMPLETE", "E_SLOT_FAILED"],
|
["COMPLETE", null],
|
["COMPLETE", 7],
|
["FAILED", "SLOT_COMPLETE"],
|
["FAILED", null],
|
["FAILED", "UNKNOWN"]
|
]) {
|
const pairChrome = fakeChrome();
|
const corrupt = {
|
schema: 1,
|
entries: [{
|
schema: 1,
|
slot_material: "dynamic-slot:300",
|
slot_number: 300,
|
slot_id: await hashSlot("dynamic-slot:300"),
|
lease_id: "aa".repeat(16),
|
state,
|
result_code
|
}]
|
};
|
pairChrome._local.set(runtime.SLOT_STATE_STORAGE_KEY, corrupt);
|
const before = JSON.stringify(corrupt);
|
await assert.rejects(new runtime.SlotStateStore(pairChrome).read(), /E_SLOT_STATE/u);
|
assert.equal(before, JSON.stringify(pairChrome._local.get(runtime.SLOT_STATE_STORAGE_KEY)));
|
}
|
|
// Malformed durable state is rejected without repair, browser/native action, or
|
// storage mutation.
|
const driftChrome = fakeChrome();
|
const driftStats = {count: 0};
|
driftChrome._local.set(runtime.SLOT_STATE_STORAGE_KEY, {schema: 1, entries: [], extra: true});
|
const driftBytes = JSON.stringify(driftChrome._local.get(runtime.SLOT_STATE_STORAGE_KEY));
|
const driftWorker = successfulCoordinator(driftChrome, {connectStats: driftStats});
|
assert.deepEqual(await driftWorker.coordinator.run("dynamic-slot:102"), {
|
status: "FAILED", error_code: "E_SLOT_STATE"
|
});
|
assert.equal(driftBytes, JSON.stringify(driftChrome._local.get(runtime.SLOT_STATE_STORAGE_KEY)));
|
assert.deepEqual(driftChrome._stats, {created: 0, removed: 0, updated: 0, closeAttempts: 0});
|
assert.equal(0, driftStats.count);
|
|
// The coordinator-wide gate includes the whole active run. A startup recovery
|
// arriving after CLIENT_HELLO waits until the active lease has appended and
|
// rebound its terminal; it cannot relabel that lease as interrupted.
|
const helloRaceChrome = fakeChrome();
|
const helloRaceStats = {count: 0};
|
let signalHello;
|
let releaseCommit;
|
const helloSeen = new Promise((resolve) => { signalHello = resolve; });
|
const commitRelease = new Promise((resolve) => { releaseCommit = resolve; });
|
const helloRaceWorker = successfulCoordinator(helloRaceChrome, {
|
connectStats: helloRaceStats,
|
control: {onHello: signalHello, commitRelease}
|
});
|
const helloRun = helloRaceWorker.coordinator.run("dynamic-slot:400");
|
await helloSeen;
|
let helloRecoverySettled = false;
|
const helloRecovery = helloRaceWorker.coordinator.recover().then((value) => {
|
helloRecoverySettled = true;
|
return value;
|
});
|
await new Promise((resolve) => setImmediate(resolve));
|
assert.equal(false, helloRecoverySettled);
|
releaseCommit();
|
assert.equal("COMPLETE", (await helloRun).status);
|
assert.equal(null, await helloRecovery);
|
const helloRoot = await helloRaceWorker.slotStore.read();
|
assert.deepEqual(helloRoot.entries.filter((entry) => entry.slot_material === "dynamic-slot:400").map((entry) => [entry.state, entry.result_code]), [["COMPLETE", "SLOT_COMPLETE"]]);
|
|
// The gate also spans outcome-to-terminal append/readback. A startup event
|
// queues behind that append, while a duplicate alarm is skipped without action.
|
const finishRaceChrome = fakeChrome();
|
const finishRaceStats = {count: 0};
|
const finishRaceWorker = successfulCoordinator(finishRaceChrome, {connectStats: finishRaceStats});
|
const originalFinish = finishRaceWorker.slotStore.finish.bind(finishRaceWorker.slotStore);
|
let signalFinish;
|
let releaseFinish;
|
const finishSeen = new Promise((resolve) => { signalFinish = resolve; });
|
const finishRelease = new Promise((resolve) => { releaseFinish = resolve; });
|
finishRaceWorker.slotStore.finish = async (...args) => {
|
if (args[1] === "COMPLETE") {
|
signalFinish();
|
await finishRelease;
|
}
|
return await originalFinish(...args);
|
};
|
const finishRun = finishRaceWorker.coordinator.run("dynamic-slot:401");
|
await finishSeen;
|
let finishRecoverySettled = false;
|
const finishRecovery = finishRaceWorker.coordinator.recover().then((value) => {
|
finishRecoverySettled = true;
|
return value;
|
});
|
assert.deepEqual(await finishRaceWorker.coordinator.run("dynamic-slot:402"), {status: "SKIPPED_OVERLAP"});
|
await new Promise((resolve) => setImmediate(resolve));
|
assert.equal(false, finishRecoverySettled);
|
releaseFinish();
|
assert.equal("COMPLETE", (await finishRun).status);
|
assert.equal(null, await finishRecovery);
|
assert.equal("COMPLETE", (await finishRaceWorker.coordinator.run("dynamic-slot:402")).status);
|
const finishRoot = await finishRaceWorker.slotStore.read();
|
assert.deepEqual(finishRoot.entries.filter((entry) => entry.slot_material === "dynamic-slot:401").map((entry) => [entry.state, entry.result_code]), [["COMPLETE", "SLOT_COMPLETE"]]);
|
|
assert.equal(0, chrome._stats.updated);
|
assert.deepEqual(chrome._tabs.get(1), {id: 1, windowId: 1, status: "complete", url: "https://example.com/user", marker: null});
|
process.stdout.write(JSON.stringify({
|
ok: true,
|
slots: 100,
|
create_failure_cleanup: 4,
|
durable_slot_replay: true,
|
startup_next_slot_recovery: 3,
|
terminal_cross_pair_rejections: 6,
|
coordinator_wide_races: 2,
|
tabs_update: 0,
|
user_tab_preserved: true
|
}) + "\n");
|