Test the group check's answer without swapping standard output, and wait for a take-in to forget a new module's wait (issue 1299, C2; issue 1851, A5)

This commit is contained in:
2026-10-22 20:19:57 +02:00
parent 7c0e1d223f
commit 420ae3d0e7
4 changed files with 24 additions and 52 deletions
@@ -6,9 +6,6 @@ import (
"context"
"encoding/json"
"errors"
"io"
"os"
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/catalogue"
@@ -101,47 +98,3 @@ func TestThePullRequestChecksAreAskedOnlyForARepositoryTheCheckerDoesNotJudge(t
t.Fatalf("0503 §5: the verdict said names a gate layer, or no repo-check layer: %+v", c)
}
}
// C2 (ADR 0503 §3; issue 1299): a delivery group's composed check asks build-agent nothing and answers that the checker
// judges the group.
func TestTheGroupCheckAsksNothingAndNamesTheChecker(t *testing.T) {
aMesh(t)
ctx := t.Context()
js, _ := aBuildQueue(t)
servingBus.Store(js)
t.Cleanup(func() { servingBus.Store(nil) })
members := `[{"id":"novox/a@111111111111","repository":"novox/a","base":"main","head":"1111111111111111111111111111111111111111","number":1},` +
`{"id":"novox/b@222222222222","repository":"novox/b","base":"main","head":"2222222222222222222222222222222222222222","number":2}]`
out := capturedStdout(t, func() error {
return deliveryCommand(ctx, []string{"check", "--group", "feat/x", "--members", members})
})
if !strings.Contains(out, `"judged-by": "mesh-delivery-checker"`) || !strings.Contains(out, `"asked": ""`) {
t.Fatalf("0503 §3: the group check answered %s", out)
}
q, err := link.ReadQueue(ctx, js, link.TheBuildMachine)
if err != nil {
t.Fatal(err)
}
if len(q.Asks) != 0 {
t.Fatalf("0503 §3: the group check asked %+v", q.Asks)
}
}
// capturedStdout is what run writes to standard output.
func capturedStdout(t *testing.T, run func() error) string {
t.Helper()
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
was := os.Stdout
os.Stdout = w
runErr := run()
os.Stdout = was
w.Close()
out, _ := io.ReadAll(r)
if runErr != nil {
t.Fatal(runErr)
}
return string(out)
}
+8 -2
View File
@@ -901,8 +901,7 @@ func deliveryCommand(ctx context.Context, args []string) error {
}
// **The group's composed check is the checker's** (novox/hq ADR 0503 §3; issue 1299, C2): nothing is asked of
// build-agent, and the answer says who judges it.
return answer(map[string]any{"asked": "", "group": *group, "judged-by": checkerModule,
"said": "the checker judges a delivery group's heads merged together (ADR 0503 §3): nothing was asked"})
return answer(groupCheckAnswer(*group))
case "go":
if len(positionals) != 1 {
return errors.New("delivery go <plan> [--by <who>] [--why <text>]")
@@ -1258,3 +1257,10 @@ func recheckOneHead(member string, answer func(any) error, ask func() (string, e
}
return answer(recheckAnswer(asked, member))
}
// groupCheckAnswer is what `delivery check` of a group answers from R4e: who judges it, and that nothing was asked
// (novox/hq ADR 0503 §3; issue 1299, C2).
func groupCheckAnswer(group string) map[string]any {
return map[string]any{"asked": "", "group": group, "judged-by": checkerModule,
"said": "the checker judges a delivery group's heads merged together (ADR 0503 §3): nothing was asked"}
}
+12
View File
@@ -0,0 +1,12 @@
package main
import "testing"
// C2 (ADR 0503 §3; issue 1299): a delivery group's composed check is answered as the checker's, and nothing is asked
// of build-agent: the command answers before any ask is composed.
func TestTheGroupCheckNamesTheCheckerAndAsksNothing(t *testing.T) {
a := groupCheckAnswer("feat/x")
if a["judged-by"] != "mesh-delivery-checker" || a["asked"] != "" || a["group"] != "feat/x" {
t.Fatalf("the group check answered %v", a)
}
}
@@ -58,9 +58,10 @@ func TestAMergeAddingAModuleEndsRegisteredFromItsKeyAndAsksNoBuild(t *testing.T)
_, known := inventoryHolds(t, inv, "systemd-resolved")
return known
})
if obs := newModuleObservations(time.Now().Add(time.Hour)); len(obs) != 0 {
t.Fatalf("a registered module is still named waiting: %+v", obs)
}
// The take-in forgets the wait just after the registration it made is seen.
becomes(t, 5*time.Second, "the registered module no longer named waiting", func() bool {
return len(newModuleObservations(time.Now().Add(time.Hour))) == 0
})
requests, err := inv.RequestsNamed(ctx, inventory.BuildRequest{Repository: "novox/mesh-catalog",
Path: "modules/systemd-resolved"}.Name())
if err != nil || len(requests) != 0 {