mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-19 10:52:04 +00:00
7d2106bfb5
* fix(test): reclaim fixture scratch dirs stranded in /tmp The shared predastore fixture and the integration suite's JetStream store both outlive any individual test, so neither can use t.TempDir() - the first test to finish would delete files the daemon still has open. Both used os.MkdirTemp with nothing removing the directory afterwards, so every run stranded one, and a run killed by a timeout panic or the OOM killer stranded it regardless. /tmp is a tmpfs on the dev boxes, so the leak is charged to RAM and swap, and swapped tmpfs pages have no backing store to be dropped to. Add a shared sweep that reclaims a directory only when it matches both the prefix and an age no live run can reach. The NATS store also has a clean shutdown point, so TestMain now removes it outright and the sweep is left to cover the killed-run case. The predastore daemon runs until the process exits and has no such point, so the sweep is its only mechanism. * chore: repin viperblock to the dev tip carrying the scratch-dir fix Test-only upstream change, so the build output is unchanged - this keeps go.mod aligned with the submodule pointer rather than delivering a fix.
53 lines
1.9 KiB
Go
53 lines
1.9 KiB
Go
//go:build integration
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
// TestMain amortises the embedded NATS+JetStream server across every test in
|
|
// this package instead of each StartGateway call booting (and tearing down)
|
|
// its own, for two reasons:
|
|
//
|
|
// 1. spinifex/gateway/ec2/instance's ClientTokenStore is a process-wide
|
|
// sync.Once singleton bound to whichever *nats.Conn first initialises it.
|
|
// In production a gateway holds one long-lived connection for its whole
|
|
// life, so the singleton is correct there. But this test binary runs
|
|
// every test in one process, so a per-test embedded server closes that
|
|
// first connection the moment its owning test ends — every later
|
|
// RunInstances-calling test then inherits a KV handle bound to a dead
|
|
// connection. Keeping one server, and never closing an individual
|
|
// test's connection early, keeps whichever connection wins the
|
|
// singleton alive for the life of the whole binary.
|
|
// 2. It cuts per-test startup cost: standing up an embedded JetStream
|
|
// server is the dominant fixed cost of StartGateway.
|
|
//
|
|
// Per-test state isolation is preserved despite the shared server — see the
|
|
// accountAuthenticator doc comment in shared_nats.go for how.
|
|
func TestMain(m *testing.M) {
|
|
h, err := startSharedNATS()
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, "tests/integration: failed to start shared NATS server:", err)
|
|
os.Exit(1)
|
|
}
|
|
sharedNATSHarness = h
|
|
|
|
code := m.Run()
|
|
|
|
// Connections are closed here, together, rather than per-test: closing
|
|
// one early can kill the connection the clienttoken singleton latched
|
|
// onto (see above), so every connection's lifetime is pinned to the
|
|
// whole binary rather than to any single test.
|
|
h.closeAll()
|
|
h.srv.Shutdown()
|
|
h.srv.WaitForShutdown()
|
|
|
|
// Only reached on a clean exit; a killed run leaves the store for the
|
|
// sweep in startSharedNATS to reclaim.
|
|
h.removeStore()
|
|
os.Exit(code)
|
|
}
|