Skip to content

Commit

Permalink
store test output by rootTestName->subTestNames->output
Browse files Browse the repository at this point in the history
In support of a workaround for golang/go#29755
  • Loading branch information
dnephin committed Apr 21, 2020
1 parent 08303fe commit 1233c41
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 23 deletions.
43 changes: 31 additions & 12 deletions testjson/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ type Package struct {
Failed []TestCase
Skipped []TestCase
Passed []TestCase
output map[string][]string
// output printed by test cases. Output is stored first by root TestCase
// name, then by subtest name to mitigate github.com/golang/go/issues/29755.
// In the future when that bug is fixed this can be reverted to store all
// output by full test name.
output map[string]map[string][]string
// coverage stores the code coverage output for the package without the
// trailing newline (ex: coverage: 91.1% of statements).
coverage string
Expand Down Expand Up @@ -106,7 +110,27 @@ func (p Package) TestCases() []TestCase {

// Output returns the full test output for a test.
func (p Package) Output(test string) string {
return strings.Join(p.output[test], "")
root, sub := splitTestName(test)
return strings.Join(p.output[root][sub], "")
}

func (p Package) addOutput(test string, output string) {
root, sub := splitTestName(test)
if p.output[root] == nil {
p.output[root] = make(map[string][]string)
}
// TODO: limit size of buffered test output
p.output[root][sub] = append(p.output[root][sub], output)

}

// splitTestName into root test name and any subtest names.
func splitTestName(name string) (root, sub string) {
parts := strings.SplitN(name, "/", 2)
if len(parts) < 2 {
return name, ""
}
return parts[0], parts[1]
}

// TestMainFailed returns true if the package failed, but there were no tests.
Expand Down Expand Up @@ -134,7 +158,7 @@ type TestCase struct {

func newPackage() *Package {
return &Package{
output: make(map[string][]string),
output: make(map[string]map[string][]string),
running: make(map[string]TestCase),
}
}
Expand Down Expand Up @@ -171,7 +195,7 @@ func (e *Execution) addPackageEvent(pkg *Package, event TestEvent) {
if isCachedOutput(event.Output) {
pkg.cached = true
}
pkg.output[""] = append(pkg.output[""], event.Output)
pkg.addOutput("", event.Output)
}
}

Expand All @@ -185,8 +209,7 @@ func (e *Execution) addTestEvent(pkg *Package, event TestEvent) {
}
return
case ActionOutput, ActionBench:
// TODO: limit size of buffered test output
pkg.output[event.Test] = append(pkg.output[event.Test], event.Output)
pkg.addOutput(event.Test, event.Output)
return
case ActionPause, ActionCont:
return
Expand Down Expand Up @@ -222,14 +245,10 @@ func isCachedOutput(output string) bool {
return strings.Contains(output, "\t(cached)")
}

// Output returns the full test output for a test.
func (e *Execution) Output(pkg, test string) string {
return strings.Join(e.packages[pkg].output[test], "")
}

// OutputLines returns the full test output for a test as an array of lines.
func (e *Execution) OutputLines(pkg, test string) []string {
return e.packages[pkg].output[test]
root, sub := splitTestName(test)
return e.packages[pkg].output[root][sub]
}

// Package returns the Package by name.
Expand Down
6 changes: 4 additions & 2 deletions testjson/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ func TestExecution_Add_PackageCoverage(t *testing.T) {
pkg := exec.Package("mytestpkg")
expected := &Package{
coverage: "coverage: 33.1% of statements",
output: map[string][]string{
"": {"coverage: 33.1% of statements\n"},
output: map[string]map[string][]string{
"": {
"": {"coverage: 33.1% of statements\n"},
},
},
running: map[string]TestCase{},
}
Expand Down
4 changes: 2 additions & 2 deletions testjson/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func shortVerboseFormat(event TestEvent, exec *Execution) (string, error) {
}

case event.Action == ActionFail:
return exec.Output(event.Package, event.Test) + formatTest(), nil
return exec.Package(event.Package).Output(event.Test) + formatTest(), nil

case event.Action == ActionPass:
return formatTest(), nil
Expand Down Expand Up @@ -164,7 +164,7 @@ func shortFormatPackageEvent(event TestEvent, exec *Execution) (string, error) {
func shortWithFailuresFormat(event TestEvent, exec *Execution) (string, error) {
if !event.PackageEvent() {
if event.Action == ActionFail {
return exec.Output(event.Package, event.Test), nil
return exec.Package(event.Package).Output(event.Test), nil
}
return "", nil
}
Expand Down
16 changes: 9 additions & 7 deletions testjson/summary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestPrintSummary_WithFailures(t *testing.T) {
Elapsed: 12 * time.Millisecond,
},
},
output: map[string][]string{
output: map[string]map[string][]string{
"TestFileDo": multiLine(`=== RUN TestFileDo
Some stdout/stderr here
--- FAIL: TestFailDo (1.41s)
Expand All @@ -98,7 +98,7 @@ Some stdout/stderr here
--- FAIL: TestFailDoError (0.01s)
do_test.go:50 assertion failed: expected nil error, got WHAT!
`),
"": {"FAIL\n"},
"": multiLine("FAIL\n"),
},
action: ActionFail,
},
Expand All @@ -118,7 +118,7 @@ Some stdout/stderr here
Elapsed: 0,
},
},
output: map[string][]string{
output: map[string]map[string][]string{
"TestAlbatross": multiLine(`=== RUN TestAlbatross
--- FAIL: TestAlbatross (0.04s)
`),
Expand All @@ -130,8 +130,8 @@ Some stdout/stderr here
},
"example.com/project/badmain": {
action: ActionFail,
output: map[string][]string{
"": {"sometimes main can exit 2\n"},
output: map[string]map[string][]string{
"": multiLine("sometimes main can exit 2\n"),
},
},
},
Expand Down Expand Up @@ -220,8 +220,10 @@ func patchClock() (clockwork.FakeClock, func()) {
return fake, func() { clock = clockwork.NewRealClock() }
}

func multiLine(s string) []string {
return strings.SplitAfter(s, "\n")
func multiLine(s string) map[string][]string {
return map[string][]string{
"": strings.SplitAfter(s, "\n"),
}
}

func TestPrintSummary_MissingTestFailEvent(t *testing.T) {
Expand Down

0 comments on commit 1233c41

Please sign in to comment.