86 lines
2.5 KiB
Go
86 lines
2.5 KiB
Go
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"), HealthSubject("anchor"), "mesh.mod.postgres.event.provisioner.failing"}
|
|
subjects = append(subjects, broker.ControllerFollows...)
|
|
subjects = append(subjects, broker.ControllerHears...)
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
}
|