package swoosh import ( "testing" "time" ) type staticGuardProvider struct { outcomes map[string]GuardOutcome } func newStaticGuardProvider() *staticGuardProvider { return &staticGuardProvider{outcomes: make(map[string]GuardOutcome)} } func (g *staticGuardProvider) setOutcome(name string, outcome GuardOutcome) { g.outcomes[name] = outcome } func (g *staticGuardProvider) Evaluate(t TransitionProposal, s OrchestratorState) (GuardOutcome, error) { if outcome, ok := g.outcomes[t.TransitionName]; ok { return outcome, nil } return GuardOutcome{ LicenseOK: true, BackbeatOK: true, QuorumOK: true, PolicyOK: true, MCPHealthy: true, }, nil } func newTestExecutor(t *testing.T, guard GuardProvider, wal WALStore, snap SnapshotStore) *Executor { t.Helper() initial := Snapshot{} exec := NewExecutor(wal, snap, guard, initial) return exec } func waitResult(t *testing.T, ch <-chan ApplyResult) ApplyResult { t.Helper() select { case res := <-ch: return res case <-time.After(2 * time.Second): t.Fatalf("timed out waiting for apply result") return ApplyResult{} } } func TestDeterministicReplay(t *testing.T) { walStore := &InMemoryWAL{} snapStore := &InMemorySnapshotStore{} guard := newStaticGuardProvider() guard.setOutcome("TRANSITION_QUARANTINE_ENTER", GuardOutcome{PolicyOK: false}) exec := newTestExecutor(t, guard, walStore, snapStore) transitions := []TransitionProposal{ {TransitionName: "LICENSE_GRANTED", HLC: "1"}, {TransitionName: "INGESTION_SOURCES_RESOLVED", HLC: "2"}, {TransitionName: "INGESTION_BYTES_OK", HLC: "3"}, {TransitionName: "INGESTION_SCHEMA_OK", HLC: "4"}, {TransitionName: "INGESTION_CORPUS_BUILT", HLC: "5"}, {TransitionName: "COUNCIL_PROFILES_LOADED", HLC: "6"}, {TransitionName: "COUNCIL_QUORUM_CERT", HLC: "7"}, {TransitionName: "COUNCIL_MCP_GREEN", HLC: "8"}, {TransitionName: "ENV_CAPACITY_OK", HLC: "9"}, {TransitionName: "ENV_INSTALLED", HLC: "10"}, {TransitionName: "ENV_HEALTH_GREEN", HLC: "11"}, {TransitionName: "EXEC_PLAN_LOCKED", HLC: "12", WindowID: "window-1"}, {TransitionName: "EXEC_BEAT_REVIEW_GATE", HLC: "13", WindowID: "window-1"}, {TransitionName: "EXEC_APPROVALS_THRESHOLD", HLC: "14", WindowID: "window-1"}, {TransitionName: "EXEC_NEXT_WINDOW", HLC: "15", WindowID: "window-2"}, } var finalState OrchestratorState for _, proposal := range transitions { ch, err := exec.SubmitTransition(proposal) if err != nil { t.Fatalf("submit transition %s: %v", proposal.TransitionName, err) } res := waitResult(t, ch) if !res.Success || res.Error != nil { t.Fatalf("transition %s failed: success=%t error=%v", proposal.TransitionName, res.Success, res.Error) } finalState = res.NewState } finalHash := finalState.StateHash if finalHash == "" { t.Fatal("final state hash empty") } snapshot := Snapshot{ State: finalState, LastAppliedHLC: finalState.HLCLast, LastAppliedIndex: walStore.LastIndex(), } if err := snapStore.Save(snapshot); err != nil { t.Fatalf("save snapshot: %v", err) } replayState, err := Replay(walStore, snapshot) if err != nil { t.Fatalf("replay failed: %v", err) } if replayState.StateHash != finalHash { t.Fatalf("state hash mismatch after replay: got %s want %s", replayState.StateHash, finalHash) } } func TestQuarantineEnforced(t *testing.T) { walStore := &InMemoryWAL{} snapStore := &InMemorySnapshotStore{} guard := newStaticGuardProvider() guard.setOutcome("TRANSITION_QUARANTINE_ENTER", GuardOutcome{PolicyOK: false}) exec := newTestExecutor(t, guard, walStore, snapStore) enterProposal := TransitionProposal{TransitionName: "TRANSITION_QUARANTINE_ENTER", HLC: "1"} ch, err := exec.SubmitTransition(enterProposal) if err != nil { t.Fatalf("submit quarantine enter: %v", err) } res := waitResult(t, ch) if !res.Success || res.Error != nil { t.Fatalf("quarantine enter failed: %v", res.Error) } quarantinedState := res.NewState if !quarantinedState.Policy.Quarantined { t.Fatal("state not quarantined after enter transition") } hashBefore := quarantinedState.StateHash illegalProposal := TransitionProposal{TransitionName: "EXEC_BEAT_REVIEW_GATE", HLC: "2", WindowID: "window-1"} ch, err = exec.SubmitTransition(illegalProposal) if err != nil { t.Fatalf("submit illegal transition: %v", err) } res = waitResult(t, ch) if res.Success || res.Error == nil { t.Fatalf("expected failure for illegal transition in quarantine, got success=%t error=%v", res.Success, res.Error) } stateAfter := exec.GetStateSnapshot() if stateAfter.StateHash != hashBefore { t.Fatalf("state hash changed after illegal transition: got %s want %s", stateAfter.StateHash, hashBefore) } }