Skip to content

test(x402-buyer): make ConfirmSpendFailure test work under uid 0#373

Merged
bussyjd merged 1 commit intomainfrom
claude/show-open-prs-status-Wr848
Apr 23, 2026
Merged

test(x402-buyer): make ConfirmSpendFailure test work under uid 0#373
bussyjd merged 1 commit intomainfrom
claude/show-open-prs-status-Wr848

Conversation

@bussyjd
Copy link
Copy Markdown
Collaborator

@bussyjd bussyjd commented Apr 23, 2026

Summary

Fix TestProxy_ConfirmSpendFailure_IncrementsMetric so it actually exercises the confirm-spend failure path when tests run as uid 0 (CI containers, dev sandboxes).

Root cause

The test forced StateStore.writeLocked to fail by creating its state directory with mode 0o500. That works for non-root uids but is silently bypassed under CAP_DAC_OVERRIDE when tests run as root — the write goes through, ConfirmSpend returns nil, the OnConfirmSpendFailure callback never fires, the metric family is never registered, and the test fails with missing metric family at proxy_test.go:1897.

Reproducible on every commit on main in a root-uid container, e.g.:

--- FAIL: TestProxy_ConfirmSpendFailure_IncrementsMetric (0.00s)
    proxy_test.go:1897: missing metric family
FAIL    github.com/ObolNetwork/obol-stack/internal/x402/buyer

Fix

After LoadStateStore succeeds, pre-create the target state path as a directory. The final os.Rename(tmpfile, statePath) in writeLocked then returns EEXIST/EISDIR, which root cannot bypass — it's a filesystem semantic, not a DAC check. Permission-independent failure injection without touching production code.

Test plan

  • go test -run TestProxy_ConfirmSpendFailure_IncrementsMetric -v ./internal/x402/buyer/ — PASS (log shows confirm spend: rename state: … file exists, confirming the intended path fires)
  • go test ./internal/x402/buyer/ — PASS (full package)
  • go vet ./internal/x402/buyer/ — clean
  • go build ./... — clean

Generated by Claude Code

The test forced StateStore.writeLocked to fail by creating its state
directory with mode 0o500. That works for non-root uids but is silently
bypassed when tests run as uid 0 (CI containers, dev sandboxes), because
CAP_DAC_OVERRIDE lets root write through read-only directory perms. The
spend-confirm failure path never fired, the metric family was never
registered, and the test failed with "missing metric family".

Switch to a permission-independent failure injection: after LoadStateStore
succeeds, pre-create the target state path as a directory. The final
os.Rename(tmpfile, statePath) in writeLocked then returns EEXIST/EISDIR,
which root cannot bypass (it's a filesystem semantic, not a DAC check).
@bussyjd bussyjd merged commit 6a2a542 into main Apr 23, 2026
5 checks passed
@OisinKyne OisinKyne deleted the claude/show-open-prs-status-Wr848 branch April 23, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants