Skip to content

Commit

Permalink
Add a test for the rerun-fails where the last test passes
Browse files Browse the repository at this point in the history
  • Loading branch information
dnephin committed Sep 1, 2020
1 parent cd995f8 commit e1d4f60
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,5 @@ func exitCodeWithDefault(err error) int {
type exitCoder interface {
ExitCode() int
}

var _ exitCoder = &exec.ExitError{}
5 changes: 4 additions & 1 deletion rerunfails.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func rerunFailed(ctx context.Context, opts *options, scanConfig testjson.ScanCon

nextRec := newFailureRecorder(scanConfig.Handler)
for _, tc := range tcFilter(rec.failures) {
goTestProc, err := startGoTest(ctx, goTestCmdArgs(opts, newRerunOptsFromTestCase(tc)))
goTestProc, err := startGoTestFn(ctx, goTestCmdArgs(opts, newRerunOptsFromTestCase(tc)))
if err != nil {
return err
}
Expand All @@ -85,6 +85,9 @@ func rerunFailed(ctx context.Context, opts *options, scanConfig testjson.ScanCon
return lastErr
}

// startGoTestFn is a shim for testing
var startGoTestFn = startGoTest

func hasErrors(err error, exec *testjson.Execution) error {
switch {
case len(exec.Errors()) > 0:
Expand Down
112 changes: 112 additions & 0 deletions rerunfails_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package main

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"strings"
"testing"

"gotest.tools/gotestsum/testjson"
Expand Down Expand Up @@ -59,3 +62,112 @@ func TestGoTestRunFlagFromTestCases(t *testing.T) {
})
}
}

func TestRerunFailed_ReturnsAnErrorWhenTheLastTestIsSuccessful(t *testing.T) {
type result struct {
out string
err error
}
jsonFailed := `{"Package": "pkg", "Action": "run"}
{"Package": "pkg", "Test": "TestOne", "Action": "run"}
{"Package": "pkg", "Test": "TestOne", "Action": "fail"}
{"Package": "pkg", "Action": "fail"}
`
events := []result{
{out: jsonFailed, err: newExitCode("run-failed-1", 1)},
{out: jsonFailed, err: newExitCode("run-failed-2", 1)},
{out: jsonFailed, err: newExitCode("run-failed-3", 1)},
{
out: `{"Package": "pkg", "Action": "run"}
{"Package": "pkg", "Test": "TestOne", "Action": "run"}
{"Package": "pkg", "Test": "TestOne", "Action": "pass"}
{"Package": "pkg", "Action": "pass"}
`,
},
}

fn := func(args []string) proc {
next := events[0]
events = events[1:]
return proc{
cmd: fakeWaiter{result: next.err},
stdout: strings.NewReader(next.out),
stderr: bytes.NewReader(nil),
}
}
reset := patchStartGoTestFn(fn)
defer reset()

stdout := new(bytes.Buffer)
ctx := context.Background()
opts := &options{
rerunFailsMaxInitialFailures: 10,
rerunFailsMaxAttempts: 2,
stdout: stdout,
}
cfg := testjson.ScanConfig{
Execution: newExecutionWithTwoFailures(t),
Handler: noopHandler{},
}
err := rerunFailed(ctx, opts, cfg)
assert.Error(t, err, "run-failed-3")
}

func patchStartGoTestFn(f func(args []string) proc) func() {
orig := startGoTestFn
startGoTestFn = func(ctx context.Context, args []string) (proc, error) {
return f(args), nil
}
return func() {
startGoTestFn = orig
}
}

func newExecutionWithTwoFailures(t *testing.T) *testjson.Execution {
t.Helper()

out := `{"Package": "pkg", "Action": "run"}
{"Package": "pkg", "Test": "TestOne", "Action": "run"}
{"Package": "pkg", "Test": "TestOne", "Action": "fail"}
{"Package": "pkg", "Test": "TestTwo", "Action": "run"}
{"Package": "pkg", "Test": "TestTwo", "Action": "fail"}
{"Package": "pkg", "Action": "fail"}
`
exec, err := testjson.ScanTestOutput(testjson.ScanConfig{
Stdout: strings.NewReader(out),
Stderr: strings.NewReader(""),
})
assert.NilError(t, err)
return exec
}

type fakeWaiter struct {
result error
}

func (f fakeWaiter) Wait() error {
return f.result
}

type exitCodeError struct {
error
code int
}

func (e exitCodeError) ExitCode() int {
return e.code
}

func newExitCode(msg string, code int) error {
return exitCodeError{error: fmt.Errorf(msg), code: code}
}

type noopHandler struct{}

func (s noopHandler) Event(testjson.TestEvent, *testjson.Execution) error {
return nil
}

func (s noopHandler) Err(string) error {
return nil
}

0 comments on commit e1d4f60

Please sign in to comment.