From 55d43e1b59d083615051ba303dfe5fe820ebaee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20L=C3=B6nnblad?= Date: Sun, 24 May 2020 11:36:38 +0200 Subject: [PATCH] Made the builder tests run in parallel --- builder_go112_test.go | 59 +++----- builder_go113_test.go | 47 ++----- builder_go_module_test.go | 184 ++++++------------------ builder_test.go | 287 ++++++++++++++++---------------------- 4 files changed, 196 insertions(+), 381 deletions(-) diff --git a/builder_go112_test.go b/builder_go112_test.go index d1507b1..37275f4 100644 --- a/builder_go112_test.go +++ b/builder_go112_test.go @@ -4,57 +4,38 @@ package godog_test import ( - "bytes" "os" "path/filepath" "testing" + + "github.com/stretchr/testify/require" ) -func TestGodogBuildWithVendoredGodogAndMod(t *testing.T) { - gopath := filepath.Join(os.TempDir(), "_gpc") - dir := filepath.Join(gopath, "src", "godogs") - err := buildTestPackage(dir, map[string]string{ +func testWithVendoredGodogAndMod(t *testing.T) { + builderTC := builderTestCase{} + + gopath := filepath.Join(os.TempDir(), t.Name(), "_gpc") + defer os.RemoveAll(gopath) + + builderTC.dir = filepath.Join(gopath, "src", "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "godogs_test.go": builderTestFile, "go.mod": builderModFile, - }) - if err != nil { - os.RemoveAll(gopath) - t.Fatal(err) - } - defer os.RemoveAll(gopath) - - pkg := filepath.Join(dir, "vendor", "github.com", "cucumber") - if err := os.MkdirAll(pkg, 0755); err != nil { - t.Fatal(err) } - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) - } + pkg := filepath.Join(builderTC.dir, "vendor", "github.com", "cucumber") + err := os.MkdirAll(pkg, 0755) + require.Nil(t, err) + + wd, err := os.Getwd() + require.Nil(t, err) // symlink godog package - if err := os.Symlink(prevDir, filepath.Join(pkg, "godog")); err != nil { - t.Fatal(err) - } + err = os.Symlink(wd, filepath.Join(pkg, "godog")) + require.Nil(t, err) - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) - - cmd := buildTestCommand(t, "godogs.feature") - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = append(envVarsWithoutGopath(), "GOPATH="+gopath) - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.testCmdEnv = append(envVarsWithoutGopath(), "GOPATH="+gopath) + builderTC.run(t) } diff --git a/builder_go113_test.go b/builder_go113_test.go index 898e5dc..bdb5708 100644 --- a/builder_go113_test.go +++ b/builder_go113_test.go @@ -3,52 +3,29 @@ package godog_test import ( - "bytes" "os" "os/exec" "path/filepath" "testing" ) -func TestGodogBuildWithVendoredGodogAndMod(t *testing.T) { - gopath := filepath.Join(os.TempDir(), "_gpc") - dir := filepath.Join(gopath, "src", "godogs") - err := buildTestPackage(dir, map[string]string{ +func testWithVendoredGodogAndMod(t *testing.T) { + builderTC := builderTestCase{} + + gopath := filepath.Join(os.TempDir(), t.Name(), "_gpc") + defer os.RemoveAll(gopath) + + builderTC.dir = filepath.Join(gopath, "src", "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "godogs_test.go": builderTestFile, "go.mod": builderModFile, - }) - if err != nil { - os.RemoveAll(gopath) - t.Fatal(err) - } - defer os.RemoveAll(gopath) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err = exec.Command("go", "mod", "vendor").Run(); err != nil { - t.Fatal(err) - } + builderTC.goModCmds = make([]*exec.Cmd, 1) + builderTC.goModCmds[0] = exec.Command("go", "mod", "vendor") + builderTC.testCmdEnv = append(envVarsWithoutGopath(), "GOPATH="+gopath) - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) - - cmd := buildTestCommand(t, "godogs.feature") - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = append(envVarsWithoutGopath(), "GOPATH="+gopath) - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } diff --git a/builder_go_module_test.go b/builder_go_module_test.go index 7f2d07f..298538d 100644 --- a/builder_go_module_test.go +++ b/builder_go_module_test.go @@ -1,7 +1,6 @@ package godog_test import ( - "bytes" "fmt" "os" "os/exec" @@ -11,176 +10,73 @@ import ( "github.com/cucumber/godog" ) -func TestGodogBuildWithModuleOutsideGopathAndHavingOnlyFeature(t *testing.T) { - dir := filepath.Join(os.TempDir(), "godogs") - err := buildTestPackage(dir, map[string]string{ +func testOutsideGopathAndHavingOnlyFeature(t *testing.T) { + builderTC := builderTestCase{} + + builderTC.dir = filepath.Join(os.TempDir(), t.Name(), "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, - }) - if err != nil { - os.RemoveAll(dir) - t.Fatal(err) - } - defer os.RemoveAll(dir) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) + builderTC.goModCmds = make([]*exec.Cmd, 2) + builderTC.goModCmds[0] = exec.Command("go", "mod", "init", "godogs") - if out, err := exec.Command("go", "mod", "init", "godogs").CombinedOutput(); err != nil { - t.Log(string(out)) - t.Fatal(err) - } + godogDependency := fmt.Sprintf("github.com/cucumber/godog@%s", godog.Version) + builderTC.goModCmds[1] = exec.Command("go", "mod", "edit", "-require", godogDependency) - if out, err := exec.Command("go", "mod", "edit", "-require", fmt.Sprintf("github.com/cucumber/godog@%s", godog.Version)).CombinedOutput(); err != nil { - t.Log(string(out)) - t.Fatal(err) - } - - var stdout, stderr bytes.Buffer - cmd := buildTestCommand(t, "godogs.feature") - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = os.Environ() - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } -func TestGodogBuildWithModuleOutsideGopath(t *testing.T) { - dir := filepath.Join(os.TempDir(), "godogs") - err := buildTestPackage(dir, map[string]string{ +func testOutsideGopath(t *testing.T) { + builderTC := builderTestCase{} + + builderTC.dir = filepath.Join(os.TempDir(), t.Name(), "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "godogs_test.go": builderTestFile, - }) - if err != nil { - os.RemoveAll(dir) - t.Fatal(err) - } - defer os.RemoveAll(dir) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) + builderTC.goModCmds = make([]*exec.Cmd, 1) + builderTC.goModCmds[0] = exec.Command("go", "mod", "init", "godogs") - if out, err := exec.Command("go", "mod", "init", "godogs").CombinedOutput(); err != nil { - t.Log(string(out)) - t.Fatal(err) - } - - var stdout, stderr bytes.Buffer - cmd := buildTestCommand(t, "godogs.feature") - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = os.Environ() - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } -func TestGodogBuildWithModuleWithXTestOutsideGopath(t *testing.T) { - dir := filepath.Join(os.TempDir(), "godogs") - err := buildTestPackage(dir, map[string]string{ +func testOutsideGopathWithXTest(t *testing.T) { + builderTC := builderTestCase{} + + builderTC.dir = filepath.Join(os.TempDir(), t.Name(), "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "godogs_test.go": builderXTestFile, - }) - if err != nil { - os.RemoveAll(dir) - t.Fatal(err) - } - defer os.RemoveAll(dir) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) + builderTC.goModCmds = make([]*exec.Cmd, 1) + builderTC.goModCmds[0] = exec.Command("go", "mod", "init", "godogs") - if out, err := exec.Command("go", "mod", "init", "godogs").CombinedOutput(); err != nil { - t.Log(string(out)) - t.Fatal(err) - } - - var stdout, stderr bytes.Buffer - cmd := buildTestCommand(t, "godogs.feature") - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = os.Environ() - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } -func TestGodogBuildWithModuleInsideGopath(t *testing.T) { - gopath := filepath.Join(os.TempDir(), "_gp") - dir := filepath.Join(gopath, "src", "godogs") - err := buildTestPackage(dir, map[string]string{ +func testInsideGopath(t *testing.T) { + builderTC := builderTestCase{} + + gopath := filepath.Join(os.TempDir(), t.Name(), "_gp") + defer os.RemoveAll(gopath) + + builderTC.dir = filepath.Join(gopath, "src", "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "godogs_test.go": builderTestFile, - }) - if err != nil { - os.RemoveAll(gopath) - t.Fatal(err) - } - defer os.RemoveAll(gopath) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) + builderTC.goModCmds = make([]*exec.Cmd, 1) + builderTC.goModCmds[0] = exec.Command("go", "mod", "init", "godogs") + builderTC.goModCmds[0].Env = os.Environ() + builderTC.goModCmds[0].Env = append(builderTC.goModCmds[0].Env, "GOPATH="+gopath) + builderTC.goModCmds[0].Env = append(builderTC.goModCmds[0].Env, "GO111MODULE=on") - c := exec.Command("go", "mod", "init", "godogs") - c.Env = os.Environ() - c.Env = append(c.Env, "GOPATH="+gopath) - c.Env = append(c.Env, "GO111MODULE=on") - if out, err := c.CombinedOutput(); err != nil { - t.Log(string(out)) - t.Fatal(err) - } - - var stdout, stderr bytes.Buffer - cmd := buildTestCommand(t, "godogs.feature") - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "GOPATH="+gopath) - cmd.Env = append(cmd.Env, "GO111MODULE=on") - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } diff --git a/builder_test.go b/builder_test.go index f2ee3ee..c37dfb7 100644 --- a/builder_test.go +++ b/builder_test.go @@ -11,8 +11,27 @@ import ( "testing" "github.com/cucumber/godog" + "github.com/stretchr/testify/require" ) +func Test_GodogBuild(t *testing.T) { + t.Run("WithSourceNotInGoPath", testWithSourceNotInGoPath) + t.Run("WithoutSourceNotInGoPath", testWithoutSourceNotInGoPath) + t.Run("WithoutTestSourceNotInGoPath", testWithoutTestSourceNotInGoPath) + t.Run("WithinGopath", testWithinGopath) + t.Run("WithVendoredGodogWithoutModule", testWithVendoredGodogWithoutModule) + t.Run("WithVendoredGodogAndMod", testWithVendoredGodogAndMod) + + t.Run("WithModule", func(t *testing.T) { + t.Parallel() + + t.Run("OutsideGopathAndHavingOnlyFeature", testOutsideGopathAndHavingOnlyFeature) + t.Run("OutsideGopath", testOutsideGopath) + t.Run("OutsideGopathWithXTest", testOutsideGopathWithXTest) + t.Run("InsideGopath", testInsideGopath) + }) +} + var builderFeatureFile = `Feature: eat godogs In order to be happy As a hungry gopher @@ -131,232 +150,174 @@ func buildTestPackage(dir string, files map[string]string) error { return nil } -func buildTestCommand(t *testing.T, args ...string) *exec.Cmd { - bin, err := filepath.Abs("godog.test") - if err != nil { - t.Fatal(err) - } +func buildTestCommand(t *testing.T, wd, featureFile string) *exec.Cmd { + testBin := filepath.Join(wd, "godog.test") + testBin, err := filepath.Abs(testBin) + require.Nil(t, err) + if build.Default.GOOS == "windows" { - bin += ".exe" - } - if err = godog.Build(bin); err != nil { - t.Fatal(err) + testBin += ".exe" } - return exec.Command(bin, args...) + err = godog.Build(testBin) + require.Nil(t, err) + + featureFilePath := filepath.Join(wd, featureFile) + return exec.Command(testBin, featureFilePath) } func envVarsWithoutGopath() []string { var env []string + for _, def := range os.Environ() { if strings.Index(def, "GOPATH=") == 0 { continue } + env = append(env, def) } + return env } -func TestGodogBuildWithSourceNotInGoPath(t *testing.T) { - dir := filepath.Join(os.TempDir(), "godogs") - err := buildTestPackage(dir, map[string]string{ +func testWithSourceNotInGoPath(t *testing.T) { + dir := filepath.Join(os.TempDir(), t.Name(), "godogs") + files := map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "godogs_test.go": builderTestFile, "go.mod": builderModFile, - }) - if err != nil { - os.RemoveAll(dir) - t.Fatal(err) } + + err := buildTestPackage(dir, files) defer os.RemoveAll(dir) + require.Nil(t, err) prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) - } + require.Nil(t, err) - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } + err = os.Chdir(dir) + require.Nil(t, err) defer os.Chdir(prevDir) - cmd := buildTestCommand(t, "godogs.feature") + testCmd := buildTestCommand(t, "", "godogs.feature") + testCmd.Env = os.Environ() var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr + testCmd.Stdout = &stdout + testCmd.Stderr = &stderr - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + err = testCmd.Run() + require.Nil(t, err, "stdout:\n%s\nstderr:\n%s", stdout.String(), stderr.String()) } -func TestGodogBuildWithoutSourceNotInGoPath(t *testing.T) { - dir := filepath.Join(os.TempDir(), "godogs") - err := buildTestPackage(dir, map[string]string{ +func testWithoutSourceNotInGoPath(t *testing.T) { + builderTC := builderTestCase{} + + builderTC.dir = filepath.Join(os.TempDir(), t.Name(), "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "go.mod": builderModFile, - }) - if err != nil { - os.RemoveAll(dir) - t.Fatal(err) - } - defer os.RemoveAll(dir) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) - - cmd := buildTestCommand(t, "godogs.feature") - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } -func TestGodogBuildWithoutTestSourceNotInGoPath(t *testing.T) { - dir := filepath.Join(os.TempDir(), "godogs") - err := buildTestPackage(dir, map[string]string{ +func testWithoutTestSourceNotInGoPath(t *testing.T) { + builderTC := builderTestCase{} + + builderTC.dir = filepath.Join(os.TempDir(), t.Name(), "godogs") + builderTC.files = map[string]string{ "godogs.feature": builderFeatureFile, "godogs.go": builderMainCodeFile, "go.mod": builderModFile, - }) - if err != nil { - os.RemoveAll(dir) - t.Fatal(err) - } - defer os.RemoveAll(dir) - - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) - - cmd := buildTestCommand(t, "godogs.feature") - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.run(t) } -func TestGodogBuildWithinGopath(t *testing.T) { - gopath := filepath.Join(os.TempDir(), "_gp") - dir := filepath.Join(gopath, "src", "godogs") - err := buildTestPackage(dir, map[string]string{ - "godogs.feature": builderFeatureFile, - "godogs.go": builderMainCodeFile, - "godogs_test.go": builderTestFile, - "go.mod": builderModFile, - }) - if err != nil { - os.RemoveAll(gopath) - t.Fatal(err) - } +func testWithinGopath(t *testing.T) { + builderTC := builderTestCase{} + + gopath := filepath.Join(os.TempDir(), t.Name(), "_gp") defer os.RemoveAll(gopath) + builderTC.dir = filepath.Join(gopath, "src", "godogs") + builderTC.files = map[string]string{ + "godogs.feature": builderFeatureFile, + "godogs.go": builderMainCodeFile, + "godogs_test.go": builderTestFile, + "go.mod": builderModFile, + } + pkg := filepath.Join(gopath, "src", "github.com", "cucumber") - if err := os.MkdirAll(pkg, 0755); err != nil { - t.Fatal(err) - } + err := os.MkdirAll(pkg, 0755) + require.Nil(t, err) - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) - } + wd, err := os.Getwd() + require.Nil(t, err) // symlink godog package - if err := os.Symlink(prevDir, filepath.Join(pkg, "godog")); err != nil { - t.Fatal(err) - } + err = os.Symlink(wd, filepath.Join(pkg, "godog")) + require.Nil(t, err) - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) - - cmd := buildTestCommand(t, "godogs.feature") - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "GOPATH="+gopath) - - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + builderTC.testCmdEnv = []string{"GOPATH=" + gopath} + builderTC.run(t) } -func TestGodogBuildWithVendoredGodogWithoutModule(t *testing.T) { - gopath := filepath.Join(os.TempDir(), "_gp") - dir := filepath.Join(gopath, "src", "godogs") - err := buildTestPackage(dir, map[string]string{ - "godogs.feature": builderFeatureFile, - }) - if err != nil { - os.RemoveAll(gopath) - t.Fatal(err) - } +func testWithVendoredGodogWithoutModule(t *testing.T) { + builderTC := builderTestCase{} + + gopath := filepath.Join(os.TempDir(), t.Name(), "_gp") defer os.RemoveAll(gopath) - pkg := filepath.Join(dir, "vendor", "github.com", "cucumber") - if err := os.MkdirAll(pkg, 0755); err != nil { - t.Fatal(err) + builderTC.dir = filepath.Join(gopath, "src", "godogs") + builderTC.files = map[string]string{ + "godogs.feature": builderFeatureFile, } - prevDir, err := os.Getwd() - if err != nil { - t.Fatal(err) - } + pkg := filepath.Join(builderTC.dir, "vendor", "github.com", "cucumber") + err := os.MkdirAll(pkg, 0755) + require.Nil(t, err) + + wd, err := os.Getwd() + require.Nil(t, err) // symlink godog package - if err := os.Symlink(prevDir, filepath.Join(pkg, "godog")); err != nil { - t.Fatal(err) + err = os.Symlink(wd, filepath.Join(pkg, "godog")) + require.Nil(t, err) + + builderTC.testCmdEnv = append(envVarsWithoutGopath(), "GOPATH="+gopath) + builderTC.run(t) +} + +type builderTestCase struct { + dir string + files map[string]string + goModCmds []*exec.Cmd + testCmdEnv []string +} + +func (bt builderTestCase) run(t *testing.T) { + t.Parallel() + + err := buildTestPackage(bt.dir, bt.files) + defer os.RemoveAll(bt.dir) + require.Nil(t, err) + + for _, c := range bt.goModCmds { + c.Dir = bt.dir + out, err := c.CombinedOutput() + require.Nil(t, err, "%s", string(out)) } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - defer os.Chdir(prevDir) - - cmd := buildTestCommand(t, "godogs.feature") + testCmd := buildTestCommand(t, bt.dir, "godogs.feature") + testCmd.Env = append(os.Environ(), bt.testCmdEnv...) var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - cmd.Env = append(envVarsWithoutGopath(), "GOPATH="+gopath) + testCmd.Stdout = &stdout + testCmd.Stderr = &stderr - if err := cmd.Run(); err != nil { - t.Log(stdout.String()) - t.Log(stderr.String()) - t.Fatal(err) - } + err = testCmd.Run() + require.Nil(t, err, "stdout:\n%s\nstderr:\n%s", stdout.String(), stderr.String()) }