Read the export test's heap only after pools drop their caches (closes #511)
check / check (push) Waiting to run

`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
This commit was merged in pull request #513.
This commit is contained in:
2026-10-06 10:56:50 +02:00
parent a9d77e20d7
commit 3de345fe6f
@@ -460,8 +460,13 @@ func TestArchiveExport_OneFileOpenAtATime(t *testing.T) {
} }
// heapPeak is an io.Writer that discards what it is given and records // 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 // the largest heap it saw at a write. It collects garbage twice before
// reading, so the heap it reads is what is still held. // 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 { type heapPeak struct {
max uint64 max uint64
} }
@@ -469,6 +474,7 @@ type heapPeak struct {
func (p *heapPeak) Write(b []byte) (int, error) { func (p *heapPeak) Write(b []byte) (int, error) {
var m runtime.MemStats var m runtime.MemStats
runtime.GC()
runtime.GC() runtime.GC()
runtime.ReadMemStats(&m) runtime.ReadMemStats(&m)
p.max = max(p.max, m.HeapAlloc) p.max = max(p.max, m.HeapAlloc)
@@ -498,6 +504,8 @@ func exportHeapGrowth(t *testing.T, rows, bodySize int) uint64 {
export := listExport(t, path) export := listExport(t, path)
// Twice, for the reason heapPeak gives.
runtime.GC()
runtime.GC() runtime.GC()
var start runtime.MemStats var start runtime.MemStats