diff --git a/internal/broker/checks_test.go b/internal/broker/checks_test.go new file mode 100644 index 00000000..e778abeb --- /dev/null +++ b/internal/broker/checks_test.go @@ -0,0 +1,39 @@ +package broker + +import "testing" + +// The build agent's credential is the module principal `.build-agent` (Username, KindModule): its manifest's +// `reads: ["mesh-delivery.pulls"]` reaches that principal as a read and a watch of mesh-delivery's bucket of pull requests' +// keys — the direct get of a key, the consumer a watch makes, the stream's info — and as no write and no direct +// subscription of the bucket's subjects (novox/hq ADR 0406 §4, issue 974). +func TestTheBuildAgentReadsAndWatchesThePullRequestsKeys(t *testing.T) { + seat := Seat{Name: TheBuildSeat, Scope: "node", Accepts: []string{"build"}, Emits: []string{"built", "started"}} + p := Principal{Kind: KindModule, Node: "one", Module: "build-agent", Holds: []Seat{seat}, + Reads: []string{"mesh-delivery.pulls"}, PasswordHash: "x"} + if got := p.Username(); got != "one.build-agent" { + t.Fatalf("the build agent's credential is %q", got) + } + perms, err := PermissionsFor(p) + if err != nil { + t.Fatal(err) + } + for _, s := range []string{ + "$JS.API.STREAM.INFO.KV_mesh-delivery_pulls", + "$JS.API.DIRECT.GET.KV_mesh-delivery_pulls.>", + "$JS.API.CONSUMER.CREATE.KV_mesh-delivery_pulls.>", + "$JS.API.CONSUMER.DELETE.KV_mesh-delivery_pulls.>", + // And the two check workers it takes from. + "$JS.API.CONSUMER.MSG.NEXT.CHECKS_READY.CHECKS_READY_worker", + "$JS.API.CONSUMER.MSG.NEXT.CHECKS_OTHER.CHECKS_OTHER_worker", + "$JS.ACK.CHECKS_OTHER.CHECKS_OTHER_worker.>", + } { + has(t, perms.Publish, s) + } + hasNot(t, perms.Publish, "$KV."+PullsBucket+".>") + hasNot(t, perms.Publish, "mesh.seat.node-build-agent.check.>") + for _, s := range perms.Subscribe { + if s == "$KV."+PullsBucket+".>" { + t.Fatalf("the build agent subscribes the bucket's subjects directly: %v", perms.Subscribe) + } + } +}