package testbus import ( "os" "path/filepath" "regexp" "strings" "testing" "encoding/json" "github.com/novox/mesh-controller/internal/beside" ) // **The bus the tests run is the bus the mesh runs** (novox/hq ADR 0227 rule 9, to-be 45 §9). The server // linked into the tests is held to the release the catalogue's bus image is — the catalogue a merge check // clones beside this one, or the copy captured in testdata/beside (internal/beside, novox/hq issue 432) — // and, in a merge check that has the facts snapshot, to the release the mesh's bus server says it runs. A // bus upgrade moves the catalogue's pin; this then fails in the merge check until the tests' pin moves // with it, so the controller is never tested against a bus the mesh no longer runs, or not yet. func TestTheBusTheTestsRunIsTheBusTheMeshRuns(t *testing.T) { release, from := catalogueBusRelease(t, filepath.Join(beside.Catalogue(t), "nats")) if release != Version { t.Errorf("the tests run bus %s and the catalogue's bus image is %s (%s): move go.mod's nats-server pin "+ "(and `go mod vendor`) with the image", Version, release, from) } path := os.Getenv("MESH_FACTS") if path == "" { t.Logf("no MESH_FACTS: the bus the mesh runs is compared in a merge check, which has it") return } body, err := os.ReadFile(path) if err != nil { t.Fatal(err) } // Read as little of the snapshot as this needs (internal/facts holds the whole shape). var f struct { Taken string `json:"taken"` Versions struct { Bus string `json:"bus"` } `json:"versions"` } if err := json.Unmarshal(body, &f); err != nil { t.Fatal(err) } if f.Versions.Bus != "" && strings.TrimPrefix(f.Versions.Bus, "v") != Version { t.Errorf("the tests run bus %s and the mesh's bus runs %s (facts of %s)", Version, f.Versions.Bus, f.Taken) } } // A test's bus is its own: what one test makes, the next never sees. // catalogueBusRelease is the server release the catalogue's nats module runs, and where it was read. Since // ADR 0497 the server is an upstream artifact in the module's manifest (`nats:-alpine@sha256:…`); // before it, an image built from the module's Dockerfile, whose `upstream: nats -alpine` line said // the release its digest is. The manifest is read first; the Dockerfile only where the manifest names no // upstream nats image (a catalogue from before that move, such as the captured copy). Neither is a failure. func catalogueBusRelease(t *testing.T, module string) (release, from string) { t.Helper() manifest := filepath.Join(module, "module.json") raw, err := os.ReadFile(manifest) if err != nil { t.Fatal(err) } var m struct { Build struct { Artifacts []struct { Name string `json:"name"` Kind string `json:"kind"` From string `json:"from"` } `json:"artifacts"` } `json:"build"` } if err := json.Unmarshal(raw, &m); err != nil { t.Fatalf("%s: %v", manifest, err) } upstream := regexp.MustCompile(`^(?:[^/]+/)*nats:([0-9]+\.[0-9]+\.[0-9]+)-alpine(?:@sha256:[0-9a-f]{64})?$`) for _, a := range m.Build.Artifacts { if a.Kind != "upstream" || !strings.HasPrefix(a.From[strings.LastIndex(a.From, "/")+1:], "nats:") { continue } pinned := upstream.FindStringSubmatch(a.From) if pinned == nil { t.Fatalf("%s: the upstream artifact %q is %q, which says no release in the form nats:-alpine", manifest, a.Name, a.From) } return pinned[1], manifest } dockerfile := filepath.Join(module, "Dockerfile") raw, err = os.ReadFile(dockerfile) if err != nil { t.Fatalf("%s names no upstream nats image, and the image built before it is not there either: %v", manifest, err) } pinned := regexp.MustCompile(`upstream: nats ([0-9.]+)-alpine`).FindSubmatch(raw) if pinned == nil { t.Fatalf("%s says no release its digest is", dockerfile) } return string(pinned[1]), dockerfile }