diff --git a/modules/mesh-delivery-checker/internal/check/judge.go b/modules/mesh-delivery-checker/internal/check/judge.go index afd9bf8..1697068 100644 --- a/modules/mesh-delivery-checker/internal/check/judge.go +++ b/modules/mesh-delivery-checker/internal/check/judge.go @@ -541,19 +541,29 @@ func failureWords(f Failure) string { if cause == "" { cause = causeIn(out) } - if cause == "" && out == "" && passed { + switch { + case cause == "" && out == "" && passed: cause = "the tests passed, then the test program exited with a failure: an os.Exit or a panic in TestMain or after the tests" + case cause == "" && out == "": + // The build module on main sends a package that stopped (a timeout, an exit, a kill) as its "FAIL" line alone. + cause = "the package failed with no test to name and no panic, signal or build error in its output (an older build module sent no cause)" } if len(cause) > MaxCause { cause = strings.ToValidUTF8(cause[:MaxCause], "") + "..." } - if len(out) > MaxWords-len(cause) { - out = out[len(out)-(MaxWords-len(cause)):] + // The words keep MaxWords exactly: the cause and its newline, the marker and the kept lines (review round 1). + budget := MaxWords + if cause != "" { + budget -= len(cause) + 1 + } + if len(out) > budget { + const marker = "... " + tail := out[len(out)-(budget-len(marker)):] // Start on a whole line, and a whole character. - if i := strings.IndexByte(out, '\n'); i >= 0 { - out = "... " + strings.TrimLeft(out[i:], "\n") + if i := strings.IndexByte(tail, '\n'); i >= 0 { + tail = strings.TrimLeft(tail[i:], "\n") } - out = strings.ToValidUTF8(out, "") + out = marker + strings.ToValidUTF8(tail, "") } if cause != "" && !strings.HasPrefix(firstLine(out), cause) { out = strings.TrimRight(cause+"\n"+out, "\n") @@ -572,10 +582,11 @@ func dropSummary(out string) (string, bool) { lines := strings.Split(out, "\n") kept := lines[:0] for _, l := range lines { - switch t := strings.TrimSpace(l); { + // go's exact forms only (review round 1): "PASS" or "FAIL" alone, "ok \t\t