Judge the grants step on the declaration it sends, so nothing composed between the check and the send slips through (review of #230)
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check fail: its merge-check.sh failed: --- FAIL: TestTheGrantsStepSendsTheUserListAndNothingElse (2.55s)

The guard composed its own declaration ahead of the send; now sendToEach
judges the one it composed and stamped, and refuses it unsent.
This commit is contained in:
2026-10-11 19:12:33 +02:00
parent 538c4d5115
commit 78205d7405
4 changed files with 96 additions and 80 deletions
+9 -10
View File
@@ -3,6 +3,7 @@ package main
import (
"context"
"errors"
"fmt"
"slices"
"strings"
"testing"
@@ -32,9 +33,8 @@ type aSend struct {
func sendsRecorded(t *testing.T, holder string, behind bool, refuse error) *[]aSend {
t.Helper()
var sends []aSend
wasSend, wasBehind, wasOnly := sendRollout, brokerBehindOf, grantsOnlyOf
t.Cleanup(func() { sendRollout, brokerBehindOf, grantsOnlyOf = wasSend, wasBehind, wasOnly })
grantsOnlyOf = func(context.Context, *stores, string) (string, error) { return "", nil }
wasSend, wasBehind := sendRollout, brokerBehindOf
t.Cleanup(func() { sendRollout, brokerBehindOf = wasSend, wasBehind })
brokerBehindOf = func(_ context.Context, _ *stores, names []string) (string, bool, error) {
if slices.Contains(names, holder) {
return holder, false, nil
@@ -123,18 +123,17 @@ func TestAGrantsStepThatFailsIsSaidAndTheSendGoesOn(t *testing.T) {
}
}
// A step whose send would change more than the user list is not sent: it fails, said, and the walk goes on.
// A step whose send would change more than the user list is refused unsent by the send (sendToEach): the
// gate says it FAILED with what differed, and the walk goes on.
func TestAGrantsStepThatWouldCarryMoreIsNotSent(t *testing.T) {
sends := sendsRecorded(t, "novox", true, nil)
grantsOnlyOf = func(context.Context, *stores, string) (string, error) {
return "its send would change more than the bus's user list: -postgres.login-n8n", nil
}
refusal := fmt.Errorf("%w: its send would change more than the bus's user list: -postgres.login-n8n", errNotGrantsOnly)
sends := sendsRecorded(t, "novox", true, refusal)
sent, grants, err := sendJudged(t.Context(), nil, "ace")
if err != nil {
t.Fatal(err)
}
if len(*sends) != 1 || (*sends)[0].keepsAll || strings.Join(sent, ",") != "ace" {
t.Errorf("the walk made %+v, want ace's judged send alone", *sends)
if strings.Join(sent, ",") != "ace" || len(*sends) != 2 {
t.Errorf("the walk made %+v, want the refused step and then ace's judged send", *sends)
}
if grants == nil || grants.At != nil || !strings.Contains(grants.Failed, "-postgres.login-n8n") {
t.Fatalf("the gate keeps %+v", grants)