diff --git a/cmd/mesh-controller/replay349_test.go b/cmd/mesh-controller/replay349_test.go index 69e9e4db..fae683a2 100644 --- a/cmd/mesh-controller/replay349_test.go +++ b/cmd/mesh-controller/replay349_test.go @@ -15,7 +15,9 @@ import ( // with "gitea planned there again": the forge's module was to be built for the commit without the fix. Written // only with what the controller had before its fix (mesh-controller #179): a mesh, two registered modules of the // catalogue, the merges as the forge announces them, the plans the inventory keeps — so it is laid over the -// commit before. +// commit before. Since novox/hq ADR 0276 the earlier merge waits in a batch behind the later merge's walk and is +// planned only when that walk ends and the cutter looks again; the replay ends the walk and has a merge of another +// repository heard, which looks, and a plan of the two merges left standing with nothing planned fails it. func TestReplay349(t *testing.T) { open := aMesh(t) ctx := t.Context() @@ -28,6 +30,10 @@ func TestReplay349(t *testing.T) { t.Fatal(err) } } + if err := inv.RegisterModule(ctx, catalogue.Manifest{Module: "other", Version: "1"}, + inventory.Source{Repository: "novox/other", Seat: "git", Ref: "main", BuiltFrom: "c0", Head: "c0"}); err != nil { + t.Fatal(err) + } // Both made after the modules were last looked at, so neither is history. made := time.Now().UTC().Add(time.Minute) merge := func(commit, module string, at time.Time) link.SourceMoved { @@ -44,24 +50,57 @@ func TestReplay349(t *testing.T) { t.Fatal(err) } + // The later merge's plan builds and ends; then a merge of another repository comes. Whatever holds the earlier + // merge back while that plan runs (a batch queued behind it, novox/hq ADR 0276) is decided by now: every plan + // of the two merges left standing says what it builds. plans, err := inv.RecentPlans(ctx, 20) if err != nil { t.Fatal(err) } - // A plan superseded hands its modules to the plan that took it over; the plans left standing are what the mesh - // builds. One of them builds the fixed module, and every one that does builds it at the commit holding the fix. - built := 0 for _, p := range plans { - t.Logf("%s %s at %.8s: %v %s", p.ID, p.State, p.Commit, p.Tiers, p.Note) - if _, holds := p.Modules["notes"]; !holds || p.State == inventory.PlanSuperseded { - continue - } - built++ - if p.Commit != fix { - t.Errorf("%s plans the fixed module notes at %s, a commit without the fix %s: %s", p.ID, p.Commit, fix, p.Note) + if p.Commit == fix && p.Open() { + p.State = inventory.PlanDone + if err := inv.SavePlan(ctx, &p); err != nil { + t.Fatal(err) + } } } - if built == 0 { + if err := (following{open: open}).SourceMoved(ctx, link.SourceMoved{Owner: "novox", Repo: "other", Base: "main", + Commit: "c1other", MergedAt: made.Add(2 * time.Minute).Format(time.RFC3339Nano), + Paths: []string{"main.go"}}); err != nil { + t.Fatal(err) + } + if plans, err = inv.RecentPlans(ctx, 20); err != nil { + t.Fatal(err) + } + // A plan superseded hands its modules to the plan that took it over; the plans left standing are what the mesh + // builds. Each plan of the two merges left standing plans modules; one builds app, the earlier merge's module; + // one builds notes, the module the later merge fixed, and every one that does builds it at the commit holding + // the fix. + app, notes := 0, 0 + for _, p := range plans { + t.Logf("%s %s at %.8s: %v %s", p.ID, p.State, p.Commit, p.Tiers, p.Note) + if p.State == inventory.PlanSuperseded || (p.Commit != fix && p.Commit != earlier) { + continue + } + if len(p.Modules) == 0 { + t.Errorf("%s, of the merge at %s, is left standing and plans nothing: %s", p.ID, p.Commit, p.Note) + } + if _, holds := p.Modules["app"]; holds { + app++ + } + if _, holds := p.Modules["notes"]; holds { + notes++ + if p.Commit != fix { + t.Errorf("%s plans the fixed module notes at %s, a commit without the fix %s: %s", p.ID, p.Commit, fix, + p.Note) + } + } + } + if app == 0 { + t.Error("no plan left standing builds app, the module the earlier merge moved") + } + if notes == 0 { t.Error("no plan left standing builds notes, the module the later merge fixed") } }