File: slowest.go

package info (click to toggle)
gotestsum 1.8.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,060 kB
  • sloc: sh: 89; makefile: 16
file content (71 lines) | stat: -rw-r--r-- 1,937 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package aggregate

import (
	"sort"
	"time"

	"gotest.tools/gotestsum/testjson"
)

// Slowest returns a slice of all tests with an elapsed time greater than
// threshold. The slice is sorted by Elapsed time in descending order (slowest
// test first).
//
// If there are multiple runs of a TestCase, all of them will be represented
// by a single TestCase with the median elapsed time in the returned slice.
func Slowest(exec *testjson.Execution, threshold time.Duration) []testjson.TestCase {
	if threshold == 0 {
		return nil
	}
	pkgs := exec.Packages()
	tests := make([]testjson.TestCase, 0, len(pkgs))
	for _, pkg := range pkgs {
		pkgTests := ByElapsed(exec.Package(pkg).TestCases(), median)
		tests = append(tests, pkgTests...)
	}
	sort.Slice(tests, func(i, j int) bool {
		return tests[i].Elapsed > tests[j].Elapsed
	})
	end := sort.Search(len(tests), func(i int) bool {
		return tests[i].Elapsed < threshold
	})
	return tests[:end]
}

// ByElapsed maps all test cases by name, and if there is more than one
// instance of a TestCase, uses fn to select the elapsed time for the group.
//
// All cases are assumed to be part of the same package.
func ByElapsed(cases []testjson.TestCase, fn func(times []time.Duration) time.Duration) []testjson.TestCase {
	if len(cases) <= 1 {
		return cases
	}
	pkg := cases[0].Package
	// nolint: prealloc // size is not predictable
	m := make(map[testjson.TestName][]time.Duration)
	for _, tc := range cases {
		m[tc.Test] = append(m[tc.Test], tc.Elapsed)
	}
	result := make([]testjson.TestCase, 0, len(m))
	for name, timing := range m {
		result = append(result, testjson.TestCase{
			Package: pkg,
			Test:    name,
			Elapsed: fn(timing),
		})
	}
	return result
}

func median(times []time.Duration) time.Duration {
	switch len(times) {
	case 0:
		return 0
	case 1:
		return times[0]
	}
	sort.Slice(times, func(i, j int) bool {
		return times[i] < times[j]
	})
	return times[len(times)/2]
}