Files
spinifex/tests/e2e/multinode/main_test.go
T
2026-06-12 12:38:31 +10:00

97 lines
2.6 KiB
Go

//go:build e2e
// Package multinode is the Go port of run-multinode-e2e.sh — the real
// 3-node E2E suite that drives the full EC2/VPC/NAT lifecycle against a
// pre-bootstrapped Spinifex cluster. Each phase from the bash driver runs
// as a top-level Test* in this package; ordering is not implied — every
// phase self-bootstraps its prerequisites via harness.Discover* /
// harness.Ensure* and the package-local need* helpers.
package multinode
import (
"os"
"sync"
"testing"
"github.com/mulgadc/spinifex/tests/e2e/harness"
)
// Package-scoped singleton fixture, built lazily by requireMultiNodeFixture.
// A run with SPINIFEX_E2E unset stays cheap (no AWS dial, no temp dir).
var (
pkgFixOnce sync.Once
pkgFix *Fixture
pkgFixErr error
)
// TestMain owns process-level lifecycle for the singleton fixture.
func TestMain(m *testing.M) {
code := m.Run()
if pkgFix != nil {
if pkgFix.Harness != nil {
pkgFix.Harness.Close()
}
if pkgFix.TmpDir != "" {
_ = os.RemoveAll(pkgFix.TmpDir)
}
}
os.Exit(code)
}
// requireMultiNodeFixture returns the package-scoped Fixture singleton, building
// it on first call. Skips if SPINIFEX_E2E is unset or mode is not multinode.
func requireMultiNodeFixture(t *testing.T) *Fixture {
t.Helper()
pkgFixOnce.Do(func() {
if os.Getenv("SPINIFEX_E2E") == "" {
return
}
env := harness.LoadEnv(t)
if env.Mode != harness.ModeMultinode {
return
}
cluster, cerr := harness.ClusterFromEnv()
if cerr != nil {
pkgFixErr = cerr
return
}
awsCli := harness.NewAWSClient(t, env)
h, herr := harness.NewProcessFixture(awsCli)
if herr != nil {
pkgFixErr = herr
return
}
tmpDir, terr := os.MkdirTemp("", "multinode-pkgfix-*")
if terr != nil {
pkgFixErr = terr
return
}
pkgFix = &Fixture{
Env: env,
AWS: awsCli,
Harness: h,
Cluster: cluster,
Artifacts: harness.ArtifactDir(t, env),
TmpDir: tmpDir,
}
})
if pkgFixErr != nil {
t.Fatalf("multinode singleton fixture init failed: %v", pkgFixErr)
}
if pkgFix == nil {
t.Skip("multinode singleton fixture unavailable (SPINIFEX_E2E unset or mode != multinode)")
}
return pkgFix
}
// Fixture carries the per-process state shared across every Test* in this package.
// Per-phase resource IDs are memoized on Harness via need* / harness.Ensure* helpers.
type Fixture struct {
Env *harness.Env
AWS *harness.AWSClient
Harness *harness.Fixture // memoized Ensure* fixture; spans the whole process.
Cluster *harness.Cluster // 3-node WAN-IP cluster from SPINIFEX_NODES.
Artifacts string
TmpDir string // package-scoped scratch dir; survives every Test* in the package.
}