From 625d02862ccdf4369ebbb0635fe92ceade5ee984 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 5 Oct 2026 18:01:28 +0200 Subject: [PATCH 1/2] Test the bus users as issue 195 made them: an account-reading module is one, another is not The postgres-backed test still expected a module that declares no broker secret to be a bus user, and failed on main since #270; it skips without a database, so the change's own run did not see it. --- internal/inventory/busrecords_test.go | 30 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/internal/inventory/busrecords_test.go b/internal/inventory/busrecords_test.go index 15cf35d..fa9dfcb 100644 --- a/internal/inventory/busrecords_test.go +++ b/internal/inventory/busrecords_test.go @@ -42,26 +42,37 @@ func theSeatDeclarer() catalogue.Manifest { // A module assigned to a machine becomes a user with the authority its manifest declared — and the // protocol of a seat declared by a *different* module, which is the whole reason a seat exists. func TestAnAssignedModuleBecomesAUserWithWhatItDeclared(t *testing.T) { + // It declares where its account is delivered: a module with no own secret named broker can never + // be issued one, and is no user at all (novox/hq issue 195) — the case asserted below. shop := catalogue.Manifest{ Module: "shop", Version: "1", Emits: []string{"order.placed"}, Tools: []string{"price"}, - Uses: []string{"telegram-sender"}, + Uses: []string{"telegram-sender"}, + OwnSecrets: catalogue.OwnSecrets{"broker": {Path: "/run/broker"}}, } - inv, ctx := aMeshWith(t, theSeatDeclarer(), shop) + quiet := catalogue.Manifest{Module: "quiet", Version: "1", Emits: []string{"thing.happened"}} + inv, ctx := aMeshWith(t, theSeatDeclarer(), shop, quiet) if _, err := inv.AddNode(ctx, "one"); err != nil { t.Fatal(err) } - if _, err := inv.Assign(ctx, "one", "shop"); err != nil { - t.Fatal(err) + for _, module := range []string{"shop", "quiet"} { + if _, err := inv.Assign(ctx, "one", module); err != nil { + t.Fatal(err) + } } records, err := inv.BusRecords(ctx) if err != nil { t.Fatal(err) } - on := records.Assigned["one"] - if len(on) != 1 || on[0].Module != "shop" { - t.Fatalf("the machine's modules read as %+v", on) + var on []broker.Declared + for _, d := range records.Assigned["one"] { + if d.Module == "shop" { + on = append(on, d) + } + } + if len(on) != 1 || on[0].NoAccount { + t.Fatalf("the machine's modules read as %+v", records.Assigned["one"]) } if len(on[0].Uses) != 1 || on[0].Uses[0].Accepts[0] != "send" { t.Fatalf("the seat it uses carries no protocol: %+v — so it would be granted nothing on a "+ @@ -98,6 +109,11 @@ func TestAnAssignedModuleBecomesAUserWithWhatItDeclared(t *testing.T) { if !found { t.Fatal("no user was derived for the assigned module") } + for _, u := range users { + if u.Username() == "one.quiet" { + t.Fatal("a module with nowhere to read an account was made a user (novox/hq issue 195)") + } + } } // A machine holding a live token gets an enrolment user; one whose token is spent or expired does From 0b07e68cb8440c90cd9f5002965a7f70fd87b91a Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 5 Oct 2026 18:04:40 +0200 Subject: [PATCH 2/2] Publish the followed events once the controller's consumer exists Made from now since issue 248, the consumer does not replay what was published before it; the test raced the controller's start and published first. --- internal/link/receive_nats_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/link/receive_nats_test.go b/internal/link/receive_nats_test.go index 6f2b779..ba276e0 100644 --- a/internal/link/receive_nats_test.go +++ b/internal/link/receive_nats_test.go @@ -315,6 +315,12 @@ func TestNatsTheEventsTheControllerFollowsArriveAndAreAcknowledged(t *testing.T) ctx, stop := context.WithCancel(context.Background()) defer stop() go func() { _ = s.Serve(ctx) }() + // The controller's event consumer is made from now (novox/hq issue 248): what was published before + // it existed is history it never replays. So the announcements are made once it is there. + eventually(t, "the controller's event consumer being made", func() bool { + _, err := js.Context().ConsumerInfo("EVENTS", broker.ControllerName) + return err == nil + }) moved, _ := json.Marshal(Upgraded{Module: "gitea", Commit: "abcdef0123"}) if _, err := js.Context().Publish(broker.ControllerFollows[0], moved); err != nil {