From a9dc74cdce2cebcd3e42c34111efc3e59058cadc Mon Sep 17 00:00:00 2001 From: Kamil Jopek Date: Thu, 10 Sep 2026 18:27:12 -0500 Subject: [PATCH] test(safe-js): verify each replay checkpoint independently The co scenario combined seven interpreter executions into one five-second case. Exact PR719 reproduction failed that deadline; phase tracing measured 6.78 seconds, dominated by retained-data accounting during repeated runs. Parameterize public, signal, and completed checkpoint contracts with independent setup. Preserve native output, pending-boundary, replay, recapture, immutability, receipt, and no-reexecution assertions without changing timeouts or concurrency. Validation: original focused file reproduced 18 passes and one timeout; revised file passes all 29 cases. The three co cases took 2184ms, 2099ms, and 2126ms under Node20 with the maintained package configuration. --- .../ppr2-integration-adjudication.test.ts | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/packages/safe-js/test/ppr2-integration-adjudication.test.ts b/packages/safe-js/test/ppr2-integration-adjudication.test.ts index 70228918b..aa828c9f2 100644 --- a/packages/safe-js/test/ppr2-integration-adjudication.test.ts +++ b/packages/safe-js/test/ppr2-integration-adjudication.test.ts @@ -39,8 +39,16 @@ afterEach(() => { }); describe("independent ordered PPR2 fresh writer continuations", () => { - it.each(originalScenarios)( - "$id: native trace, public/signal/completed checkpoints and recapture", + it.each( + originalScenarios.flatMap((scenario) => + ["public", "signal", "completed"].map((checkpoint, captureIndex) => ({ + ...scenario, + checkpoint, + captureIndex + })) + ) + )( + "$id / $checkpoint: native trace, checkpoint and recapture", async (scenario) => { const nativeHost = makeFixture(scenario.id, true, scenario.policy); const AsyncFunction = Object.getPrototypeOf(async () => undefined).constructor; @@ -105,40 +113,40 @@ describe("independent ordered PPR2 fresh writer continuations", () => { expect(original.returnValue).toEqual(native); expect(host.calls).toEqual(nativeHost.calls); captures.push(await dump(execution)); - for (const [index, bytes] of captures.entries()) { - const snapshot = restore(JSON.parse(bytes), { source: scenario.source }); - expect(snapshot.executionSemantics).toBe(expectedFresh); - expect(snapshot.version).toBe(2); - const before = JSON.stringify(snapshot); - const rebound = makeFixture(scenario.id, false, scenario.policy); - const requests: HostCallResumeRequest[] = []; - const resumed = await run(scenario.source, { - snapshot, - bindings: rebound.bindings, - budget: new Budget({ maxSteps: 150_000 }), - hostCallResumeProvider: receiptsProvider(original.snapshot.hostCalls ?? [], requests) - }); - expect(resumed.ok).toBe(true); - if (!resumed.ok) throw Error(resumed.error.message); - expect(resumed.returnValue).toEqual(native); - expect(rebound.calls).toEqual(index === 2 ? [] : scenario.resumeCalls); - expect(requests).toHaveLength(index < 2 && scenario.policy === "read-side-effect" ? 1 : 0); - expect(JSON.stringify(snapshot)).toBe(before); - const recaptured = restore(JSON.parse(await dump(resumed)), { source: scenario.source }); - expect(recaptured.executionSemantics).toBe(expectedFresh); - const finalHost = makeFixture(scenario.id, false, scenario.policy); - const finalProvider = vi.fn(); - const final = await run(scenario.source, { - snapshot: recaptured, - bindings: finalHost.bindings, - hostCallResumeProvider: finalProvider - }); - expect(final.ok).toBe(true); - if (!final.ok) throw Error(final.error.message); - expect(final.returnValue).toEqual(native); - expect(finalHost.calls).toEqual([]); - expect(finalProvider).not.toHaveBeenCalled(); - } + const index = scenario.captureIndex; + const bytes = captures[index]!; + const snapshot = restore(JSON.parse(bytes), { source: scenario.source }); + expect(snapshot.executionSemantics).toBe(expectedFresh); + expect(snapshot.version).toBe(2); + const before = JSON.stringify(snapshot); + const rebound = makeFixture(scenario.id, false, scenario.policy); + const requests: HostCallResumeRequest[] = []; + const resumed = await run(scenario.source, { + snapshot, + bindings: rebound.bindings, + budget: new Budget({ maxSteps: 150_000 }), + hostCallResumeProvider: receiptsProvider(original.snapshot.hostCalls ?? [], requests) + }); + expect(resumed.ok).toBe(true); + if (!resumed.ok) throw Error(resumed.error.message); + expect(resumed.returnValue).toEqual(native); + expect(rebound.calls).toEqual(index === 2 ? [] : scenario.resumeCalls); + expect(requests).toHaveLength(index < 2 && scenario.policy === "read-side-effect" ? 1 : 0); + expect(JSON.stringify(snapshot)).toBe(before); + const recaptured = restore(JSON.parse(await dump(resumed)), { source: scenario.source }); + expect(recaptured.executionSemantics).toBe(expectedFresh); + const finalHost = makeFixture(scenario.id, false, scenario.policy); + const finalProvider = vi.fn(); + const final = await run(scenario.source, { + snapshot: recaptured, + bindings: finalHost.bindings, + hostCallResumeProvider: finalProvider + }); + expect(final.ok).toBe(true); + if (!final.ok) throw Error(final.error.message); + expect(final.returnValue).toEqual(native); + expect(finalHost.calls).toEqual([]); + expect(finalProvider).not.toHaveBeenCalled(); } );