feat: initial release
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// 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)
|
||||
}
|
||||
Reference in New Issue
Block a user