tools: test-runner add TIME column
Shows the net time spent waiting for tint & validators to complete the test run Helps identify the slow compilers Change-Id: I3e915762fdb4dc56f02320d7f5e0e13f7cb83d78 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60343 Kokoro: Kokoro <noreply+kokoro@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
6ed467a340
commit
b209c477db
|
@ -249,13 +249,13 @@ func run() error {
|
||||||
|
|
||||||
type stats struct {
|
type stats struct {
|
||||||
numTests, numPass, numSkip, numFail int
|
numTests, numPass, numSkip, numFail int
|
||||||
|
timeTaken time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statistics per output format
|
// Statistics per output format
|
||||||
statsByFmt := map[outputFormat]*stats{}
|
statsByFmt := map[outputFormat]*stats{}
|
||||||
for _, format := range formats {
|
for _, format := range formats {
|
||||||
statsByFmt[format] = &stats{}
|
statsByFmt[format] = &stats{}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the table of file x format and gather per-format stats
|
// Print the table of file x format and gather per-format stats
|
||||||
|
@ -313,6 +313,7 @@ func run() error {
|
||||||
result := <-results[format]
|
result := <-results[format]
|
||||||
stats := statsByFmt[format]
|
stats := statsByFmt[format]
|
||||||
stats.numTests++
|
stats.numTests++
|
||||||
|
stats.timeTaken += result.timeTaken
|
||||||
if err := result.err; err != nil {
|
if err := result.err; err != nil {
|
||||||
failures = append(failures, failure{
|
failures = append(failures, failure{
|
||||||
file: file, format: format, err: err,
|
file: file, format: format, err: err,
|
||||||
|
@ -386,6 +387,14 @@ func run() error {
|
||||||
printStat(green, "PASS", func(s *stats) int { return s.numPass })
|
printStat(green, "PASS", func(s *stats) int { return s.numPass })
|
||||||
printStat(yellow, "SKIP", func(s *stats) int { return s.numSkip })
|
printStat(yellow, "SKIP", func(s *stats) int { return s.numSkip })
|
||||||
printStat(red, "FAIL", func(s *stats) int { return s.numFail })
|
printStat(red, "FAIL", func(s *stats) int { return s.numFail })
|
||||||
|
|
||||||
|
cyan.Printf(alignRight("TIME", filenameColumnWidth))
|
||||||
|
fmt.Printf(" ┃ ")
|
||||||
|
for _, format := range formats {
|
||||||
|
timeTaken := printDuration(statsByFmt[format].timeTaken)
|
||||||
|
cyan.Printf(alignLeft(timeTaken, formatWidth(format)))
|
||||||
|
fmt.Printf(" │ ")
|
||||||
|
}
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
for _, f := range failures {
|
for _, f := range failures {
|
||||||
|
@ -458,6 +467,7 @@ const (
|
||||||
type status struct {
|
type status struct {
|
||||||
code statusCode
|
code statusCode
|
||||||
err error
|
err error
|
||||||
|
timeTaken time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type job struct {
|
type job struct {
|
||||||
|
@ -515,7 +525,10 @@ func (j job) run(wd, exe string, fxc bool, dxcPath, xcrunPath string, generateEx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the compiler...
|
// Invoke the compiler...
|
||||||
|
start := time.Now()
|
||||||
ok, out := invoke(wd, exe, args...)
|
ok, out := invoke(wd, exe, args...)
|
||||||
|
timeTaken := time.Since(start)
|
||||||
|
|
||||||
out = strings.ReplaceAll(out, "\r\n", "\n")
|
out = strings.ReplaceAll(out, "\r\n", "\n")
|
||||||
matched := expected == "" || expected == out
|
matched := expected == "" || expected == out
|
||||||
|
|
||||||
|
@ -527,7 +540,7 @@ func (j job) run(wd, exe string, fxc bool, dxcPath, xcrunPath string, generateEx
|
||||||
switch {
|
switch {
|
||||||
case ok && matched:
|
case ok && matched:
|
||||||
// Test passed
|
// Test passed
|
||||||
return status{code: pass}
|
return status{code: pass, timeTaken: timeTaken}
|
||||||
|
|
||||||
// --- Below this point the test has failed ---
|
// --- Below this point the test has failed ---
|
||||||
|
|
||||||
|
@ -535,7 +548,7 @@ func (j job) run(wd, exe string, fxc bool, dxcPath, xcrunPath string, generateEx
|
||||||
if generateSkip {
|
if generateSkip {
|
||||||
saveExpectedFile(j.file, j.format, "SKIP: FAILED\n\n"+out)
|
saveExpectedFile(j.file, j.format, "SKIP: FAILED\n\n"+out)
|
||||||
}
|
}
|
||||||
return status{code: skip}
|
return status{code: skip, timeTaken: timeTaken}
|
||||||
|
|
||||||
case !ok:
|
case !ok:
|
||||||
// Compiler returned non-zero exit code
|
// Compiler returned non-zero exit code
|
||||||
|
@ -543,7 +556,7 @@ func (j job) run(wd, exe string, fxc bool, dxcPath, xcrunPath string, generateEx
|
||||||
saveExpectedFile(j.file, j.format, "SKIP: FAILED\n\n"+out)
|
saveExpectedFile(j.file, j.format, "SKIP: FAILED\n\n"+out)
|
||||||
}
|
}
|
||||||
err := fmt.Errorf("%s", out)
|
err := fmt.Errorf("%s", out)
|
||||||
return status{code: fail, err: err}
|
return status{code: fail, err: err, timeTaken: timeTaken}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Compiler returned zero exit code, or output was not as expected
|
// Compiler returned zero exit code, or output was not as expected
|
||||||
|
@ -571,7 +584,7 @@ func (j job) run(wd, exe string, fxc bool, dxcPath, xcrunPath string, generateEx
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
%s`,
|
%s`,
|
||||||
expected, out, diff)
|
expected, out, diff)
|
||||||
return status{code: fail, err: err}
|
return status{code: fail, err: err, timeTaken: timeTaken}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -610,6 +623,9 @@ func indent(s string, n int) string {
|
||||||
func alignLeft(val interface{}, width int) string {
|
func alignLeft(val interface{}, width int) string {
|
||||||
s := fmt.Sprint(val)
|
s := fmt.Sprint(val)
|
||||||
padding := width - utf8.RuneCountInString(s)
|
padding := width - utf8.RuneCountInString(s)
|
||||||
|
if padding < 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
return s + strings.Repeat(" ", padding)
|
return s + strings.Repeat(" ", padding)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,6 +634,9 @@ func alignLeft(val interface{}, width int) string {
|
||||||
func alignCenter(val interface{}, width int) string {
|
func alignCenter(val interface{}, width int) string {
|
||||||
s := fmt.Sprint(val)
|
s := fmt.Sprint(val)
|
||||||
padding := width - utf8.RuneCountInString(s)
|
padding := width - utf8.RuneCountInString(s)
|
||||||
|
if padding < 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
return strings.Repeat(" ", padding/2) + s + strings.Repeat(" ", (padding+1)/2)
|
return strings.Repeat(" ", padding/2) + s + strings.Repeat(" ", (padding+1)/2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,6 +645,9 @@ func alignCenter(val interface{}, width int) string {
|
||||||
func alignRight(val interface{}, width int) string {
|
func alignRight(val interface{}, width int) string {
|
||||||
s := fmt.Sprint(val)
|
s := fmt.Sprint(val)
|
||||||
padding := width - utf8.RuneCountInString(s)
|
padding := width - utf8.RuneCountInString(s)
|
||||||
|
if padding < 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
return strings.Repeat(" ", padding) + s
|
return strings.Repeat(" ", padding) + s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,3 +702,22 @@ func invoke(wd, exe string, args ...string) (ok bool, output string) {
|
||||||
}
|
}
|
||||||
return true, str
|
return true, str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printDuration(d time.Duration) string {
|
||||||
|
sec := int(d.Seconds())
|
||||||
|
min := int(sec) / 60
|
||||||
|
hour := min / 60
|
||||||
|
min -= hour * 60
|
||||||
|
sec -= min * 60
|
||||||
|
sb := &strings.Builder{}
|
||||||
|
if hour > 0 {
|
||||||
|
fmt.Fprintf(sb, "%dh", hour)
|
||||||
|
}
|
||||||
|
if min > 0 {
|
||||||
|
fmt.Fprintf(sb, "%dm", min)
|
||||||
|
}
|
||||||
|
if sec > 0 {
|
||||||
|
fmt.Fprintf(sb, "%ds", sec)
|
||||||
|
}
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue