mesh-issues: test that a pull request closed unmerged is withdrawn, not stuck (hq issue 483)

This commit is contained in:
2026-10-11 12:23:42 +02:00
parent d81e7d063b
commit 601eed06e7
@@ -305,3 +305,103 @@ func mustView(t *testing.T, h *harness, n uint64) *View {
}
return v
}
// A pull request closed without merging is withdrawn: mesh-delivery says it `stopped` with no merged_as (its
// `closed` event). It is not a fix merged and stuck, not delivered, and not an open pull request: the operator is
// never told it is merged and not delivered, and a worker with nothing else in review holds a stale claim.
func TestAPullRequestClosedUnmergedIsWithdrawn(t *testing.T) {
for _, via := range []string{"transition", "checks"} {
t.Run(via, func(t *testing.T) {
h := newHarness(t)
now := clocked(h)
note := &notified{}
h.Notify = note.notify
n := h.open(t, "x", "mesh-catalog modules/records")
if _, err := h.Move(MoveAsk{Number: n, Status: StatusFixing, By: "fix-x@g14"}); err != nil {
t.Fatal(err)
}
linkPR(t, h, n, "mesh-catalog#9")
closed := now.Add(-time.Hour)
if via == "transition" {
transition(t, h, 9, "ready", "its merge", "", closed.Add(-time.Hour))
transition(t, h, 9, "stopped", "the pull request was closed without merging", "", closed)
} else {
h.Deliveries = func(string, string) (Delivery, error) {
return Delivery{State: "stopped", Why: "the pull request was closed without merging", Since: closed}, nil
}
}
*now = now.Add(25 * time.Hour)
for i := 0; i < 2; i++ {
if _, err := h.Sweep(); err != nil {
t.Fatal(err)
}
}
if len(note.said) != 0 {
t.Fatalf("a pull request closed unmerged was said to the operator: %q", note.said)
}
is := get(t, h, n)
if len(is.Fixes) != 1 || is.Fixes[0].Merged || is.Fixes[0].MergedAt != nil {
t.Fatalf("a pull request closed unmerged is kept as merged: %+v", is.Fixes)
}
v := asJSON(t, mustView(t, h, n))
if v["delivered-not-resolved"] == true || countEvents(h, EventReadyToVerify) != 0 {
t.Fatalf("a withdrawn pull request reads as delivered: %v", v)
}
if v["stale-claim"] != true {
t.Fatalf("a withdrawn pull request reads as open, so the claim is not stale: %v", v)
}
if d, _ := v["delivery"].(string); !strings.HasPrefix(d, "fix withdrawn: mesh-catalog#9") {
t.Fatalf("delivery %q", d)
}
// A second fix linked and delivered is all the issue waits for: the withdrawn one is no fix.
linkPR(t, h, n, "mesh-catalog#10")
transition(t, h, 10, "delivered", "", "abc", *now)
if v := mustView(t, h, n); !v.DeliveredNotResolved || v.Delivery != "delivered to every machine it should reach" {
t.Fatalf("%+v %q", v.DeliveredNotResolved, v.Delivery)
}
})
}
}
// One pull request linked to several issues is measured on each, and each is warned and cleared on its own.
func TestOnePullRequestLinkedToSeveralIssues(t *testing.T) {
h := newHarness(t)
now := clocked(h)
note := &notified{}
h.Notify = note.notify
var ns []uint64
for _, w := range []string{"fix-a@g14", "fix-b@shanks"} {
n := h.open(t, "x "+w, "mesh-catalog modules/records")
if _, err := h.Move(MoveAsk{Number: n, Status: StatusFixing, By: w}); err != nil {
t.Fatal(err)
}
linkPR(t, h, n, "mesh-catalog#9")
ns = append(ns, n)
}
transition(t, h, 9, "delivered", "", "abc", *now)
if countEvents(h, EventReadyToVerify) != 2 {
t.Fatalf("%d ready-to-verify", countEvents(h, EventReadyToVerify))
}
*now = now.Add(2 * time.Hour)
if _, err := h.Sweep(); err != nil {
t.Fatal(err)
}
if len(note.said) != 2 || !strings.Contains(strings.Join(note.said, "\n"), "fix-a@g14") ||
!strings.Contains(strings.Join(note.said, "\n"), "fix-b@shanks") {
t.Fatalf("said %q", note.said)
}
if _, err := h.Move(MoveAsk{Number: ns[0], Status: StatusResolved, FixedBy: []string{"mesh-catalog#9"}}); err != nil {
t.Fatal(err)
}
if err := h.OnMoved(envelopeOf(ns[0])); err != nil {
t.Fatal(err)
}
if _, err := h.Sweep(); err != nil {
t.Fatal(err)
}
if len(note.clear) != 1 || note.clear[0] != notResolvedKeyOf(ns[0]) || len(note.said) != 2 {
t.Fatalf("cleared %q, said %q", note.clear, note.said)
}
}
func notResolvedKeyOf(n uint64) string { return "issue-tracker.delivered-not-resolved." + keyOf(n) }