Files
rvbox/test/harness/harness_test.go
T

352 lines
11 KiB
Go

package main
import (
"bytes"
"context"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestSampleRunLifecycle_HP_CFG_01(t *testing.T) {
t.Parallel()
root := t.TempDir()
var output bytes.Buffer
h := &harness{root: root, now: func() time.Time { return time.Unix(1_700_000_000, 0).UTC() }, out: &output}
current, err := h.create("sample-run", "integration", "sample")
if err != nil {
t.Fatalf("create: %v", err)
}
if current.Phase != "created" || current.ComposeProject != "rvbox-test-sample-run" {
t.Fatalf("manifest = %+v", current)
}
if err := h.transition(current, "interrupted", "interrupt", "test"); err != nil {
t.Fatal(err)
}
loaded, err := h.load("sample-run")
if err != nil || loaded.Phase != "interrupted" {
t.Fatalf("load = (%+v, %v)", loaded, err)
}
if err := h.collect(loaded); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(filepath.Join(root, "sample-run", "artifacts", "report.json")); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(filepath.Join(root, "sample-run", "artifacts", "junit.xml")); err != nil {
t.Fatal(err)
}
if err := h.transition(loaded, "reset", "reset", "test"); err != nil {
t.Fatal(err)
}
if err := h.purge(loaded); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(filepath.Join(root, "sample-run")); !os.IsNotExist(err) {
t.Fatalf("purged run still exists: %v", err)
}
}
func TestRunIsolationAndManifestIdentity_HP_CFG_01(t *testing.T) {
t.Parallel()
h := &harness{root: t.TempDir(), now: time.Now, out: &bytes.Buffer{}}
first, err := h.create("first-run", "integration", "sample")
if err != nil {
t.Fatal(err)
}
second, err := h.create("second-run", "integration", "sample")
if err != nil {
t.Fatal(err)
}
if err := h.transition(first, "reset", "reset", "test"); err != nil {
t.Fatal(err)
}
if err := h.purge(first); err != nil {
t.Fatal(err)
}
if _, err := h.load(second.RunID); err != nil {
t.Fatalf("unrelated run was affected: %v", err)
}
manifestPath := h.manifestPath(second.RunID)
data, err := os.ReadFile(manifestPath)
if err != nil {
t.Fatal(err)
}
data = bytes.Replace(data, []byte(`repository_id = 'rvbox'`), []byte(`repository_id = 'other'`), 1)
data = bytes.Replace(data, []byte(`repository_id = "rvbox"`), []byte(`repository_id = "other"`), 1)
if err := os.WriteFile(manifestPath, data, 0o600); err != nil {
t.Fatal(err)
}
if _, err := h.load(second.RunID); err == nil {
t.Fatal("foreign manifest accepted")
}
}
func TestPurgeRequiresExplicitExecution_HP_CFG_01(t *testing.T) {
t.Parallel()
var output bytes.Buffer
h := &harness{root: t.TempDir(), now: time.Now, out: &output}
current, err := h.create("safe-purge", "integration", "sample")
if err != nil {
t.Fatal(err)
}
if err := h.transition(current, "reset", "reset", "test"); err != nil {
t.Fatal(err)
}
if err := h.environmentCommand("purge", []string{"--run-id", current.RunID}); err != nil {
t.Fatalf("purge dry run: %v", err)
}
if _, err := h.load(current.RunID); err != nil {
t.Fatalf("dry-run purge removed run: %v", err)
}
if err := h.environmentCommand("purge", []string{"--run-id", current.RunID, "--execute"}); err == nil {
t.Fatal("unconfirmed purge execution succeeded")
}
if err := h.environmentCommand("purge", []string{"--run-id", current.RunID, "--execute", "--yes"}); err != nil {
t.Fatalf("confirmed purge: %v", err)
}
if _, err := os.Stat(h.runDir(current.RunID)); !os.IsNotExist(err) {
t.Fatalf("confirmed purge retained run: %v", err)
}
}
func TestGCOnlyRemovesEligibleOldRuns_HP_CFG_01(t *testing.T) {
t.Parallel()
now := time.Date(2026, time.September, 11, 6, 0, 0, 0, time.UTC)
h := &harness{root: t.TempDir(), now: func() time.Time { return now }, out: &bytes.Buffer{}}
old, err := h.create("old-reset", "integration", "sample")
if err != nil {
t.Fatal(err)
}
if err := h.transition(old, "reset", "reset", "test"); err != nil {
t.Fatal(err)
}
now = now.Add(2 * time.Hour)
active, err := h.create("active-run", "integration", "sample")
if err != nil {
t.Fatal(err)
}
if err := h.gc([]string{"--older-than", "1h", "--execute", "--yes"}); err != nil {
t.Fatalf("gc: %v", err)
}
if _, err := os.Stat(h.runDir(old.RunID)); !os.IsNotExist(err) {
t.Fatalf("gc retained old reset run: %v", err)
}
if _, err := h.load(active.RunID); err != nil {
t.Fatalf("gc affected active run: %v", err)
}
}
func TestRunIDTraversalAndSymlinkPurgeRejected_HP_CFG_01(t *testing.T) {
t.Parallel()
for _, value := range []string{"", "../escape", "/absolute", "UPPER", strings.Repeat("a", 65)} {
if err := validateRunID(value); err == nil {
t.Errorf("validateRunID(%q) succeeded", value)
}
}
root := t.TempDir()
h := &harness{root: root, now: time.Now, out: &bytes.Buffer{}}
target := t.TempDir()
if err := os.Symlink(target, filepath.Join(root, "linked-run")); err != nil {
t.Fatal(err)
}
if err := h.purge(&manifest{RunID: "linked-run"}); err == nil {
t.Fatal("symlink purge succeeded")
}
}
func TestIntegrationResumeValidation_HP_CFG_01(t *testing.T) {
t.Parallel()
h := &harness{root: t.TempDir(), now: time.Now, out: &bytes.Buffer{}}
if err := h.integration(context.Background(), []string{"--resume", "--suite", "sample"}); err == nil {
t.Fatal("resume without run ID succeeded")
}
if err := h.integration(context.Background(), []string{"--suite", "unknown"}); err == nil {
t.Fatal("unknown suite succeeded")
}
}
func TestE2EScenarioValidationAndRunIdentity_HP_E2E_01(t *testing.T) {
t.Parallel()
h := &harness{root: t.TempDir(), now: time.Now, out: &bytes.Buffer{}}
if err := h.e2e(context.Background(), []string{"--scenario", "unknown"}); err == nil {
t.Fatal("unknown e2e scenario accepted")
}
if err := h.e2e(context.Background(), []string{"--resume", "--scenario", "smoke"}); err == nil {
t.Fatal("e2e resume without run ID accepted")
}
}
func TestStableSuiteAndScenarioListing_HP_CFG_01(t *testing.T) {
t.Parallel()
var output bytes.Buffer
h := &harness{root: t.TempDir(), now: time.Now, out: &output}
if err := h.integration(context.Background(), []string{"--list"}); err != nil {
t.Fatalf("list integration suites: %v", err)
}
if got, want := output.String(), "integration suites:\nsample\nstore\nserver-session\ncontrol\nclient-agent\nall\n"; got != want {
t.Fatalf("integration list = %q, want %q", got, want)
}
output.Reset()
if err := h.e2e(context.Background(), []string{"--list"}); err != nil {
t.Fatalf("list e2e scenarios: %v", err)
}
if got, want := output.String(), "e2e scenarios:\nsmoke\ninteractive\nidempotency\nreconnect\nretention\nexpiry-and-incidents\nscript\nrecovery\nall\n"; got != want {
t.Fatalf("e2e list = %q, want %q", got, want)
}
if err := h.integration(context.Background(), []string{"--suite", "store", "--case", "["}); err == nil {
t.Fatal("invalid --case regexp succeeded")
}
if err := h.e2e(context.Background(), []string{"--scenario", "all", "--case", "Test"}); err == nil {
t.Fatal("--case with all scenarios succeeded")
}
}
func TestHarnessDefaultsAndResumeIdentity_HP_CFG_01(t *testing.T) {
t.Parallel()
defaults, err := loadHarnessDefaults("defaults.toml")
if err != nil {
t.Fatalf("load defaults: %v", err)
}
if defaults.Limits.MaxConcurrentRuns != 1 || defaults.Limits.FreeSpaceFloorBytes == 0 {
t.Fatalf("defaults = %#v", defaults)
}
h := &harness{root: t.TempDir(), now: time.Now, out: &bytes.Buffer{}}
current, err := h.create("resume-identity", "integration", "sample")
if err != nil {
t.Fatal(err)
}
current.GitCommit = "different-commit"
if err := h.verifyResume(current); err == nil || !strings.Contains(err.Error(), "commit") {
t.Fatalf("verifyResume mismatched commit = %v", err)
}
}
func TestBoundedSuiteLogAndFailedRunRecovery_BH_STORE_03(t *testing.T) {
t.Parallel()
capture := &limitedCapture{limit: 4}
if written, err := capture.Write([]byte("123456")); err != nil || written != 6 {
t.Fatalf("Write = (%d, %v)", written, err)
}
if got := string(capture.Bytes()); !strings.HasPrefix(got, "1234\n") || !strings.Contains(got, "truncated") {
t.Fatalf("bounded output = %q", got)
}
h := &harness{root: t.TempDir(), now: time.Now, out: &bytes.Buffer{}}
current, err := h.create("failed-store", "integration", "store")
if err != nil {
t.Fatal(err)
}
if err := h.transition(current, "failed", "store-failed", "injected"); err != nil {
t.Fatal(err)
}
if err := h.environmentCommand("recover", []string{"--run-id", current.RunID}); err != nil {
t.Fatalf("recover failed run: %v", err)
}
loaded, err := h.load(current.RunID)
if err != nil || loaded.Phase != "ready" {
t.Fatalf("recovered run = (%+v, %v)", loaded, err)
}
}
func TestResetOnlyRemovesEphemeralState_HP_CFG_02(t *testing.T) {
t.Parallel()
h := &harness{root: t.TempDir(), now: time.Now, out: &bytes.Buffer{}}
current, err := h.create("reset-scratch", "integration", "sample")
if err != nil {
t.Fatal(err)
}
for _, name := range []string{"runtime", "pki", "scratch", "artifacts"} {
path := filepath.Join(h.runDir(current.RunID), name)
if err := os.Mkdir(path, 0o700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(path, "marker"), []byte(name), 0o600); err != nil {
t.Fatal(err)
}
}
if err := h.reset(current); err != nil {
t.Fatalf("reset: %v", err)
}
for _, name := range []string{"runtime", "pki", "scratch"} {
if _, err := os.Stat(filepath.Join(h.runDir(current.RunID), name)); !os.IsNotExist(err) {
t.Fatalf("reset retained %s: %v", name, err)
}
}
if _, err := os.Stat(filepath.Join(h.runDir(current.RunID), "artifacts", "marker")); err != nil {
t.Fatalf("reset removed preserved artifacts: %v", err)
}
loaded, err := h.load(current.RunID)
if err != nil || loaded.Phase != "reset" {
t.Fatalf("reset manifest = (%+v, %v)", loaded, err)
}
active, err := h.create("running-scratch", "integration", "sample")
if err != nil {
t.Fatal(err)
}
if err := h.transition(active, "running", "start", "test"); err != nil {
t.Fatal(err)
}
if err := h.reset(active); err == nil {
t.Fatal("reset allowed an active run")
}
}
func TestReuseCreatesFreshRun_HP_CFG_03(t *testing.T) {
t.Parallel()
var output bytes.Buffer
h := &harness{root: t.TempDir(), now: time.Now, out: &output}
previous, err := h.create("prior-run", "e2e", "reconnect")
if err != nil {
t.Fatal(err)
}
previous.TestCase = "^TestReconnect$"
if err := h.writeManifest(previous); err != nil {
t.Fatal(err)
}
if err := h.transition(previous, "reset", "reset", "test"); err != nil {
t.Fatal(err)
}
if err := h.environmentCommand("reuse", []string{"--run-id", previous.RunID, "--new-run-id", "fresh-run"}); err != nil {
t.Fatalf("reuse: %v", err)
}
stillPrevious, err := h.load(previous.RunID)
if err != nil || stillPrevious.Phase != "reset" {
t.Fatalf("reuse mutated source run = (%+v, %v)", stillPrevious, err)
}
fresh, err := h.load("fresh-run")
if err != nil {
t.Fatal(err)
}
if fresh.Layer != previous.Layer || fresh.Suite != previous.Suite || fresh.TestCase != previous.TestCase || fresh.Phase != "created" {
t.Fatalf("fresh reused manifest = %+v", fresh)
}
if !strings.Contains(output.String(), "reused_from=prior-run new_run_id=fresh-run") {
t.Fatalf("reuse output = %q", output.String())
}
}
func TestCoverageInventoryReferencesExistingTests_HP_CFG_01(t *testing.T) {
t.Parallel()
if err := validateCoverageInventory(filepath.Join("..", "coverage.toml")); err != nil {
t.Fatalf("validateCoverageInventory(): %v", err)
}
}