Files
mesh-catalog/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/issue1726_test.go
T
jschoubben 5ff337e0dc Gate keeps the merge's six states and asks the controller nothing (issue 1946, R6-C1, C2, C4)
Release 6 deletes the plans: the walk half of the holder, the controller port, the carry-over of the former module and the verbs times, what-if, release, stop and retire-history go; the table holds proposed, ready, rejected, merged, held and closed; the delivery's status and view name the source revision the merge moved.
2026-10-24 16:26:36 +02:00

127 lines
4.7 KiB
Go

package main
import (
"strings"
"testing"
"time"
)
// novox/hq issue 1726: a delivery made from a check's verdict that arrived before its pull request's head was heard
// (transition "its verdict arrived before its head was heard", as mesh-controller#419 at a47476252772 was) holds no base,
// branch, title, URLs or review record. The ready pass skipped it in silence, so no Approve was ever asked, and the
// announcement of the same head, heard later, filled none of it.
const verdictFirstBody = "Fixes a bug.\n\nReviewed-by: reviewer@shanks at " + readyHead + "\n"
// verdictFirst is the live shape: the verdict heard, the head not, and the delivery ready.
func verdictFirst(t *testing.T) (*world, string) {
w := newWorld(t)
w.op.auto = false
id := IDOf("novox/app", readyHead)
w.h.Checked(judgedAt("novox/app", 419, readyHead, "pass", "t1t1t1t1t1t1"))
w.settleAll()
d := w.delivery(id)
if d.State != Ready || d.Base != "" || d.Branch != "" || d.Title != "" || d.HTMLURL != "" {
t.Fatalf("not the live shape: %s base %q branch %q title %q", d.State, d.Base, d.Branch, d.Title)
}
return w, id
}
func TestADeliveryWithoutItsHeadSaysWhatItWaitsForAndAsksNoOne(t *testing.T) {
w, id := verdictFirst(t)
if n := len(w.op.open()); n != 0 {
t.Fatalf("an ask was made for a delivery with no base: %d", n)
}
d := w.delivery(id)
if d.Ready == nil || !strings.Contains(d.Ready.Waits, "announcement") {
t.Fatalf("it does not say what it waits for: %+v", d.Ready)
}
shown, err := w.h.Show(id)
if err != nil {
t.Fatal(err)
}
if waits, _ := shown.(map[string]any)["waits"].(string); !strings.Contains(waits, "announcement") {
t.Fatalf("show waits %q", waits)
}
}
func TestAnAnnouncementFillsADeliveryMadeFromItsVerdictAndTheOperatorIsAsked(t *testing.T) {
w, id := verdictFirst(t)
p := pr("novox/app", 419, readyHead, "fix/x", "src/a.go")
p.Title, p.Body, p.CloneURL = "Fix x", verdictFirstBody, "https://forge.invalid/novox/app.git"
w.h.PullUpdated(p)
w.settleAll()
d := w.delivery(id)
if d.Base != "main" || d.Branch != "fix/x" || d.Title != "Fix x" || d.HTMLURL == "" || d.CloneURL == "" ||
d.ReviewedBy != "reviewer@shanks" || len(d.Paths) != 1 {
t.Fatalf("the announcement did not fill the delivery: %+v", d)
}
if n := len(w.op.open()); n != 1 {
t.Fatalf("the operator was asked %d times; wanted once", n)
}
if d.Ready.Waits != "" && !strings.Contains(d.Ready.Waits, "Approve") {
t.Fatalf("still waits: %q", d.Ready.Waits)
}
}
func TestADeliveryWithoutItsHeadPastItsBoundIsStalled(t *testing.T) {
w, id := verdictFirst(t)
if s := w.h.Stalled(); len(s) != 0 {
t.Fatalf("stalled before its bound: %+v", s)
}
w.later(headHeardBound + time.Minute)
w.settleAll()
var found bool
for _, l := range w.h.Stalled() {
if l.ID == id && strings.Contains(l.Says, "announcement") {
found = true
}
}
if !found {
t.Fatalf("not stalled past its bound: %+v", w.h.Stalled())
}
}
// A head asked, then a push whose verdict is heard before its head: the announcement of the new head supersedes the old
// one exactly as a first announcement does, so one Approve stands, for the new head.
func TestAnAnnouncementFillingAVerdictFirstHeadSupersedesTheOlderHeadAndItsAsk(t *testing.T) {
w := newWorld(t)
w.op.auto = false
a, b := IDOf("novox/app", readyHead), IDOf("novox/app", pushed)
w.h.PullUpdated(pr("novox/app", 419, readyHead, "fix/x", "src/a.go"))
w.h.Checked(judgedAt("novox/app", 419, readyHead, "pass", "t1t1t1t1t1t1"))
w.settleAll()
if n := len(w.op.open()); n != 1 {
t.Fatalf("head A: %d asks open; wanted 1", n)
}
w.h.Checked(judgedAt("novox/app", 419, pushed, "pass", "t1t1t1t1t1t1"))
w.settleAll()
w.h.PullUpdated(pr("novox/app", 419, pushed, "fix/x", "src/a.go"))
w.settleAll()
if got := w.delivery(a); got.NewerHead != pushed || got.State != Closed {
t.Fatalf("head A is %s with newer head %q; wanted closed by %s", got.State, got.NewerHead, pushed)
}
if got := w.delivery(b); got.Base != "main" || got.Branch != "fix/x" {
t.Fatalf("head B not filled: %+v", got)
}
if n := len(w.op.open()); n != 1 {
t.Fatalf("%d asks open; wanted one, for the new head", n)
}
}
// A description edit is a natural trigger too: it fills a delivery made from its verdict.
func TestAnEditOfThePullRequestFillsADeliveryMadeFromItsVerdict(t *testing.T) {
w, id := verdictFirst(t)
p := pr("novox/app", 419, readyHead, "fix/x")
p.Title, p.Body = "Fix x", verdictFirstBody
w.h.PullEdited(p)
w.settleAll()
d := w.delivery(id)
if d.Base != "main" || d.Branch != "fix/x" || d.Title != "Fix x" || d.ReviewedBy != "reviewer@shanks" {
t.Fatalf("the edit did not fill the delivery: %+v", d)
}
if n := len(w.op.open()); n != 1 {
t.Fatalf("the operator was asked %d times; wanted once", n)
}
}