From 3de345fe6f3b923f4dbb454b0cd12b7a84dddb2a Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Tue, 6 Oct 2026 10:56:50 +0200 Subject: [PATCH] Read the export test's heap only after pools drop their caches (closes #511) `TestArchiveExport_Streams` read the heap after one garbage collection, but the libraries the export calls (`regexp` under GORM's table names, `encoding/json`, GORM's row scanning) keep spare buffers in a `sync.Pool`, which keeps them through one collection. Each reading therefore counted however many happened to be cached, which varied by about as much as the test's limit and failed `go test` on `next`. The test now collects twice before each reading, so a reading is the memory the export holds. The limit, the row counts and the claim are unchanged, and an export that does not stream still fails it. Unverified: the branch's CI run waits for the runner outage to clear. Model: opus-5-5 --- internal/delivery/target_database_export_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/delivery/target_database_export_test.go b/internal/delivery/target_database_export_test.go index 6515b7d..fc6dd61 100644 --- a/internal/delivery/target_database_export_test.go +++ b/internal/delivery/target_database_export_test.go @@ -460,8 +460,13 @@ func TestArchiveExport_OneFileOpenAtATime(t *testing.T) { } // heapPeak is an io.Writer that discards what it is given and records -// the largest heap it saw at a write. It collects garbage before each -// reading, so the heap it reads is what is still held. +// the largest heap it saw at a write. It collects garbage twice before +// each reading, so the heap it reads is what is still held. Once is not +// enough: the libraries the export calls (regexp, under GORM's table +// names, and encoding/json among them) cache buffers in a sync.Pool, +// which keeps them through one collection, so after one the reading +// counts however many happen to be cached. That varies from run to run +// by about as much as the limit in TestArchiveExport_Streams. type heapPeak struct { max uint64 } @@ -469,6 +474,7 @@ type heapPeak struct { func (p *heapPeak) Write(b []byte) (int, error) { var m runtime.MemStats + runtime.GC() runtime.GC() runtime.ReadMemStats(&m) p.max = max(p.max, m.HeapAlloc) @@ -498,6 +504,8 @@ func exportHeapGrowth(t *testing.T, rows, bodySize int) uint64 { export := listExport(t, path) + // Twice, for the reason heapPeak gives. + runtime.GC() runtime.GC() var start runtime.MemStats