From b1baa8d8baf0289b76e8082b3b95d146af6a973e Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 13 Oct 2026 02:27:07 +0200 Subject: [PATCH] Replay issue 166 with only what the catalogue had before its fix (for mesh-lab R166) A replay must fail on the commit before its fix and pass on it; the fix's own tests read what the fix added, so this one uses only ParseManifest, Resolve and the resolve tests' helpers, and can be laid over the commit before #281. --- internal/catalogue/replay166_test.go | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 internal/catalogue/replay166_test.go diff --git a/internal/catalogue/replay166_test.go b/internal/catalogue/replay166_test.go new file mode 100644 index 00000000..7611666b --- /dev/null +++ b/internal/catalogue/replay166_test.go @@ -0,0 +1,44 @@ +package catalogue + +import ( + "strings" + "testing" +) + +// Replay of novox/hq issue 166: every soft dependency had become a hard requirement. grafana runs without a +// data source, yet a manifest could not say so: a mesh without influxdb could not register a grafana that +// said its influxdb-api was optional, and with influxdb only in the catalogue, assigning grafana installed +// influxdb for it. Written only with what the catalogue had before its fix (mesh-controller #281): +// ParseManifest, Resolve, and the resolve tests' shelf, reachable machine and names, so it is laid over the +// commit before. +func TestReplay166(t *testing.T) { + grafana, err := ParseManifest([]byte(`{"module":"grafana","version":"1", + "requires":[{"name":"influxdb-api","optional":true}]}`)) + if err != nil { + t.Fatalf("a manifest cannot say grafana runs without influxdb-api: %v", err) + } + catalogue := shelf( + Manifest{Module: "influxdb", Version: "1", Provides: FromAnywhere("influxdb-api")}, + grafana, + ) + // Nothing in the mesh runs influxdb; it is only in the catalogue. + got, err := Resolve(catalogue, []string{"grafana"}, reachable(), World{}) + if err != nil { + t.Fatalf("grafana could not be assigned on a mesh without influxdb: %v", err) + } + if have := strings.Join(names(got), " "); have != "grafana" { + t.Fatalf("assigning grafana put %s on the machine; nothing is installed for an optional requirement", have) + } + if len(got.Needs) != 0 { + t.Fatalf("grafana was given a binding with nothing providing it: %+v", got.Needs) + } + // And once influxdb runs somewhere, grafana binds to it as before. + got, err = Resolve(catalogue, []string{"grafana"}, reachable(), World{Offered: map[string][]Provider{ + "influxdb-api": {{Node: "anchor", At: "anchor.internal", Module: "influxdb"}}}}) + if err != nil { + t.Fatal(err) + } + if len(got.Needs) != 1 || got.Needs[0].From != "anchor" || got.Needs[0].For != "grafana" { + t.Fatalf("grafana did not bind to influxdb on anchor: %+v", got.Needs) + } +}