Files
mesh-delivery/modules/mesh-delivery-forge-bridge/internal/bridge/moved_test.go
T
jschoubben dce4d01a58 FB1, FB9, FB10: the forge bridge writes one message per move of every watched branch
The bridge watches the registrations' branches by origin (a first view of registrations, then registration-changed),
before the first registration the gate's source's (source-moved); no branch is named in its code, Trunk goes. Every
move is heard on the seat git's branch-moved through the bridge's durable on SEAT_git_branch-moved, its head read by
the seat's verb branch, never the event's: merged with its pull request and `base` (the watched branch) when the
seat's pull names the head a pull request's merge, else `pushed` with branch, head and `before`, both with the
take-in inputs at the head. The last head written per watched branch is kept in the state heads under
branch.<owner>.<name>.<escaped branch>, so a move heard twice writes once, and each watched branch's head is read at
the start and when a branch is registered. A move of an unprotected branch writes nothing. pull.merged into a watched
branch writes nothing (its message is the move's); the forge-made merge's trunk filter goes.

Builds: design 47 G §4, §7, §11, §20, §41, §507, §509, §532, §714, A-227, A-236

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 09:15:04 +01:00

78 lines
3.6 KiB
Go

package bridge
import (
"context"
"encoding/json"
"errors"
"testing"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-forge-bridge/forgemsg"
"mesh-delivery-forge-bridge/internal/gitfixture"
)
// Design 47 G §4, §11, §507, §509, §714, A-236 (FB1, FB9, FB10): the watched branches are the registrations' by origin, and
// before the first registration the gate's source's, no branch fixed in code; a move of a watched branch is one message:
// merged with its pull request and base when the seat's pull names the new head a pull request's merge, pushed with
// its branch, head and before when it names none, both carrying the commit's take-in inputs; a pull the forge could not
// say is heard again, never read as a push.
func TestAMoveOfAWatchedBranchIsOneMessage(t *testing.T) {
w := &Watched{}
w.Set([]Registered{{Origin: "novox/mesh-sdk", Branches: []string{"main", "beta"}}}, []string{"main"})
for _, c := range []struct {
repo, branch string
want bool
}{{"novox/mesh-sdk", "beta", true}, {"novox/mesh-sdk", "feat/x", false}, {"novox/other", "main", false}} {
if got := w.Watches(c.repo, c.branch); got != c.want {
t.Errorf("registered: %s of %s watched %v, want %v", c.branch, c.repo, got, c.want)
}
}
if !watchedOf("main").Watches("novox/other", "main") || watchedOf("main").Watches("novox/other", "beta") {
t.Errorf("before the first registration the gate's source's branches are watched, of every repository")
}
const landedAt, before = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "cccccccccccccccccccccccccccccccccccccccc"
moved := Moved{Owner: "novox", Repo: "mesh-sdk", Branch: "beta"}
for _, c := range []struct {
name string
pull json.RawMessage
want forgemsg.Forge
retry bool
calls1 int
}{
{"a merge", gitfixture.Given(t, "pull answers", "verb:pull.answer"), forgemsg.Forge{Kind: forgemsg.ForgeMerged,
Branch: "feat/47-G", Number: 178, Head: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Merge: landedAt, Base: "beta"}, false, 1},
{"an admitted push", json.RawMessage(`{"error":"no pull request merged at that commit","error-kind":"not-found"}`),
forgemsg.Forge{Kind: forgemsg.ForgePushed, Branch: "beta", Head: landedAt, Before: before}, false, 1},
{"a pull the forge could not say", gitfixture.Given(t, "pull answers an error, never none", "verb:pull.answer"),
forgemsg.Forge{}, true, 0},
} {
var asked []string
ask := func(_ context.Context, key string, body any) (json.RawMessage, error) {
b, _ := json.Marshal(body)
asked = append(asked, key+" "+string(b))
return c.pull, nil
}
var trees []call
msg, err := MoveMessage(context.Background(), ask, moved, landedAt, before, treesOf(&trees, "r0", map[string]string{"modules/a": "t1"}, nil), anyFiles, nil)
if c.retry {
if !errors.Is(err, ErrRetry) || msg.Data != nil {
t.Errorf("%s: %v, %s; want ErrRetry and nothing written", c.name, err, msg.Data)
}
continue
}
if err != nil {
t.Fatalf("%s: %v", c.name, err)
}
f, err := forgemsg.DecodeForge(msg.Data)
c.want.V, c.want.Repository, c.want.Root = forgemsg.Version, "novox/mesh-sdk", "r0"
c.want.Trees, c.want.Manifests = map[string]string{"modules/a": "t1"}, map[string]string{"modules/a": "{}"}
if err != nil || !forgemsg.SameForge(f, c.want) || msg.Event != "forge.novox.mesh-sdk."+c.want.Kind {
t.Errorf("%s: %s %+v (%v), want %+v", c.name, msg.Event, f, err, c.want)
}
if len(trees) != c.calls1 || trees[0].sha != landedAt || asked[0] != `seat:git.pull {"merge-commit":"`+landedAt+`","repository":"novox/mesh-sdk"}` {
t.Errorf("%s: trees asked %v, pull asked %v; want the landed commit's", c.name, trees, asked)
}
}
}