banger/internal/smoketest/smoke_test.go
2026-05-01 19:34:44 -03:00

72 lines
2.8 KiB
Go

//go:build smoke
package smoketest
import "testing"
// TestSmoke is the single top-level test that pins run-order across
// scenario classes:
//
// - "pool" runs pure scenarios concurrently (each calls t.Parallel)
// alongside the repodir chain, which runs its own subtests
// sequentially. The pool subtest only returns once every t.Parallel
// child has finished.
// - "global" runs after pool, serially, in registry order. These
// scenarios assert host-wide state (iptables, vm row counts,
// ssh-config under a fake HOME, the update / rollback flow, daemon
// stop) and would race with the parallel pool.
//
// `go test -parallel N` controls fan-out within the pool. `-run
// TestSmoke/pool/bare_run` runs a single scenario without changing
// the install preamble path.
func TestSmoke(t *testing.T) {
t.Run("pool", func(t *testing.T) {
// Pure scenarios — t.Parallel inside each, fan out under -parallel.
t.Run("bare_run", testBareRun)
t.Run("exit_code", testExitCode)
t.Run("concurrent_run", testConcurrentRun)
t.Run("detach_run", testDetachRun)
t.Run("bootstrap_precondition", testBootstrapPrecondition)
t.Run("vm_lifecycle", testVMLifecycle)
t.Run("vm_set", testVMSet)
t.Run("vm_restart", testVMRestart)
t.Run("vm_kill", testVMKill)
t.Run("vm_ports", testVMPorts)
t.Run("ssh_config", testSSHConfig)
// Repodir chain — single virtual job in the pool. Subtests run
// sequentially because they share the throwaway git repo at
// repoDir and mutate it; t.Parallel() is intentionally absent.
// The chain itself competes with the pure scenarios for a
// parallel slot at this outer level.
t.Run("repodir_chain", func(t *testing.T) {
t.Parallel()
t.Run("workspace_run", testWorkspaceRun)
t.Run("workspace_dryrun", testWorkspaceDryrun)
t.Run("include_untracked", testIncludeUntracked)
t.Run("workspace_export", testWorkspaceExport)
t.Run("workspace_full_copy", testWorkspaceFullCopy)
t.Run("workspace_basecommit", testWorkspaceBasecommit)
t.Run("workspace_restart", testWorkspaceRestart)
t.Run("vm_exec", testVMExec)
})
})
// Global scenarios — serial, after the pool drains. Order matters:
// daemon_admin tears the installed services down and must be LAST.
// The order otherwise mirrors scripts/smoke.sh's SMOKE_SCENARIOS
// registry so the run shape is comparable.
t.Run("global", func(t *testing.T) {
t.Run("vm_prune", testVMPrune)
t.Run("nat", testNAT)
t.Run("invalid_spec", testInvalidSpec)
t.Run("invalid_name", testInvalidName)
t.Run("update_check", testUpdateCheck)
t.Run("update_to_unknown", testUpdateToUnknown)
t.Run("update_no_root", testUpdateNoRoot)
t.Run("update_dry_run", testUpdateDryRun)
t.Run("update_keeps_vm_alive", testUpdateKeepsVMAlive)
t.Run("update_rollback_keeps_vm_alive", testUpdateRollbackKeepsVMAlive)
t.Run("daemon_admin", testDaemonAdmin)
})
}