github.com/aclements/go-misc@v0.0.0-20240129233631-2f6ede80790c/findflakes/text.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "io" 10 ) 11 12 func round(x float64) int { 13 return int(x + 0.5) 14 } 15 16 func pct(x float64) string { 17 p := 100 * x 18 if p >= 9.5 { 19 return fmt.Sprintf("%.0f%%", p) 20 } else if p > 0.95 { 21 return fmt.Sprintf("%.1f%%", p) 22 } else { 23 return fmt.Sprintf("%.2f%%", p) 24 } 25 } 26 27 func printTextReport(w io.Writer, classes []*failureClass) { 28 for _, fc := range classes { 29 fmt.Fprintf(w, "%s\n", fc.Class) 30 printTextFlakeReport(w, fc) 31 fmt.Fprintln(w) 32 } 33 } 34 35 func printTextFlakeReport(w io.Writer, fc *failureClass) { 36 // TODO: Report deterministic failures better. 37 // 38 // TODO: Report observed OSs/Arches 39 40 fmt.Fprintf(w, "First observed %s (%d commits ago)\n", fc.Revs[fc.Latest.First], len(fc.Revs)-fc.Latest.First-1) 41 fmt.Fprintf(w, "Last observed %s (%d commits ago)\n", fc.Revs[fc.Latest.Last], len(fc.Revs)-fc.Latest.Last-1) 42 if fc.Latest.First == fc.Latest.Last { 43 fmt.Fprintf(w, "Isolated failure\n") 44 } else { 45 fmt.Fprintf(w, "%s chance failure is still happening\n", pct(fc.Current)) 46 fmt.Fprintf(w, "%s failure probability (%d of %d commits)\n", pct(fc.Latest.FailureProbability), fc.Latest.Failures, fc.Latest.Last-fc.Latest.First+1) 47 fmt.Fprintf(w, "Likely culprits:\n") 48 for _, c := range fc.Latest.Culprits(0.9, 10) { 49 fmt.Fprintf(w, " %3d%% %s\n", round(100*c.P), fc.Revs[c.T].OneLine()) 50 } 51 } 52 53 if len(fc.Test.All) > 1 { 54 fmt.Fprintf(w, "Past failures:\n") 55 for _, reg := range fc.Test.All[1:] { 56 if reg.First == reg.Last { 57 rev := fc.Revs[reg.First] 58 fmt.Fprintf(w, " %s (isolated failure)\n", rev) 59 } else { 60 fmt.Fprintf(w, " %s to %s\n", fc.Revs[reg.First], fc.Revs[reg.Last]) 61 fmt.Fprintf(w, " %s failure probability (%d of %d commits)\n", pct(reg.FailureProbability), reg.Failures, reg.Last-reg.First+1) 62 } 63 } 64 } else { 65 fmt.Fprintf(w, "No known past failures\n") 66 } 67 }