From d9a730307c315af365ec41f6f66bf206f3f7f964 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 9 Oct 2026 15:29:31 +0200 Subject: [PATCH] Test the newest merge's order, a second reopening's gaps and sub-second merge times (hq issues 348, 349) The review of PR 179 found four paths no test held: which of two earlier plans NewestMergeOf takes, a tie between them, gaps kept across a second reopening in one keeper, and a merge time's fraction of a second. --- cmd/mesh-controller/issue349_test.go | 21 ++++++++++++++ internal/conditions/store_test.go | 35 +++++++++++++++++++++++ internal/inventory/plans_test.go | 42 ++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/cmd/mesh-controller/issue349_test.go b/cmd/mesh-controller/issue349_test.go index 29ff7a75..f750cd41 100644 --- a/cmd/mesh-controller/issue349_test.go +++ b/cmd/mesh-controller/issue349_test.go @@ -171,3 +171,24 @@ func TestTheBranchOrderIsTheMerges(t *testing.T) { t.Fatal("merges within one second lost their order") } } + +// A merge time with a fraction of a second is kept whole in its plan, and two merges within one second keep +// their order through the plans and the lookup (review of PR 179). +func TestAMergeTimeKeepsItsFractionOfASecond(t *testing.T) { + at := "2026-10-09T10:57:52.123456789Z" + p := planOfMerge(link.SourceMoved{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "c1", MergedAt: at}, nil, nil) + want := time.Date(2026, 10, 9, 10, 57, 52, 123456789, time.UTC) + if !p.Merged.Equal(want) { + t.Fatalf("the plan's merge time is %s, not %s", p.Merged, want) + } + earlier := planOfMerge(link.SourceMoved{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "c0", + MergedAt: "2026-10-09T10:57:52.123456788Z"}, nil, nil) + earlier.Created = p.Created.Add(time.Second) // made after, merged before + if !earlierOnTheBranch(earlier, p) || earlierOnTheBranch(p, earlier) { + t.Fatal("two merges a nanosecond apart lost their order") + } + m := link.SourceMoved{Owner: "novox", Repo: "mesh-catalog", Base: "main", Commit: "c0", MergedAt: "2026-10-09T10:57:52.123456788Z"} + if !laterOnTheBranch(m, p) { + t.Fatal("a merge a nanosecond later was not found as the later one") + } +} diff --git a/internal/conditions/store_test.go b/internal/conditions/store_test.go index f460e0d8..5035e4a4 100644 --- a/internal/conditions/store_test.go +++ b/internal/conditions/store_test.go @@ -459,3 +459,38 @@ func TestAFaultKeepsItsNewestGapsAndForgetsWhatWasBefore(t *testing.T) { t.Fatalf("a fault reopened at its own first raising: %+v", d) } } + +// Two reopenings in one keeper, each after ClearSaying: both gaps kept, the fault begun at its first raising, +// and open again at the second clearing's reopening. +func TestASecondReopeningKeepsBothGaps(t *testing.T) { + k, _, _, c := keeper(t) + ctx := t.Context() + first, err := k.Observe(ctx, silent("ace")) + if err != nil { + t.Fatal(err) + } + var cleared []time.Time + for i := 0; i < 2; i++ { + c.pass(30 * time.Second) + cleared = append(cleared, c.now().UTC()) + if ok, err := k.ClearSaying(ctx, "machine.ace.silent", "heard again", "ace is heard again"); err != nil || !ok { + t.Fatalf("cleared %v: %v", ok, err) + } + c.pass(time.Minute) + if _, err := k.Observe(ctx, silent("ace")); err != nil { + t.Fatal(err) + } + } + got, err := k.Open(ctx) + if err != nil || len(got) != 1 { + t.Fatalf("%+v %v", got, err) + } + g := got[0] + if !g.Began().Equal(first.Raised) || len(g.Gaps) != 2 || !g.Gaps[0].Cleared.Equal(cleared[0]) || + !g.Gaps[1].Cleared.Equal(cleared[1]) || !g.Gaps[1].Reopened.Equal(g.Raised) || g.Count != 3 { + t.Fatalf("after two reopenings: began %s, gaps %+v, count %d", g.Began(), g.Gaps, g.Count) + } + if g.OpenAt(cleared[0].Add(time.Second)) || !g.OpenAt(cleared[0].Add(-time.Second)) || g.OpenAt(cleared[1].Add(time.Second)) { + t.Fatalf("open at the wrong moments: %+v", g) + } +} diff --git a/internal/inventory/plans_test.go b/internal/inventory/plans_test.go index a1cfff4b..b92c5195 100644 --- a/internal/inventory/plans_test.go +++ b/internal/inventory/plans_test.go @@ -73,3 +73,45 @@ func TestASupersededPlanIsNotOpen(t *testing.T) { t.Fatalf("a superseded plan is not among the recent ones as superseded: %+v", recent) } } + +// novox/hq issue 349 (review of the follow-up): the newest merge of a branch is the one merged last, whatever +// order the plans were made in, in any state; a tie is broken by the plan made last; a release, another +// branch and another repository are never it; and its time is kept to the nanosecond. +func TestTheNewestMergeOfABranchIsTheOneMergedLast(t *testing.T) { + inv := ForTest(t) + ctx := t.Context() + t0 := time.Date(2026, 10, 9, 10, 0, 0, 0, time.UTC) + save := func(id, repo, branch string, merged, created time.Time, state string, release bool) { + t.Helper() + p := Plan{ID: id, Repository: repo, Branch: branch, Commit: id + "-commit", Merged: merged, Created: created, + State: state, Tiers: [][]string{}, Modules: map[string]*PlanModule{}} + if release { + p.Release = &PlanRelease{} + } + if err := inv.SavePlan(ctx, &p); err != nil { + t.Fatal(err) + } + } + if _, found, err := inv.NewestMergeOf(ctx, "novox/mesh-catalog", "main"); err != nil || found { + t.Fatalf("a branch with no plan: %v %v", found, err) + } + // Made in the other order than merged: the later merge's plan made first, and done. + save("plan-later", "novox/mesh-catalog", "main", t0.Add(2*time.Minute+250*time.Millisecond), t0, PlanDone, false) + save("plan-earlier", "novox/mesh-catalog", "main", t0.Add(time.Minute), t0.Add(5*time.Minute), PlanRolling, false) + save("plan-other-branch", "novox/mesh-catalog", "release", t0.Add(time.Hour), t0, PlanRolling, false) + save("plan-other-repo", "novox/mesh-controller", "main", t0.Add(time.Hour), t0, PlanRolling, false) + save("release-1", "novox/mesh-catalog", "main", t0.Add(time.Hour), t0, PlanRolling, true) + save("plan-unknown", "novox/mesh-catalog", "main", time.Time{}, t0.Add(time.Hour), PlanRolling, false) + p, found, err := inv.NewestMergeOf(ctx, "Novox/Mesh-Catalog", "main") + if err != nil || !found || p.ID != "plan-later" { + t.Fatalf("the newest merge: %s %v %v", p.ID, found, err) + } + if !p.Merged.Equal(t0.Add(2*time.Minute + 250*time.Millisecond)) { + t.Fatalf("its merge time was not kept to the nanosecond: %s", p.Merged) + } + // The same merge time: the plan made last. + save("plan-again", "novox/mesh-catalog", "main", t0.Add(2*time.Minute+250*time.Millisecond), t0.Add(time.Minute), PlanBuilding, false) + if p, _, _ := inv.NewestMergeOf(ctx, "novox/mesh-catalog", "main"); p.ID != "plan-again" { + t.Fatalf("one merge time, two plans: %s", p.ID) + } +}