mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
a7a62addeb
The fixture wrote a config the strict decoder rejects and built its cluster through clusterrun, so it now renders a v1 TOML, loads it through LoadConfig and serves under Run. Loading the real file means the fixture trips over the same validation an install does. Its data directory holds node-<id> directly, and it drains on cancellation rather than being abandoned at exit. The runtime tests drove buildRuntime, serve and the old on-disk layout, all of which predastore owns now, so they go. What replaces them covers what spinifex still decides: the flag merge and its precedence, a host id or gate node the config does not have, and the pid file behind Stop and Status. Two fixes to earlier commits in this series: the host id conversion moves behind its own guard, and the node status probes use WaitGroup.Go.
87 lines
3.1 KiB
Go
87 lines
3.1 KiB
Go
//go:build integration
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
testpredastore "github.com/mulgadc/spinifex/tests/fixtures/predastore"
|
|
)
|
|
|
|
// 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) {
|
|
policy, err := loadConformancePolicy()
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, "tests/integration: load AWS conformance policy:", err)
|
|
os.Exit(1)
|
|
}
|
|
mode, err := conformanceModeFromEnvironment()
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, "tests/integration:", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
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()
|
|
|
|
// The predastore fixture outlives any single test on purpose, so this is
|
|
// the only point at which its cluster goroutines can be drained.
|
|
testpredastore.Stop()
|
|
|
|
report := suiteConformance.report(policy, mode)
|
|
fmt.Fprintln(os.Stderr, report)
|
|
if blocking := suiteConformance.blocking(policy, mode); blocking != 0 {
|
|
fmt.Fprintf(os.Stderr, "tests/integration: %d blocking AWS model conformance violation(s)\n", blocking)
|
|
code = 1
|
|
}
|
|
if reportPath := os.Getenv("AWS_MODEL_CONFORMANCE_REPORT"); reportPath != "" {
|
|
if err := os.MkdirAll(filepath.Dir(reportPath), 0o755); err != nil {
|
|
fmt.Fprintln(os.Stderr, "tests/integration: create conformance report directory:", err)
|
|
code = 1
|
|
} else if err := os.WriteFile(reportPath, []byte(report+"\n"), 0o644); err != nil {
|
|
fmt.Fprintln(os.Stderr, "tests/integration: write conformance report:", err)
|
|
code = 1
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
}
|