Repository navigation
test: assert these contracts by behaviour instead of by source shape #4846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
01abdb8
d6ebcc8
d6b20ff
433b356
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,4 @@ | ||
| import { describe, expect, test } from "bun:test"; | ||
| import { readFileSync } from "node:fs"; | ||
| import { | ||
| CODEX_TEXT_GUARDED_BUDGET_POLICY, | ||
| createRequestExecutionBudget, | ||
|
|
@@ -200,76 +199,73 @@ describe("layer caps intersect the shared budget", () => { | |
| }); | ||
|
|
||
| /** | ||
| * The refund property above is only worth something if every caller actually uses it. | ||
| * A credential hop reserves before it knows whether account resolution, request rebuilding, or | ||
| * admission will reach the wire. The reservation is a real charge immediately, so every exit | ||
| * before dispatch must release it. Once bytes leave, the same permit must become non-refundable. | ||
| * | ||
| * The generic-OAuth 429 ladder reserves a hop before it knows whether a rotation is possible. | ||
| * Two of its three exits released correctly and the `catch` did not, so a throw from the | ||
| * snapshot fetch or from credential application charged the request for a send that never left | ||
| * the process — and a later recovery in the same request was then refused on an allowance | ||
| * nothing had spent. The passthrough and runTurn ladders already had it right; these two did not. | ||
| * | ||
| * This is a source oracle because the defect lives in the caller's control flow, not in the | ||
| * budget: a unit test of the budget cannot see a caller that forgets to hand the permit back. | ||
| * These cases assert the permit state and spend observer directly. They fail on the historical | ||
| * accounting defect without depending on a particular server function name or catch-block shape. | ||
| */ | ||
| describe("generic-OAuth hop reservations are handed back when no send happens", () => { | ||
| // Bounded to each ladder's own span and matched on the catch that opens it. An earlier version | ||
| // of this test searched from the first following "catch {" and found the inline body-cancel | ||
| // catch instead, so it passed while the defect was still present. | ||
| const ladder = (relativePath: string, fromMarker: string, toMarker: string): string => { | ||
| const source = readFileSync(new URL("../../" + relativePath, import.meta.url), "utf8"); | ||
| const from = source.indexOf(fromMarker); | ||
| const to = source.indexOf(toMarker, from); | ||
| expect(from).toBeGreaterThan(-1); | ||
| expect(to).toBeGreaterThan(from); | ||
| return source.slice(from, to); | ||
| describe("dispatch permits distinguish pre-send failures from physical sends", () => { | ||
| const recordingObserver = () => { | ||
| const events: string[] = []; | ||
| return { | ||
| events, | ||
| observer: { | ||
| charge: () => { events.push("charge"); return true; }, | ||
| refund: () => { events.push("refund"); }, | ||
| }, | ||
| }; | ||
| }; | ||
| const refundsOnThrow = /catch \{[^}]*hop\.permit\?\.release\(\)/; | ||
|
|
||
| test("the adapter dispatch ladder confirms at the dispatch boundary and refunds otherwise", () => { | ||
| const source = readFileSync(new URL("../../src/server/responses/adapter-dispatch.ts", import.meta.url), "utf8"); | ||
| // Confirming before the rebuild is not enough: buildRequest failures return { failed } | ||
| // without reaching the wire, so the hop is confirmed by the callback the rebuild invokes at | ||
| // its dispatch boundary, and the { failed } arm refunds whatever that callback did not spend. | ||
| expect(source).toContain("onDispatch?.()"); | ||
| // Confirmed at the wire, not before the pacer: waitForProviderRequestSlot can reject for an | ||
| // abort, a saturated queue, an expired slot or a removed provider without ever calling the | ||
| // adapter, and release() is a no-op once used, so an early confirm could never be refunded. | ||
| const slotWait = source.indexOf("await waitForProviderRequestSlot("); | ||
| const confirmAfterWait = source.indexOf("onDispatch?.()", slotWait); | ||
| const adapterSend = source.indexOf("transportState.activeAdapter.fetchResponse(retryRequest", confirmAfterWait); | ||
| expect(slotWait).toBeGreaterThan(-1); | ||
| expect(confirmAfterWait).toBeGreaterThan(slotWait); | ||
| expect(adapterSend).toBeGreaterThan(confirmAfterWait); | ||
| // The helper path has the same boundary inside the thunk that reaches the wire. | ||
| const thunkConfirm = source.indexOf("onDispatch?.()", adapterSend); | ||
| const headerTimeout = source.indexOf("fetchWithHeaderTimeout(retryRequest.url", thunkConfirm); | ||
| expect(thunkConfirm).toBeGreaterThan(adapterSend); | ||
| expect(headerTimeout).toBeGreaterThan(thunkConfirm); | ||
| const block = ladder( | ||
| "src/server/responses/adapter-dispatch.ts", | ||
| "adapter-recovery-oauth-429", | ||
| "attemptOpaqueBlobRecovery", | ||
| ); | ||
| expect(block).toContain('rebuildAndRefetch("oauth-account-429", () => {'); | ||
| // ...except on an adapter-owned ladder, which confirms through its own reservation. Settling | ||
| // here as well would close the permit before `adapterDispatchBudget` could hand it over, and | ||
| // an adapter whose `use()` fails reads the request as exhausted and stops sending (#4709). | ||
| expect(block).toContain("if (!adapterOwnsDispatch) hop.permit?.use();"); | ||
| expect(block).toContain("sendBudgetState.pendingHopPermit = hop.permit;"); | ||
| expect(block).toMatch(/if \("failed" in result\) \{[^}]*hop\.permit\?\.release\(\)/); | ||
| expect(block).toMatch(refundsOnThrow); | ||
|
|
||
| test("a reservation released after a pre-dispatch failure books no spend", () => { | ||
| const spy = recordingObserver(); | ||
| const budget = createRequestExecutionBudget(ONE_SEND_LEFT, "lr-pre-dispatch", spy.observer); | ||
| const hop = budget.reserveDispatch({ | ||
| sendClass: "auth-recovery", | ||
| targetKey: "provider|model", | ||
| countedExternally: true, | ||
| }); | ||
| if (!hop.allowed) throw new Error("unreachable"); | ||
|
|
||
| let physicalSends = 0; | ||
| try { | ||
| throw new Error("credential application failed"); | ||
| } catch { | ||
| hop.permit.release(); | ||
| } | ||
|
|
||
| expect(physicalSends).toBe(0); | ||
| expect(budget.used).toBe(0); | ||
| expect(spy.events).toEqual(["charge", "refund"]); | ||
| expect(hop.permit.use()).toBe(false); | ||
| expect(budget.reserveDispatch({ sendClass: "auth-recovery", targetKey: "provider|model" }).allowed) | ||
| .toBe(true); | ||
| }); | ||
|
|
||
| test("the continuation ladder refunds, because its send happens after the loop continues", () => { | ||
| const block = ladder( | ||
| "src/server/responses/adapter-continuation.ts", | ||
| "continuation-oauth-429", | ||
| "shouldAttemptImageTierRetry", | ||
| ); | ||
| // Nothing in that try dispatches: the replay is the next iteration, so a throw must return | ||
| // the reservation rather than confirm it. | ||
| expect(block).not.toContain("hop.permit?.use()"); | ||
| expect(block).toMatch(refundsOnThrow); | ||
| test("a reservation confirmed at dispatch stays charged after a later failure", () => { | ||
| const spy = recordingObserver(); | ||
| const budget = createRequestExecutionBudget(ONE_SEND_LEFT, "lr-post-dispatch", spy.observer); | ||
| const hop = budget.reserveDispatch({ | ||
| sendClass: "auth-recovery", | ||
| targetKey: "provider|model", | ||
| }); | ||
| if (!hop.allowed) throw new Error("unreachable"); | ||
|
|
||
| let physicalSends = 0; | ||
| try { | ||
| physicalSends += 1; | ||
| expect(hop.permit.use()).toBe(true); | ||
| throw new Error("upstream rejected after dispatch"); | ||
| } catch { | ||
| hop.permit.release(); | ||
| } | ||
|
|
||
| expect(physicalSends).toBe(1); | ||
| expect(budget.used).toBe(1); | ||
| expect(spy.events).toEqual(["charge"]); | ||
| expect(budget.reserveDispatch({ sendClass: "transient", targetKey: "provider|model" })) | ||
| .toEqual({ allowed: false, reason: "total-exhausted" }); | ||
|
Comment on lines
+221
to
+268
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift 🔎 Supported by static analysis🏁 Script executed: sed -n '190,340p' tests/lib/execution-budget-permits.test.ts
sed -n '1,200p' tests/lib/transient-budget-scope-source.test.ts
rg -n -C 3 'adapterOwnsDispatch|adapterSendBudget|remainingTransientSendBudget|reserveDispatch|deriveRequestExecutionBudget|onSendsConsumed' src testsRepository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- diff stat ---'
git diff --stat
printf '%s\n' '--- production budget/retry usages ---'
rg -n -C 2 'reserveDispatch|deriveRequestExecutionBudget|fetchWithTransientRetry|fetchWithResetRetry|onSendsConsumed|remainingBaseSends' src --glob '*.ts'
printf '%s\n' '--- related tests ---'
rg -n -C 2 'reserveDispatch|deriveRequestExecutionBudget|fetchWithTransientRetry|fetchWithResetRetry|onSendsConsumed|remainingBaseSends|execution budget|send budget' tests --glob '*.ts'
printf '%s\n' '--- focused diff for cited tests ---'
git diff --unified=5 -- tests/lib/execution-budget-permits.test.ts tests/lib/transient-budget-scope-source.test.tsRepository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- repository state ---'
git status --short
git log -1 --oneline
printf '%s\n' '--- focused test files ---'
fd -t f tests | rg '(responses|adapter|budget|continuation|combo|dispatch|passthrough|codex)'
printf '%s\n' '--- exact budget/retry references in tests ---'
rg -n 'reserveDispatch|deriveRequestExecutionBudget|fetchWithTransientRetry|fetchWithResetRetry|remainingTransientSendBudget|sendBudget|noteTransientSends' tests --glob '*.ts' | head -n 300
printf '%s\n' '--- request-send-budget ---'
sed -n '1,280p' src/server/responses/request-send-budget.ts
printf '%s\n' '--- adapter-continuation handoff ---'
sed -n '180,255p' src/server/responses/adapter-continuation.ts
printf '%s\n' '--- core-combo construction and handoff ---'
sed -n '100,150p' src/server/responses/core-combo.ts
sed -n '420,470p' src/server/responses/core-combo.ts
printf '%s\n' '--- adapter-dispatch selection and handoff ---'
sed -n '285,345p' src/server/responses/adapter-dispatch.ts
sed -n '450,510p' src/server/responses/adapter-dispatch.tsRepository: lidge-jun/opencodex Length of output: 48496 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- adapter send-budget wiring test ---'
sed -n '1,230p' tests/adapters/adapter-inner-send-budget-wiring.test.ts
printf '%s\n' '--- combo failover e2e test ---'
sed -n '1,190p' tests/server/server-combo-failover-e2e.test.ts
printf '%s\n' '--- response core budget tests ---'
sed -n '1,230p' tests/responses/responses-core-modules.test.ts
printf '%s\n' '--- response spend-ledger tests ---'
sed -n '1,180p' tests/responses/responses-spend-ledger-wiring.test.ts
printf '%s\n' '--- HEAD test changes ---'
git show --stat --oneline HEAD
git diff --unified=4 HEAD^ HEAD -- tests/lib/execution-budget-permits.test.ts tests/lib/transient-budget-scope-source.test.ts tests/adapters/adapter-inner-send-budget-wiring.test.ts tests/server/server-combo-failover-e2e.test.ts tests/responses/responses-core-modules.test.ts tests/responses/responses-spend-ledger-wiring.test.tsRepository: lidge-jun/opencodex Length of output: 50375 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- remaining adapter wiring test ---'
sed -n '190,380p' tests/adapters/adapter-inner-send-budget-wiring.test.ts
printf '%s\n' '--- targeted behavioral test names ---'
rg -n -C 4 'test\(".*(budget|retry|combo|continu|5xx|send|ledger|handoff)|it\(".*(budget|retry|combo|continu|5xx|send|ledger|handoff)' \
tests/server/server-combo-failover-e2e.test.ts \
tests/responses/responses-*.test.ts \
tests/adapters/adapter-inner-send-budget-wiring.test.ts
printf '%s\n' '--- removed production-coverage assertions ---'
for f in tests/lib/execution-budget-permits.test.ts tests/lib/transient-budget-scope-source.test.ts; do
echo "FILE $f"
git show HEAD^:"$f" | rg -n -C 3 'source|adapter-dispatch|adapter-continuation|run-turn-execution|continuation|combo|fetchWithTransientRetry|fetchWithResetRetry|onSendsConsumed|sendBudget|attempts|derive'
doneRepository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- send-count integration tests ---'
sed -n '80,190p' tests/responses/responses-send-budget-counts.test.ts
printf '%s\n' '--- pool recovery integration tests ---'
sed -n '380,480p' tests/responses/responses-pool-401-refresh.test.ts
sed -n '920,980p' tests/responses/responses-pool-401-refresh.test.ts
sed -n '1135,1225p' tests/responses/responses-pool-401-refresh.test.ts
printf '%s\n' '--- combo scope construction ---'
rg -n -C 6 'deriveSendBudgetScope|comboSendScope|options\.sendBudget|handleComboResponses|handleResponses\(' src/server/responses --glob '*.ts'
printf '%s\n' '--- focused test names in send-count file ---'
rg -n 'test\(|it\(' tests/responses/responses-send-budget-counts.test.tsRepository: lidge-jun/opencodex Length of output: 42059 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- send-count fixture and retry-selection cases ---'
sed -n '1,85p' tests/responses/responses-send-budget-counts.test.ts
sed -n '185,265p' tests/responses/responses-send-budget-counts.test.ts
printf '%s\n' '--- tests mentioning the adapter handoff seam ---'
rg -n -C 3 'adapterDispatchBudget|pendingHopPermit|reserveCredentialHop|recoverySendAllowance|onPhysicalSend|sendBudget:' tests --glob '*.ts' | head -n 260Repository: lidge-jun/opencodex Length of output: 16184 Add a production-path test for the adapter budget handoff. The current tests validate the budget primitives. A regression that omits The existing Responses send-count tests cover combo ledger sharing and generic retry reporting; this test should focus only on the adapter-owned handoff. 🤖 Prompt for AI Agents |
||
| }); | ||
| }); | ||
|
|
||
|
|
@@ -327,27 +323,6 @@ describe("a credential hop is settled by whichever layer dispatches its replay", | |
| expect(budget.used).toBe(2); | ||
| }); | ||
|
|
||
| test("the three adapter hop sites hand their reservation down instead of double-charging", () => { | ||
| const responses = (name: string): string => | ||
| readFileSync(new URL("../../src/server/responses/" + name, import.meta.url), "utf8"); | ||
| // The adapter recovery loop and the continuation loop both pick their settlement from the | ||
| // shape of the dispatcher, so neither promises an external report an adapter would never make. | ||
| for (const name of ["adapter-dispatch.ts", "adapter-continuation.ts"]) { | ||
| const source = responses(name); | ||
| expect(source).toContain("const adapterOwnsDispatch = transportState.activeAdapter.fetchResponse !== undefined;"); | ||
| expect(source).toContain("!adapterOwnsDispatch && transientRetryPolicyFor(route.provider) !== null,"); | ||
| } | ||
| // runTurn has only one shape: the adapter owns the transport, so it never reports and the | ||
| // reservation is always handed down rather than confirmed here. | ||
| const runTurn = responses("run-turn-execution.ts"); | ||
| expect(runTurn).toContain("sendBudgetState.pendingHopPermit = hop.permit;"); | ||
| expect(runTurn).not.toContain("hop.permit?.use();"); | ||
| // Every adapter-owned transport now reserves against the view, which is what spends the | ||
| // handed-down permit. Passing the bare holder is the regression this pins. | ||
| for (const name of ["adapter-dispatch.ts", "adapter-continuation.ts", "run-turn-execution.ts"]) { | ||
| expect(responses(name)).not.toContain("sendBudget: adapterSendBudget"); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| describe("derived policy scopes", () => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test calls
hop.permit.release()itself, so it only proves that the budget primitive can refund a permit. If the pre-dispatchcatchinadapter-dispatch.tsoradapter-continuation.tsstops releasing its reservation—the historical defect this block claims to cover—this test remains green because neither production caller is imported or executed. Drive those recovery branches through a credential/rebuild failure, or retain a focused wiring assertion, so the actual caller contract remains covered.AGENTS.md reference: AGENTS.md:L376-L379
Useful? React with 👍 / 👎.