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
78 lines
3.6 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|