package resolution import ( "strings" "testing" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) // The mesh's bus is one per mesh, read from the catalogue beside this checkout. // // **This is step 2's claim, and it is checked here rather than in a bed** (novox/hq ADR 0116): // adoption puts the NATS server into the `mesh-broker` seat on a mesh that is already running, // and the property that matters is that a second one anywhere is refused *when it is assigned*, // not discovered later as two servers holding different halves of the mesh's traffic. A second // bus is not a degraded mesh; it is two meshes that both believe they are the one. func TestASecondMeshBusAnywhereIsRefusedByName(t *testing.T) { nats := catalogueManifest(t, "nats") if _, err := Resolve(shelf(nats), []string{"nats"}, workstation(), mcat.World{}); err != nil { t.Fatalf("the bus alone does not resolve: %v", err) } elsewhere := mcat.World{Held: []mcat.Held{{Claim: "mesh-broker", Scope: mcat.ScopeMesh, Node: "anchor", Module: "nats"}}} other := workstation() other.Name = "laptop" _, err := Resolve(shelf(nats), []string{"nats"}, other, elsewhere) if err == nil { t.Fatal("a second bus was accepted on another machine") } if !strings.Contains(err.Error(), "mesh-broker") || !strings.Contains(err.Error(), "one per mesh") { t.Fatalf("refused without naming the seat: %v", err) } } // The seat is the server's role, not the product's name (novox/hq ADR 0079). A different // implementation of the bus claims the same seat, and the mesh refuses it for the same reason — // which is the property that lets the bus be replaced at all. func TestTheSeatRefusesADifferentBusToo(t *testing.T) { nats := catalogueManifest(t, "nats") held := mcat.World{Held: []mcat.Held{{Claim: "mesh-broker", Scope: mcat.ScopeMesh, Node: "anchor", Module: "some-other-broker"}}} other := workstation() other.Name = "laptop" if _, err := Resolve(shelf(nats), []string{"nats"}, other, held); err == nil { t.Fatal("the seat admitted a second holder because the module's name differed") } }