Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8ee728ad6 |
@@ -248,3 +248,46 @@ func TestAMemberBothRefusedAndHeldForAStatusIsOneStalledLine(t *testing.T) {
|
||||
t.Fatalf("%d stalled lines for one member: %+v", n, w.h.Stalled())
|
||||
}
|
||||
}
|
||||
|
||||
// 1275/AC6: a member refused because its verdict is out of date (the trunk moved; its fresh check runs) is a warning at
|
||||
// once, and urgent only when the group is not merged within ten minutes; the pass stops at the refusal all the same.
|
||||
func TestAnOutOfDateRefusalIsAWarningAtOnceAndUrgentAfterTenMinutes(t *testing.T) {
|
||||
w := approvedGroup(t)
|
||||
allGreen(w)
|
||||
w.forge.refuse = errAskedAgain
|
||||
w.op.answer(w.op.open()[0], OptionApprove)
|
||||
w.settleAll()
|
||||
if len(w.forge.merges) != 1 {
|
||||
t.Fatalf("the pass did not stop at the refusal: %v", w.forge.merges)
|
||||
}
|
||||
sev := func() []string {
|
||||
var out []string
|
||||
for _, l := range w.h.Stalled() {
|
||||
out = append(out, l.Severity)
|
||||
}
|
||||
return out
|
||||
}
|
||||
if got := sev(); len(got) != 1 || got[0] != "warning" {
|
||||
t.Fatalf("an out of date refusal is %v at once; wanted one warning", got)
|
||||
}
|
||||
w.later(9 * time.Minute)
|
||||
if got := sev(); len(got) != 1 || got[0] != "warning" {
|
||||
t.Fatalf("at nine minutes it is %v; wanted still a warning", got)
|
||||
}
|
||||
w.later(2 * time.Minute)
|
||||
if got := sev(); len(got) != 1 || got[0] != "urgent" {
|
||||
t.Fatalf("after ten minutes it is %v; wanted urgent", got)
|
||||
}
|
||||
}
|
||||
|
||||
// 1275/AC6: every other refusal (here a missing status) is urgent at once.
|
||||
func TestAMissingStatusRefusalIsUrgentAtOnce(t *testing.T) {
|
||||
w := approvedGroup(t)
|
||||
allGreen(w)
|
||||
w.forge.refuseRepo = map[string]error{gCat: refusedWords("novox/mesh-catalog#2")}
|
||||
w.op.answer(w.op.open()[0], OptionApprove)
|
||||
w.settleAll()
|
||||
if lines := w.h.Stalled(); len(lines) != 1 || lines[0].Severity != "urgent" {
|
||||
t.Fatalf("a missing status refusal is not urgent at once: %+v", lines)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ func (h *Holder) readyLines(now time.Time) []StalledLine {
|
||||
out = append(out, StalledLine{ID: d.ID, Number: d.Number, State: d.State,
|
||||
For: now.Sub(*r.RefusedSince).Round(time.Second).String(), Bound: groupRefusedFor.String(),
|
||||
H2: "none: the group's composed check is asked again after each refusal, and the merge each minute — the operator's",
|
||||
Severity: "urgent",
|
||||
Severity: refusalSeverity(r, now),
|
||||
Says: fmt.Sprintf("group %s is half merged: %s#%d is approved at %s and the merge tool has refused it since %s: %s. "+
|
||||
"Needed: the refusal's cause is met (the merge is asked again at each verdict, status or Approve), or the operator decides.",
|
||||
d.Group, d.Repository, d.Number, shortOf(r.Head, 12), r.RefusedSince.UTC().Format(time.RFC3339), r.Answer)})
|
||||
@@ -443,7 +443,7 @@ func (h *Holder) readyLines(now time.Time) []StalledLine {
|
||||
"status turning success — the operator's",
|
||||
Says: fmt.Sprintf("%s%s#%d is approved at %s, and the merge tool has refused it since %s: %s%s", heldInGroup(d),
|
||||
d.Repository, d.Number, shortOf(r.Head, 12), r.RefusedSince.UTC().Format(time.RFC3339), r.Answer, neededOf(d)),
|
||||
Severity: severityOf(d)})
|
||||
Severity: severityOf(d, now)})
|
||||
}
|
||||
}
|
||||
return out
|
||||
@@ -482,10 +482,30 @@ func neededOf(d *Delivery) string {
|
||||
return ". Needed: the refusal's cause is met (the merge is asked again at each verdict, status or Approve), or the operator decides."
|
||||
}
|
||||
|
||||
// severityOf is "urgent" for a member of a group (a refused merge is the group held), empty for a lone delivery.
|
||||
func severityOf(d *Delivery) string {
|
||||
if d.Group == "" {
|
||||
return ""
|
||||
// outOfDateFor is how long a refusal for an out of date verdict is a warning before it is urgent (issue 1275, AC6).
|
||||
const outOfDateFor = 10 * time.Minute
|
||||
|
||||
// outOfDateRefusal is whether the merge tool refused because the member's verdict is judged against an earlier trunk: the
|
||||
// forge's "its verdict was judged against trunk <t>, and main is now <t>. The check of head <h> merged into trunk <t> was
|
||||
// asked" (gitea merge.ts), whose fresh check is already running.
|
||||
func outOfDateRefusal(answer string) bool {
|
||||
return strings.Contains(answer, "its verdict ") && strings.Contains(answer, " is now ") ||
|
||||
strings.Contains(answer, "merged into trunk") && strings.Contains(answer, "was asked")
|
||||
}
|
||||
|
||||
// refusalSeverity is "warning" while a member's refusal for an out of date verdict is younger than ten minutes, as its
|
||||
// fresh check runs, and "urgent" for it after that and for every other refusal at once.
|
||||
func refusalSeverity(r *ReadyRun, now time.Time) string {
|
||||
if r.RefusedSince != nil && outOfDateRefusal(r.Answer) && now.Sub(*r.RefusedSince) < outOfDateFor {
|
||||
return "warning"
|
||||
}
|
||||
return "urgent"
|
||||
}
|
||||
|
||||
// severityOf is the severity of a refused member of a group, empty for a lone delivery.
|
||||
func severityOf(d *Delivery, now time.Time) string {
|
||||
if d.Group == "" {
|
||||
return ""
|
||||
}
|
||||
return refusalSeverity(d.Ready, now)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user