From 3a0495a787ae18a9f4cbef3e12432a2a6b584ab5 Mon Sep 17 00:00:00 2001 From: clawbot <35+clawbot@noreply.example.org> Date: Tue, 6 Oct 2026 07:26:55 +0000 Subject: [PATCH] Read the export test's heap only after pools drop their caches (closes #511) TestArchiveExport_Streams read the heap after one collection. GORM's table naming (through regexp) and encoding/json cache buffers in a sync.Pool, which keeps them through one collection, so each reading counted however many happened to be cached, and that swung between runs by about the test's whole limit. It now collects twice before each reading, the starting one included, so a reading is what the export holds. No other test runs during the measurement: Go holds the parallel tests until the sequential ones have finished. 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