mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	adding prettybench and go-junit-report to vendor
This commit is contained in:
		
							
								
								
									
										23
									
								
								vendor/github.com/jstemmer/go-junit-report/parser/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/jstemmer/go-junit-report/parser/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| load("@io_bazel_rules_go//go:def.bzl", "go_library") | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = ["parser.go"], | ||||
|     importmap = "k8s.io/kubernetes/vendor/github.com/jstemmer/go-junit-report/parser", | ||||
|     importpath = "github.com/jstemmer/go-junit-report/parser", | ||||
|     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"], | ||||
| ) | ||||
							
								
								
									
										303
									
								
								vendor/github.com/jstemmer/go-junit-report/parser/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								vendor/github.com/jstemmer/go-junit-report/parser/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,303 @@ | ||||
| package parser | ||||
|  | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"io" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Result represents a test result. | ||||
| type Result int | ||||
|  | ||||
| // Test result constants | ||||
| const ( | ||||
| 	PASS Result = iota | ||||
| 	FAIL | ||||
| 	SKIP | ||||
| ) | ||||
|  | ||||
| // Report is a collection of package tests. | ||||
| type Report struct { | ||||
| 	Packages []Package | ||||
| } | ||||
|  | ||||
| // Package contains the test results of a single package. | ||||
| type Package struct { | ||||
| 	Name        string | ||||
| 	Duration    time.Duration | ||||
| 	Tests       []*Test | ||||
| 	Benchmarks  []*Benchmark | ||||
| 	CoveragePct string | ||||
|  | ||||
| 	// Time is deprecated, use Duration instead. | ||||
| 	Time int // in milliseconds | ||||
| } | ||||
|  | ||||
| // Test contains the results of a single test. | ||||
| type Test struct { | ||||
| 	Name     string | ||||
| 	Duration time.Duration | ||||
| 	Result   Result | ||||
| 	Output   []string | ||||
|  | ||||
| 	SubtestIndent string | ||||
|  | ||||
| 	// Time is deprecated, use Duration instead. | ||||
| 	Time int // in milliseconds | ||||
| } | ||||
|  | ||||
| // Benchmark contains the results of a single benchmark. | ||||
| type Benchmark struct { | ||||
| 	Name     string | ||||
| 	Duration time.Duration | ||||
| 	// number of B/op | ||||
| 	Bytes int | ||||
| 	// number of allocs/op | ||||
| 	Allocs int | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	regexStatus   = regexp.MustCompile(`--- (PASS|FAIL|SKIP): (.+) \((\d+\.\d+)(?: seconds|s)\)`) | ||||
| 	regexIndent   = regexp.MustCompile(`^([ \t]+)---`) | ||||
| 	regexCoverage = regexp.MustCompile(`^coverage:\s+(\d+\.\d+)%\s+of\s+statements(?:\sin\s.+)?$`) | ||||
| 	regexResult   = regexp.MustCompile(`^(ok|FAIL)\s+([^ ]+)\s+(?:(\d+\.\d+)s|\(cached\)|(\[\w+ failed]))(?:\s+coverage:\s+(\d+\.\d+)%\sof\sstatements(?:\sin\s.+)?)?$`) | ||||
| 	// regexBenchmark captures 3-5 groups: benchmark name, number of times ran, ns/op (with or without decimal), B/op (optional), and allocs/op (optional). | ||||
| 	regexBenchmark = regexp.MustCompile(`^(Benchmark[^ -]+)(?:-\d+\s+|\s+)(\d+)\s+(\d+|\d+\.\d+)\sns/op(?:\s+(\d+)\sB/op)?(?:\s+(\d+)\sallocs/op)?`) | ||||
| 	regexOutput    = regexp.MustCompile(`(    )*\t(.*)`) | ||||
| 	regexSummary   = regexp.MustCompile(`^(PASS|FAIL|SKIP)$`) | ||||
| ) | ||||
|  | ||||
| // Parse parses go test output from reader r and returns a report with the | ||||
| // results. An optional pkgName can be given, which is used in case a package | ||||
| // result line is missing. | ||||
| func Parse(r io.Reader, pkgName string) (*Report, error) { | ||||
| 	reader := bufio.NewReader(r) | ||||
|  | ||||
| 	report := &Report{make([]Package, 0)} | ||||
|  | ||||
| 	// keep track of tests we find | ||||
| 	var tests []*Test | ||||
|  | ||||
| 	// keep track of benchmarks we find | ||||
| 	var benchmarks []*Benchmark | ||||
|  | ||||
| 	// sum of tests' time, use this if current test has no result line (when it is compiled test) | ||||
| 	var testsTime time.Duration | ||||
|  | ||||
| 	// current test | ||||
| 	var cur string | ||||
|  | ||||
| 	// keep track if we've already seen a summary for the current test | ||||
| 	var seenSummary bool | ||||
|  | ||||
| 	// coverage percentage report for current package | ||||
| 	var coveragePct string | ||||
|  | ||||
| 	// stores mapping between package name and output of build failures | ||||
| 	var packageCaptures = map[string][]string{} | ||||
|  | ||||
| 	// the name of the package which it's build failure output is being captured | ||||
| 	var capturedPackage string | ||||
|  | ||||
| 	// capture any non-test output | ||||
| 	var buffers = map[string][]string{} | ||||
|  | ||||
| 	// parse lines | ||||
| 	for { | ||||
| 		l, _, err := reader.ReadLine() | ||||
| 		if err != nil && err == io.EOF { | ||||
| 			break | ||||
| 		} else if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		line := string(l) | ||||
|  | ||||
| 		if strings.HasPrefix(line, "=== RUN ") { | ||||
| 			// new test | ||||
| 			cur = strings.TrimSpace(line[8:]) | ||||
| 			tests = append(tests, &Test{ | ||||
| 				Name:   cur, | ||||
| 				Result: FAIL, | ||||
| 				Output: make([]string, 0), | ||||
| 			}) | ||||
|  | ||||
| 			// clear the current build package, so output lines won't be added to that build | ||||
| 			capturedPackage = "" | ||||
| 			seenSummary = false | ||||
| 		} else if matches := regexBenchmark.FindStringSubmatch(line); len(matches) == 6 { | ||||
| 			bytes, _ := strconv.Atoi(matches[4]) | ||||
| 			allocs, _ := strconv.Atoi(matches[5]) | ||||
|  | ||||
| 			benchmarks = append(benchmarks, &Benchmark{ | ||||
| 				Name:     matches[1], | ||||
| 				Duration: parseNanoseconds(matches[3]), | ||||
| 				Bytes:    bytes, | ||||
| 				Allocs:   allocs, | ||||
| 			}) | ||||
| 		} else if strings.HasPrefix(line, "=== PAUSE ") { | ||||
| 			continue | ||||
| 		} else if strings.HasPrefix(line, "=== CONT ") { | ||||
| 			cur = strings.TrimSpace(line[8:]) | ||||
| 			continue | ||||
| 		} else if matches := regexResult.FindStringSubmatch(line); len(matches) == 6 { | ||||
| 			if matches[5] != "" { | ||||
| 				coveragePct = matches[5] | ||||
| 			} | ||||
| 			if strings.HasSuffix(matches[4], "failed]") { | ||||
| 				// the build of the package failed, inject a dummy test into the package | ||||
| 				// which indicate about the failure and contain the failure description. | ||||
| 				tests = append(tests, &Test{ | ||||
| 					Name:   matches[4], | ||||
| 					Result: FAIL, | ||||
| 					Output: packageCaptures[matches[2]], | ||||
| 				}) | ||||
| 			} else if matches[1] == "FAIL" && len(tests) == 0 && len(buffers[cur]) > 0 { | ||||
| 				// This package didn't have any tests, but it failed with some | ||||
| 				// output. Create a dummy test with the output. | ||||
| 				tests = append(tests, &Test{ | ||||
| 					Name:   "Failure", | ||||
| 					Result: FAIL, | ||||
| 					Output: buffers[cur], | ||||
| 				}) | ||||
| 				buffers[cur] = buffers[cur][0:0] | ||||
| 			} | ||||
|  | ||||
| 			// all tests in this package are finished | ||||
| 			report.Packages = append(report.Packages, Package{ | ||||
| 				Name:        matches[2], | ||||
| 				Duration:    parseSeconds(matches[3]), | ||||
| 				Tests:       tests, | ||||
| 				Benchmarks:  benchmarks, | ||||
| 				CoveragePct: coveragePct, | ||||
|  | ||||
| 				Time: int(parseSeconds(matches[3]) / time.Millisecond), // deprecated | ||||
| 			}) | ||||
|  | ||||
| 			buffers[cur] = buffers[cur][0:0] | ||||
| 			tests = make([]*Test, 0) | ||||
| 			benchmarks = make([]*Benchmark, 0) | ||||
| 			coveragePct = "" | ||||
| 			cur = "" | ||||
| 			testsTime = 0 | ||||
| 		} else if matches := regexStatus.FindStringSubmatch(line); len(matches) == 4 { | ||||
| 			cur = matches[2] | ||||
| 			test := findTest(tests, cur) | ||||
| 			if test == nil { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			// test status | ||||
| 			if matches[1] == "PASS" { | ||||
| 				test.Result = PASS | ||||
| 			} else if matches[1] == "SKIP" { | ||||
| 				test.Result = SKIP | ||||
| 			} else { | ||||
| 				test.Result = FAIL | ||||
| 			} | ||||
|  | ||||
| 			if matches := regexIndent.FindStringSubmatch(line); len(matches) == 2 { | ||||
| 				test.SubtestIndent = matches[1] | ||||
| 			} | ||||
|  | ||||
| 			test.Output = buffers[cur] | ||||
|  | ||||
| 			test.Name = matches[2] | ||||
| 			test.Duration = parseSeconds(matches[3]) | ||||
| 			testsTime += test.Duration | ||||
|  | ||||
| 			test.Time = int(test.Duration / time.Millisecond) // deprecated | ||||
| 		} else if matches := regexCoverage.FindStringSubmatch(line); len(matches) == 2 { | ||||
| 			coveragePct = matches[1] | ||||
| 		} else if matches := regexOutput.FindStringSubmatch(line); capturedPackage == "" && len(matches) == 3 { | ||||
| 			// Sub-tests start with one or more series of 4-space indents, followed by a hard tab, | ||||
| 			// followed by the test output | ||||
| 			// Top-level tests start with a hard tab. | ||||
| 			test := findTest(tests, cur) | ||||
| 			if test == nil { | ||||
| 				continue | ||||
| 			} | ||||
| 			test.Output = append(test.Output, matches[2]) | ||||
| 		} else if strings.HasPrefix(line, "# ") { | ||||
| 			// indicates a capture of build output of a package. set the current build package. | ||||
| 			capturedPackage = line[2:] | ||||
| 		} else if capturedPackage != "" { | ||||
| 			// current line is build failure capture for the current built package | ||||
| 			packageCaptures[capturedPackage] = append(packageCaptures[capturedPackage], line) | ||||
| 		} else if regexSummary.MatchString(line) { | ||||
| 			// don't store any output after the summary | ||||
| 			seenSummary = true | ||||
| 		} else if !seenSummary { | ||||
| 			// buffer anything else that we didn't recognize | ||||
| 			buffers[cur] = append(buffers[cur], line) | ||||
|  | ||||
| 			// if we have a current test, also append to its output | ||||
| 			test := findTest(tests, cur) | ||||
| 			if test != nil { | ||||
| 				if strings.HasPrefix(line, test.SubtestIndent+"    ") { | ||||
| 					test.Output = append(test.Output, strings.TrimPrefix(line, test.SubtestIndent+"    ")) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(tests) > 0 { | ||||
| 		// no result line found | ||||
| 		report.Packages = append(report.Packages, Package{ | ||||
| 			Name:        pkgName, | ||||
| 			Duration:    testsTime, | ||||
| 			Time:        int(testsTime / time.Millisecond), | ||||
| 			Tests:       tests, | ||||
| 			Benchmarks:  benchmarks, | ||||
| 			CoveragePct: coveragePct, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	return report, nil | ||||
| } | ||||
|  | ||||
| func parseSeconds(t string) time.Duration { | ||||
| 	if t == "" { | ||||
| 		return time.Duration(0) | ||||
| 	} | ||||
| 	// ignore error | ||||
| 	d, _ := time.ParseDuration(t + "s") | ||||
| 	return d | ||||
| } | ||||
|  | ||||
| func parseNanoseconds(t string) time.Duration { | ||||
| 	// note: if input < 1 ns precision, result will be 0s. | ||||
| 	if t == "" { | ||||
| 		return time.Duration(0) | ||||
| 	} | ||||
| 	// ignore error | ||||
| 	d, _ := time.ParseDuration(t + "ns") | ||||
| 	return d | ||||
| } | ||||
|  | ||||
| func findTest(tests []*Test, name string) *Test { | ||||
| 	for i := len(tests) - 1; i >= 0; i-- { | ||||
| 		if tests[i].Name == name { | ||||
| 			return tests[i] | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Failures counts the number of failed tests in this report | ||||
| func (r *Report) Failures() int { | ||||
| 	count := 0 | ||||
|  | ||||
| 	for _, p := range r.Packages { | ||||
| 		for _, t := range p.Tests { | ||||
| 			if t.Result == FAIL { | ||||
| 				count++ | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return count | ||||
| } | ||||
		Reference in New Issue
	
	Block a user