mesh/check failed: unit: ..test: node:internal/modules/esm/resolve:241 | 01f615aa0ad6 on aa9da942606d | unit 3345 run, 0 kept, 7 skipped | integration…
mesh/repo-check head 01f615aa0ad6 merged into trunk aa9da942606d — pass: its merge-check.sh passed
mesh/merge-gate head 01f615aa0ad6 merged into trunk aa9da942606d — pass: group feat/r4d composed: every machine composes with the change as it did without …
mesh/delivery delivered
mesh/delivery-group group feat/r4d delivered: every member is delivered
mesh-catalog #434 runs the nats server as the upstream image named in module.json (ADR 0497) and deletes modules/nats/Dockerfile, so the check failed opening it. The manifest's upstream nats artifact is read first; the Dockerfile only for a catalogue from before the move (the captured copy).
100 lines
3.8 KiB
Go
100 lines
3.8 KiB
Go
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:<release>-alpine@sha256:…`);
|
|
// before it, an image built from the module's Dockerfile, whose `upstream: nats <release>-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:<x.y.z>-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
|
|
}
|