test: Advance an injected clock instead of sleeping past the TTL #16

Merged
linus merged 1 commit from ash/expiry-clock-9 into develop 2026-10-24 15:01:45 +00:00
Collaborator

Closes #9.

TestCreateReadThenExpireScratch created a scratch with a 120ms TTL and read it right away. A slow -race runner could cross the TTL before the read and get 410 instead of 200 (run 2154).

The server now checks expiry against an optional clock (Server.now, nil means time.Now). The expiry tests use a one-hour TTL and push a test clock two hours forward instead of sleeping. The read half has hours of headroom, the expiry half is still asserted, and the sleeps are gone. The two sibling tests with the same short-TTL pattern (TestUploadedScratchViewAndRawBeforeAndAfterExpiry, TestParallelClientsExpiredScratchReadsReturnGone) get the same change.

Proof on the jumpbox (go1.27.2):

  • go test -race -run 'TestCreateReadThenExpireScratch|TestUploadedScratchViewAndRawBeforeAndAfterExpiry|TestParallelClientsExpiredScratchReadsReturnGone' -count=50 ./internal/http/ passes.
  • go vet ./... and gofmt -l are clean.
  • go test -race -count=3 ./... passes apart from TestScratchPageServerMetaInjection and TestFaviconServed, which need the built UI (no Node on the jumpbox, so I used a placeholder web/static). They fail the same way on develop with that placeholder. CI builds the real UI.

Revert is git revert.

Closes #9. `TestCreateReadThenExpireScratch` created a scratch with a 120ms TTL and read it right away. A slow `-race` runner could cross the TTL before the read and get 410 instead of 200 (run 2154). The server now checks expiry against an optional clock (`Server.now`, nil means `time.Now`). The expiry tests use a one-hour TTL and push a test clock two hours forward instead of sleeping. The read half has hours of headroom, the expiry half is still asserted, and the sleeps are gone. The two sibling tests with the same short-TTL pattern (`TestUploadedScratchViewAndRawBeforeAndAfterExpiry`, `TestParallelClientsExpiredScratchReadsReturnGone`) get the same change. Proof on the jumpbox (go1.27.2): - `go test -race -run 'TestCreateReadThenExpireScratch|TestUploadedScratchViewAndRawBeforeAndAfterExpiry|TestParallelClientsExpiredScratchReadsReturnGone' -count=50 ./internal/http/` passes. - `go vet ./...` and `gofmt -l` are clean. - `go test -race -count=3 ./...` passes apart from `TestScratchPageServerMetaInjection` and `TestFaviconServed`, which need the built UI (no Node on the jumpbox, so I used a placeholder `web/static`). They fail the same way on develop with that placeholder. CI builds the real UI. Revert is `git revert`.
test: Advance an injected clock instead of sleeping past the TTL (closes #9)
All checks were successful
Format / gofmt (push) Successful in 21s
CI / Build (push) Successful in 32s
CI / Go Tests (push) Successful in 32s
CI / Go Tests (pull_request) Successful in 33s
CI / Build (pull_request) Successful in 25s
Format / gofmt (pull_request) Successful in 19s
5ffa72f151
TestCreateReadThenExpireScratch used a 120ms TTL and read the scratch
right after creating it. A slow -race runner could cross the TTL
before the read and get 410 instead of 200.

The server now checks expiry against an optional clock. The expiry
tests use a one-hour TTL and push a test clock two hours forward
instead of sleeping, so the read half has plenty of headroom and the
expiry half is still asserted, with no sleeps. The same change goes
into the two sibling tests that used the same short-TTL pattern.
ash requested review from eva 2026-10-24 14:56:20 +00:00
eva approved these changes 2026-10-24 14:58:17 +00:00
eva left a comment

GO on 5ffa72f.

This fixes the flake the right way. Expiry now reads an injectable clock (nil falls back to time.Now, so production behavior is unchanged), and the three short-TTL tests use a one-hour TTL plus a pushed-forward test clock instead of sleeping. The read-before-expiry half gets hours of headroom and the expiry half is still asserted. The atomic offset keeps the parallel test race-safe. Build, gofmt and Go Tests are green on this head, and the head sits on the current develop tip.

No security surface here, so Linus can merge.

GO on 5ffa72f. This fixes the flake the right way. Expiry now reads an injectable clock (nil falls back to time.Now, so production behavior is unchanged), and the three short-TTL tests use a one-hour TTL plus a pushed-forward test clock instead of sleeping. The read-before-expiry half gets hours of headroom and the expiry half is still asserted. The atomic offset keeps the parallel test race-safe. Build, gofmt and Go Tests are green on this head, and the head sits on the current develop tip. No security surface here, so Linus can merge.
linus merged commit 1c69312890 into develop 2026-10-24 15:01:45 +00:00
linus deleted branch ash/expiry-clock-9 2026-10-24 15:01:45 +00:00
Sign in to join this conversation.
No reviewers
eva
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
s1d3sw1ped/scratchbox!16
No description provided.