package main import ( "go/ast" "go/parser" "go/token" "testing" ) // R-356 §10 seam discipline. The restore now decides "is this app installed?" from // ListDeployedStacks. That answer only means anything if the PRODUCTION adapter is the thing // answering it, and if that adapter really filters on Deployed — a component that is correct in a // fake and unreachable in production is the four-times-shipped defect class in this repo. // // AST, never strings.Contains: a commented-out call still satisfies a substring match. // funcBody returns the named top-level func's body from main.go, or fails. func funcBodyInMain(t *testing.T, name string) *ast.BlockStmt { t.Helper() fset := token.NewFileSet() f, err := parser.ParseFile(fset, "main.go", nil, 0) if err != nil { t.Fatalf("parse main.go: %v", err) } for _, decl := range f.Decls { fn, ok := decl.(*ast.FuncDecl) if !ok || fn.Body == nil || fn.Name.Name != name { continue } return fn.Body } t.Fatalf("func %s not found in main.go", name) return nil } // TestMainWiresTheStackProviderIntoTheBackupManager: without this call the backup manager's // stackProvider is nil, isStackDeployed fails closed, and EVERY off-site restore refuses. func TestMainWiresTheStackProviderIntoTheBackupManager(t *testing.T) { body := funcBodyInMain(t, "main") var found bool ast.Inspect(body, func(n ast.Node) bool { call, ok := n.(*ast.CallExpr) if !ok { return true } sel, ok := call.Fun.(*ast.SelectorExpr) if !ok || sel.Sel.Name != "SetStackProvider" || len(call.Args) != 1 { return true } found = true return false }) if !found { t.Fatal("main() never calls SetStackProvider — the restore's deployment check would fail closed for every app") } } // TestStackAdapterListDeployedFiltersOnDeployed pins the semantics R-356 depends on: the adapter // returns DEPLOYED stacks, not all known ones. Verified by the presence of the `!s.Deployed` // continue-guard in the method body — remove it and an app that was never deployed would be told it // has somewhere to restore to. func TestStackAdapterListDeployedFiltersOnDeployed(t *testing.T) { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "main.go", nil, 0) if err != nil { t.Fatalf("parse main.go: %v", err) } var body *ast.BlockStmt for _, decl := range f.Decls { fn, ok := decl.(*ast.FuncDecl) if !ok || fn.Recv == nil || fn.Name.Name != "ListDeployedStacks" || fn.Body == nil { continue } body = fn.Body } if body == nil { t.Fatal("stackAdapter.ListDeployedStacks not found in main.go") } var guarded bool ast.Inspect(body, func(n ast.Node) bool { un, ok := n.(*ast.UnaryExpr) if !ok || un.Op != token.NOT { return true } sel, ok := un.X.(*ast.SelectorExpr) if ok && sel.Sel.Name == "Deployed" { guarded = true } return true }) if !guarded { t.Fatal("ListDeployedStacks does not test !s.Deployed — an undeployed app would be reported installed") } }