diff --git a/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go b/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go index 80d1623..c446fde 100644 --- a/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go +++ b/modules/mesh-delivery-checker/cmd/mesh-delivery-checker/integration_test.go @@ -220,7 +220,7 @@ func startBed(t *testing.T) *bed { for name, history := range map[string]int{delivery.CheckerVerdictsBucket: delivery.CheckerVerdictsHistory, delivery.CheckerKeptBucket: delivery.CheckerKeptHistory, delivery.CheckerOwedBucket: delivery.CheckerOwedHistory, delivery.PreviewsBucket: delivery.PreviewsHistory, delivery.CandidatesBucket: delivery.CandidatesHistory, delivery.ModulesBucket: delivery.ModulesHistory, delivery.ManifestsBucket: delivery.ManifestsHistory, delivery.SourceBucket: delivery.SourceHistory, - delivery.PresenceBucket: delivery.PresenceHistory, delivery.HaveBucket: delivery.HaveHistory, delivery.BuilderBuildsBucket: delivery.BuilderBuildsHistory} { + delivery.PresenceBucket: delivery.PresenceHistory, delivery.HaveBucket: delivery.HaveHistory} { kv, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: name, History: uint8(history)}) if err != nil { t.Fatal(err) @@ -526,28 +526,3 @@ func TestNoCheckStartsWhileADeliveryBuildsAndOneStartsWhenItEnds(t *testing.T) { t.Errorf("verdict = %+v", v) } } - -// TestTheLineSaysTheStateOfTheBuildsOfTheCandidatesModules: the builder wrote builds.avahi. done for the fingerprint the -// candidate carries for avahi; the status's line says avahi is built (ADR 0484 clause 7). -func TestTheLineSaysTheStateOfTheBuildsOfTheCandidatesModules(t *testing.T) { // N7/AC1 - b := startBed(t) - fp := "src2:" + strings.Repeat("a", 64) - buildKey, _ := delivery.BuilderBuildKey("avahi", fp) - done, err := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "n1.mesh-delivery-builder", Manifest: strings.Repeat("0a", 32), - Artifacts: []delivery.BuiltArtifact{{Name: "avahi", Kind: "bundle", Digest: "sha256:" + strings.Repeat("a", 64)}}}) - if err != nil { - t.Fatal(err) - } - if _, err := b.buckets[delivery.BuilderBuildsBucket].Put(b.ctx, buildKey, done); err != nil { - t.Fatal(err) - } - p := pull(repo, 7, head1) - p.Modules = []string{"avahi"} - p.Fps = map[string]delivery.CandidateModule{"avahi": {FP2: fp, Manifest: strings.Repeat("0a", 32)}} - key := b.candidate(t, "feat/x", p) - b.start(t, nil) - b.verdict(t, key, ended) - if o := b.owed(t, 7, head1, "success"); !strings.Contains(o.Text, "builds: avahi built") { - t.Errorf("owed = %+v, want the builds in the line", o) - } -} diff --git a/modules/mesh-delivery-checker/internal/check/line.go b/modules/mesh-delivery-checker/internal/check/line.go index db675c2..0882cf1 100644 --- a/modules/mesh-delivery-checker/internal/check/line.go +++ b/modules/mesh-delivery-checker/internal/check/line.go @@ -50,13 +50,16 @@ func firstFailed(v delivery.Verdict) string { // pieces are the parts of a line, from the most to the least needed. type pieces struct { - head, commits, counts, times, over, builds, composition, group string + head, commits, counts, shortCounts, times, shortTimes, over, builds, composition, group string } func (p pieces) join(drop int) string { parts := []string{p.head, p.commits, p.counts} - if drop < 3 && p.times != "" { + switch { + case drop < 3 && p.times != "": parts = append(parts, p.times) + case drop == 3 && p.shortTimes != "": + parts = []string{p.head, p.commits, p.shortCounts, p.shortTimes} } if p.over != "" { parts = append(parts, p.over) @@ -128,6 +131,18 @@ func parts(v delivery.Verdict, cs *Case, p Pull, builds []BuildNote, slowest []s } } pc.counts = strings.Join(counts, " | ") + var short []string + for _, level := range []string{delivery.LevelUnit, delivery.LevelIntegration} { + if r, ok := v.Levels[level]; ok { + name := map[string]string{delivery.LevelUnit: "unit", delivery.LevelIntegration: "int"}[level] + w := fmt.Sprintf("%s %d run %d kept", name, r.Run, r.Kept) + if r.Skipped > 0 { + w += fmt.Sprintf(" %d skipped", r.Skipped) + } + short = append(short, w) + } + } + pc.shortCounts = strings.Join(short, " | ") if v.State != delivery.VerdictRunning { t := v.Took var times []string @@ -142,6 +157,21 @@ func parts(v delivery.Verdict, cs *Case, p Pull, builds []BuildNote, slowest []s if len(times) > 0 { pc.times = strings.Join(times, ", ") } + // The compact form for a line that is too long: the parts that dominate, the integration level's setup and run as one. + short = short[:0:0] + if t.Clone > 0 { + short = append(short, "clone "+seconds(t.Clone)) + } + if t.Unit > 0 { + short = append(short, "unit "+seconds(t.Unit)) + } + switch { + case t.IntegrationSetup > 0 && t.IntegrationRun > 0: + short = append(short, "int "+seconds(t.IntegrationSetup)+"+"+seconds(t.IntegrationRun)) + case t.IntegrationRun > 0: + short = append(short, "int "+seconds(t.IntegrationRun)) + } + pc.shortTimes = strings.Join(short, " ") } if len(v.OverBound) > 0 { pc.over = "over bound: " + strings.Join(v.OverBound, ", ") @@ -171,14 +201,14 @@ func Report(v delivery.Verdict, cs *Case, p Pull, builds []BuildNote, slowest [] // failure names the conflict, the refused step or the test before anything), the head and the trunk commit as twelve // characters each, the tests run, kept and skipped per level, the time of each part, a level over its bound with its slowest // tests, the builds of the touched modules, and that the composition was not yet run. It is at most MaxLine characters: the -// builds, then the group, then the times drop in that order, and the line is cut at last. +// builds, then the group drop first, then the times are given in their compact form, then dropped, and the line is cut at last. func Line(v delivery.Verdict, cs *Case, p Pull, builds []BuildNote, slowest []string) string { pc := parts(v, cs, p, builds, slowest) - for drop := 0; drop <= 3; drop++ { + for drop := 0; drop <= 4; drop++ { if s := pc.join(drop); utf8.RuneCountInString(s) <= MaxLine { return s } } - runes := []rune(pc.join(3)) + runes := []rune(pc.join(4)) return string(runes[:MaxLine-1]) + "…" } diff --git a/modules/mesh-delivery-checker/internal/check/line_test.go b/modules/mesh-delivery-checker/internal/check/line_test.go index ccbce03..6ea2499 100644 --- a/modules/mesh-delivery-checker/internal/check/line_test.go +++ b/modules/mesh-delivery-checker/internal/check/line_test.go @@ -35,7 +35,8 @@ func TestAPassOpensWithTheVerdictAndSaysTheCommitsTheCountsTheTimesAndThatTheCom if n := utf8.RuneCountInString(line); n > MaxLine { t.Errorf("the line is %d characters, want at most %d: %q", n, MaxLine, line) } - if !strings.HasPrefix(line, "pass 111111111111 on aaaaaaaaaaaa") || !strings.Contains(line, "composition not yet run") || !strings.Contains(line, "unit 12 run, 301 kept") { + if !strings.HasPrefix(line, "pass 111111111111 on aaaaaaaaaaaa") || !strings.Contains(line, "composition not yet run") || !strings.Contains(line, "unit 12 run 301 kept") || + !strings.Contains(line, "clone 4.1s") || !strings.Contains(line, "int 3.2s+12s") { t.Errorf("line = %q", line) } }