mesh/merge-gate head 37947ca4eed1 merged into trunk d8e785bb4b4b — pass: the change touches no module of the mesh's graph
mesh/repo-check head 37947ca4eed1 merged into trunk d8e785bb4b4b — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
The installer could not raise a first node: the old bundle's control plane had no MESH_BUS_NATS and crash-looped, and the NATS bundle was refused because rootsecrets only knew the previous broker's guest:guest@ template. One bundle now, the NATS one. rootsecrets makes the controller's bus account and puts it in both placeholders (the address and the bcrypt hash in the carried user list), kept with its hash so a re-run writes the same bundle. Preflight refuses a template naming no bus connection it knows, naming the placeholder, instead of waiting out the verify step. The broker step adopts the bus as the nats module and refuses, by name, a catalogue without it or a server that is not the foundation's container.
94 lines
3.5 KiB
Go
94 lines
3.5 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// aCatalogue is a catalogue checkout holding these modules' manifests.
|
|
func aCatalogue(t *testing.T, manifests map[string]string) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
for module, manifest := range manifests {
|
|
at := filepath.Join(dir, catalogueDir, module)
|
|
if err := os.MkdirAll(at, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(at, "module.json"), []byte(manifest), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
return dir
|
|
}
|
|
|
|
// aBusModule is the nats module's manifest as far as adoption reads it: a server container by name.
|
|
func aBusModule(server string) string {
|
|
return `{"module": "nats", "version": "1",
|
|
"claims": [{"name": "mesh-broker", "scope": "mesh"}],
|
|
"bus-users": "/var/lib/nats-module/conf/accounts.conf",
|
|
"resources": [{"id": "server", "type": "container", "name": "` + server + `", "ports": ["4222:4222"], "artifact": "server"}],
|
|
"build": {"artifacts": [{"name": "server", "kind": "image", "from": "Dockerfile"}]}}`
|
|
}
|
|
|
|
func busStep(t *testing.T, catalogue string) (*asked, error) {
|
|
t.Helper()
|
|
rewritten, err := Rewrite(theRealBundle(t), held)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
runtime := &asked{answer: aMeshThatAgrees(nil)}
|
|
control := controlPlane{container: "mesh-controller", run: runtime.run, timeout: 0}
|
|
err = InstallBroker(context.Background(), installing(t, catalogue), control, rewritten.Declaration, func(string) {})
|
|
return runtime, err
|
|
}
|
|
|
|
// The broker step adopts the foundation's bus as the nats module (novox/hq ADR 0331 §1): the module
|
|
// the mesh goes on managing, registered from the catalogue — never lavinmq, which left it.
|
|
func TestTheBrokerStepAdoptsTheBusAsTheNatsModule(t *testing.T) {
|
|
catalogue := aCatalogue(t, map[string]string{BusModule: aBusModule("mesh-broker")})
|
|
runtime, _ := busStep(t, catalogue)
|
|
if !runtime.ran("module add /nats-module.json") {
|
|
t.Fatalf("the nats module was not registered: %v", runtime.commands)
|
|
}
|
|
if runtime.ran("lavinmq") {
|
|
t.Errorf("the broker step still speaks of lavinmq: %v", runtime.commands)
|
|
}
|
|
}
|
|
|
|
// A catalogue that holds no nats module fails the step by name, before anything is registered —
|
|
// which is what today's step did for lavinmq, silently adopting a module that no longer exists.
|
|
func TestTheBrokerStepFailsForAModuleTheCatalogueDoesNotHold(t *testing.T) {
|
|
catalogue := aCatalogue(t, map[string]string{"lavinmq": `{"module": "lavinmq", "version": "1"}`})
|
|
runtime, err := busStep(t, catalogue)
|
|
if err == nil {
|
|
t.Fatal("a catalogue without the nats module was adopted from")
|
|
}
|
|
if !strings.Contains(err.Error(), "nats module") {
|
|
t.Errorf("the refusal does not name the module it looked for: %v", err)
|
|
}
|
|
if runtime.ran("module add") {
|
|
t.Errorf("something was registered: %v", runtime.commands)
|
|
}
|
|
}
|
|
|
|
// A bus module whose server is not the foundation's container by name would raise a second bus
|
|
// beside the first; it is refused naming both, before anything is registered.
|
|
func TestABusModuleWhoseServerIsNotTheFoundationsIsRefused(t *testing.T) {
|
|
catalogue := aCatalogue(t, map[string]string{BusModule: aBusModule("mesh-broker-nats")})
|
|
runtime, err := busStep(t, catalogue)
|
|
if err == nil {
|
|
t.Fatal("a bus module with another server was adopted")
|
|
}
|
|
for _, named := range []string{"mesh-broker-nats", `"mesh-broker"`} {
|
|
if !strings.Contains(err.Error(), named) {
|
|
t.Errorf("the refusal does not name %s: %v", named, err)
|
|
}
|
|
}
|
|
if runtime.ran("module add") {
|
|
t.Errorf("something was registered: %v", runtime.commands)
|
|
}
|
|
}
|