Files
tensor/io/zz_guard_test.go
T
petrbalvin af4ee19703
Release / gates (push) Successful in 4m38s
Test / test (push) Successful in 5m16s
Release / release (push) Successful in 35s
feat: initial release
Assisted-by: GLM 5.3 Flash
2026-09-03 10:00:00 +02:00

62 lines
2.0 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package io
import (
"flag"
"fmt"
"os"
"runtime"
"testing"
"time"
)
// TestMain installs a heap watchdog for the whole package run. The io
// tests are hostile-input tests by design: they feed crafted headers to
// the readers and check that nothing panics and nothing grows without
// bound. A regression therefore cannot fail politely, it allocates: a
// hard-link cycle and a deep group chain both took the host down once.
// The watchdog turns any such runaway into an immediate panic that
// unwinds the offending code path, so the worst case is a failed test
// rather than an OOM kill of the editor that started it.
func TestMain(m *testing.M) {
// The aggregate read budget bounds what one input may allocate
// legally; the watchdog sits an order above it. Fuzzing runs many
// workers holding inputs at once and the engine carries its own
// corpus and coverage bookkeeping, so the fuzz run watches a wider
// ceiling while still catching the unbounded growth the guard
// exists for: a runaway reaches any finite cap in seconds.
//
// The flags are parsed here, before the ceiling is decided: the
// test flags are only registered at TestMain and m.Run parses them
// later, so an earlier read of test.fuzz sees its empty default and
// the fuzz ceiling never fires.
flag.Parse()
const plainCap = 3 << 30
ceiling := int64(plainCap)
if f := flag.Lookup("test.fuzz"); f != nil && f.Value.String() != "" {
ceiling = 32 << 30
}
stop := make(chan struct{})
go func() {
ticker := time.NewTicker(20 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-stop:
return
case <-ticker.C:
var m runtime.MemStats
runtime.ReadMemStats(&m)
if int64(m.HeapAlloc) > ceiling {
panic(fmt.Sprintf("io test binary heap above %d GiB: a reader is allocating without bound", ceiling>>30))
}
}
}
}()
code := m.Run()
close(stop)
os.Exit(code)
}