Make the periodic reconciliation test wait for the startup pass (closes #189) #193

Merged
clawbot merged 1 commits from issue-189-startup-pass-wait into next 2026-10-04 19:59:37 +02:00
2 changed files with 31 additions and 8 deletions
+8
View File
@@ -31,6 +31,14 @@ P2: security: referer blacklist
# Completed Steps
- 2026-10-04 `TestPeriodicReconciliationAdoptsFileThatAppearsAfterStartup`
only passes through a periodic pass (closes #189): it slept for three
eviction intervals before writing its file, and a startup pass still running
then could adopt the file itself. It now holds the test database's only
connection until the startup pass waits for it after walking the empty
variant directory, writes the file and lets the connection go, as
`TestEvictionRunsOnPeriodicSchedule` does, so only a periodic reconciliation
pass can adopt the file. Test only.
- 2026-10-04 logging in, logging out, the URL generator and `/v1/e/` have
handler tests (closes #77): new tests in `internal/handlers`, with no
network, check that `GET /` without a login session shows the login form; a
+23 -8
View File
@@ -847,15 +847,28 @@ func TestPeriodicReconciliationAdoptsFileThatAppearsAfterStartup(t *testing.T) {
cache, _ := newEvictionTestCache(t, 1<<30)
const interval = 100 * time.Millisecond
// Hold the test database's only connection, so the startup pass
// waits for it after walking the still empty variant directory: the
// file written while it waits is first seen by a periodic pass.
conn, err := cache.db.Conn(t.Context())
if err != nil {
t.Fatalf("failed to take the database connection: %v", err)
}
cache.StartEviction(interval)
defer func() { _ = conn.Close() }()
cache.StartEviction(100 * time.Millisecond)
defer func() { _ = cache.StopEviction(t.Context()) }()
// Let startup reconciliation run and settle on an empty cache
// before introducing the untracked file, so the adoption we assert
// below can only be the work of a later, periodic pass.
time.Sleep(3 * interval)
deadline := time.Now().Add(5 * time.Second)
for cache.db.Stats().WaitCount == 0 {
if time.Now().After(deadline) {
t.Fatal("the startup pass never waited for the database")
}
time.Sleep(10 * time.Millisecond)
}
// Simulate a variant whose accounting insert failed after the
// process was already running and serving requests: the content
@@ -864,14 +877,16 @@ func TestPeriodicReconciliationAdoptsFileThatAppearsAfterStartup(t *testing.T) {
// insert had failed and only the file write had succeeded.
untracked := bytes.Repeat([]byte{0x41}, 900)
_, err := cache.variants.Store(
_, err = cache.variants.Store(
"aabbccdd0099", bytes.NewReader(untracked), "image/webp",
)
if err != nil {
t.Fatalf("failed to store untracked variant file: %v", err)
}
deadline := time.Now().Add(5 * time.Second)
_ = conn.Close()
deadline = time.Now().Add(5 * time.Second)
var usage int64