package link import ( "go/parser" "go/token" "io/fs" "path/filepath" "strings" "testing" "github.com/novox/mesh-controller/internal/broker" ) // Every subject the controller consumes is a kind with a contract, and every test a contract names // exists (novox/hq to-be 45 Phase 2, ADR 0227 rule 2). func TestEveryConsumedKindHasAContract(t *testing.T) { // What the controller can be handed, from the subjects it is granted and the ones it derives. subjects := []string{EnrolSubject, BuiltSubject, ReportSubject("anchor"), AliveSubject("anchor"), ToolsAliveSubject("anchor"), "mesh.mod.postgres.event.provisioner.failing"} subjects = append(subjects, broker.ControllerFollows...) kinds := map[string]bool{} for _, s := range subjects { kind, known := kindOfSubject(s) if !known { if strings.Contains(s, "*") { continue // a pattern among the follows; its concrete subject is listed above } t.Errorf("the controller follows %s and has no kind for it", s) continue } kinds[kind] = true } for kind := range kinds { c, ok := Contracts[kind] switch { case !ok: t.Errorf("the controller consumes %s and no contract says how an older one is told from a newer", kind) case (c.Ordered == "") == (c.Unordered == ""): t.Errorf("%s's contract says neither, or both, how it is ordered and why it need not be: %+v", kind, c) case c.Ordered != "" && len(c.Tests) == 0: t.Errorf("%s is ordered and no test delivers the newer and then the older", kind) } } for kind := range Contracts { if !kinds[kind] { t.Errorf("a contract for %s, which the controller does not consume", kind) } } // Every test named exists in this repository. exists := map[string]bool{} fset := token.NewFileSet() err := filepath.WalkDir("../..", func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() && (d.Name() == "vendor" || d.Name() == ".git") { return filepath.SkipDir } if d.IsDir() || !strings.HasSuffix(path, "_test.go") { return nil } f, err := parser.ParseFile(fset, path, nil, 0) if err != nil { return err } for name, obj := range f.Scope.Objects { if obj.Kind.String() == "func" && strings.HasPrefix(name, "Test") { exists[name] = true } } return nil }) if err != nil { t.Fatal(err) } for kind, c := range Contracts { for _, name := range c.Tests { if !exists[name] { t.Errorf("%s's contract names %s, which no test in this repository is", kind, name) } } } }