Fit the status line in the forge's 140 characters by giving the times and counts in their compact form before dropping them (issue 1682)
This commit is contained in:
@@ -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.<fp> 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]) + "…"
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user