adding prettybench and go-junit-report to vendor

This commit is contained in:
Krzysztof Siedlecki
2019-02-05 13:02:18 +01:00
parent 29e9ff36a9
commit 6c1a842248
74 changed files with 20563 additions and 10432 deletions

1
vendor/github.com/cespare/prettybench/.gitignore generated vendored Normal file
View File

@@ -0,0 +1 @@
/prettybench

30
vendor/github.com/cespare/prettybench/BUILD generated vendored Normal file
View File

@@ -0,0 +1,30 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = ["prettybench.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/cespare/prettybench",
importpath = "github.com/cespare/prettybench",
visibility = ["//visibility:private"],
deps = ["//vendor/golang.org/x/tools/benchmark/parse:go_default_library"],
)
go_binary(
name = "prettybench",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

22
vendor/github.com/cespare/prettybench/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2014 Caleb Spare
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

36
vendor/github.com/cespare/prettybench/README.md generated vendored Normal file
View File

@@ -0,0 +1,36 @@
# Prettybench
A tool for transforming `go test`'s benchmark output a bit to make it nicer for humans.
## Problem
Go benchmarks are great, particularly when used in concert with benchcmp. But the output can be a bit hard to
read:
![before](/screenshots/before.png)
## Solution
$ go get github.com/cespare/prettybench
$ go test -bench=. | prettybench
![after](/screenshots/after.png)
* Column headers
* Columns are aligned
* Time output is adjusted to convenient units
## Notes
* Right now the units for the time are chosen based on the smallest value in the column.
* Prettybench has to buffer all the rows of output before it can print them (for column formatting), so you
won't see intermediate progress. If you want to see that too, you could tee your output so that you see the
unmodified version as well. If you do this, you'll want to use the prettybench's `-no-passthrough` flag so
it doesn't print all the other lines (because then they'd be printed twice):
$ go test -bench=. | tee >(prettybench -no-passthrough)
## To Do (maybe)
* Handle benchcmp output
* Change the units for non-time columns as well (these are generally OK though).

198
vendor/github.com/cespare/prettybench/prettybench.go generated vendored Normal file
View File

@@ -0,0 +1,198 @@
package main
import (
"bufio"
"bytes"
"errors"
"flag"
"fmt"
"os"
"regexp"
"strconv"
"strings"
"time"
bench "golang.org/x/tools/benchmark/parse"
)
var noPassthrough = flag.Bool("no-passthrough", false, "Don't print non-benchmark lines")
type BenchOutputGroup struct {
Lines []*bench.Benchmark
// Columns which are in use
Measured int
}
type Table struct {
MaxLengths []int
Cells [][]string
}
func (g *BenchOutputGroup) String() string {
if len(g.Lines) == 0 {
return ""
}
columnNames := []string{"benchmark", "iter", "time/iter"}
if (g.Measured & bench.MBPerS) > 0 {
columnNames = append(columnNames, "throughput")
}
if (g.Measured & bench.AllocedBytesPerOp) > 0 {
columnNames = append(columnNames, "bytes alloc")
}
if (g.Measured & bench.AllocsPerOp) > 0 {
columnNames = append(columnNames, "allocs")
}
table := &Table{Cells: [][]string{columnNames}}
var underlines []string
for _, name := range columnNames {
underlines = append(underlines, strings.Repeat("-", len(name)))
}
table.Cells = append(table.Cells, underlines)
timeFormatFunc := g.TimeFormatFunc()
for _, line := range g.Lines {
row := []string{line.Name, FormatIterations(line.N), timeFormatFunc(line.NsPerOp)}
if (g.Measured & bench.MBPerS) > 0 {
row = append(row, FormatMegaBytesPerSecond(line))
}
if (g.Measured & bench.AllocedBytesPerOp) > 0 {
row = append(row, FormatBytesAllocPerOp(line))
}
if (g.Measured & bench.AllocsPerOp) > 0 {
row = append(row, FormatAllocsPerOp(line))
}
table.Cells = append(table.Cells, row)
}
for i := range columnNames {
maxLength := 0
for _, row := range table.Cells {
if len(row[i]) > maxLength {
maxLength = len(row[i])
}
}
table.MaxLengths = append(table.MaxLengths, maxLength)
}
var buf bytes.Buffer
for _, row := range table.Cells {
for i, cell := range row {
var format string
switch i {
case 0:
format = "%%-%ds "
case len(row) - 1:
format = "%%%ds"
default:
format = "%%%ds "
}
fmt.Fprintf(&buf, fmt.Sprintf(format, table.MaxLengths[i]), cell)
}
fmt.Fprint(&buf, "\n")
}
return buf.String()
}
func FormatIterations(iter int) string {
return strconv.FormatInt(int64(iter), 10)
}
func (g *BenchOutputGroup) TimeFormatFunc() func(float64) string {
// Find the smallest time
smallest := g.Lines[0].NsPerOp
for _, line := range g.Lines[1:] {
if line.NsPerOp < smallest {
smallest = line.NsPerOp
}
}
switch {
case smallest < float64(10000*time.Nanosecond):
return func(ns float64) string {
return fmt.Sprintf("%.2f ns/op", ns)
}
case smallest < float64(time.Millisecond):
return func(ns float64) string {
return fmt.Sprintf("%.2f μs/op", ns/1000)
}
case smallest < float64(10*time.Second):
return func(ns float64) string {
return fmt.Sprintf("%.2f ms/op", (ns / 1e6))
}
default:
return func(ns float64) string {
return fmt.Sprintf("%.2f s/op", ns/1e9)
}
}
}
func FormatMegaBytesPerSecond(l *bench.Benchmark) string {
if (l.Measured & bench.MBPerS) == 0 {
return ""
}
return fmt.Sprintf("%.2f MB/s", l.MBPerS)
}
func FormatBytesAllocPerOp(l *bench.Benchmark) string {
if (l.Measured & bench.AllocedBytesPerOp) == 0 {
return ""
}
return fmt.Sprintf("%d B/op", l.AllocedBytesPerOp)
}
func FormatAllocsPerOp(l *bench.Benchmark) string {
if (l.Measured & bench.AllocsPerOp) == 0 {
return ""
}
return fmt.Sprintf("%d allocs/op", l.AllocsPerOp)
}
func (g *BenchOutputGroup) AddLine(line *bench.Benchmark) {
g.Lines = append(g.Lines, line)
g.Measured |= line.Measured
}
var (
benchLineMatcher = regexp.MustCompile(`^Benchmark.*\t.*\d+`)
okLineMatcher = regexp.MustCompile(`^ok\s`)
notBenchLineErr = errors.New("Not a bench line")
)
func ParseLine(line string) (*bench.Benchmark, error) {
if !benchLineMatcher.MatchString(line) {
return nil, notBenchLineErr
}
fields := strings.Split(line, "\t")
if len(fields) < 3 {
return nil, notBenchLineErr
}
return bench.ParseLine(line)
}
func main() {
flag.Parse()
currentBenchmark := &BenchOutputGroup{}
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
line, err := ParseLine(text)
switch err {
case notBenchLineErr:
if okLineMatcher.MatchString(text) {
fmt.Print(currentBenchmark)
currentBenchmark = &BenchOutputGroup{}
}
if !*noPassthrough {
fmt.Println(text)
}
case nil:
currentBenchmark.AddLine(line)
default:
fmt.Fprintln(os.Stderr, "prettybench unrecognized line:")
fmt.Println(text)
}
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}