package catalogue import ( "go/ast" "go/parser" "go/token" "path/filepath" "slices" "strconv" "testing" "github.com/novox/mesh-controller/internal/beside" ) // The controller refuses a definition's resolved path by the node-engine's own rules, no more (novox/hq issue // 496): the same lists, read here from mesh-host's internal/apply/placement_guard.go — in a merge check the clone // beside it at the commit the mesh runs, elsewhere the copy captured in testdata/beside. When the engine's lists // move, this fails until the controller's move with them, so the gate never refuses what the engine applies nor // passes what it refuses by path alone. func TestTheResolvedPathRulesAreTheNodeEnginesOwn(t *testing.T) { file := filepath.Join(beside.Dir(t, "mesh-host"), "internal", "apply", "placement_guard.go") parsed, err := parser.ParseFile(token.NewFileSet(), file, nil, 0) if err != nil { t.Fatalf("the node-engine's guard does not parse: %v", err) } lists := map[string][]string{} consts := map[string]string{} ast.Inspect(parsed, func(n ast.Node) bool { spec, ok := n.(*ast.ValueSpec) if !ok { return true } for i, name := range spec.Names { if i >= len(spec.Values) { continue } switch v := spec.Values[i].(type) { case *ast.CompositeLit: for _, elt := range v.Elts { if lit, ok := elt.(*ast.BasicLit); ok && lit.Kind == token.STRING { s, _ := strconv.Unquote(lit.Value) lists[name.Name] = append(lists[name.Name], s) } } case *ast.BasicLit: if v.Kind == token.STRING { consts[name.Name], _ = strconv.Unquote(v.Value) } } } return true }) for name, ours := range map[string][]string{ "protectedRoots": protectedRoots, "forbiddenBelow": forbiddenBelow, "engineTrees": engineTrees, } { theirs := lists[name] if len(theirs) == 0 { t.Errorf("the node-engine's guard names no %s any more; read it and say where its rule went", name) continue } a, b := slices.Clone(ours), slices.Clone(theirs) slices.Sort(a) slices.Sort(b) if !slices.Equal(a, b) { t.Errorf("%s differs from the node-engine's:\n controller %v\n node-engine %v", name, a, b) } } if consts["engineModule"] != engineModule { t.Errorf("the node-engine's own module is %q there and %q here", consts["engineModule"], engineModule) } }