Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit fe88577

Browse files
authored
Merge pull request #378 from tro3/parallel_tests
Parallel capability for integration tests
2 parents f12b6b1 + 4811b1b commit fe88577

File tree

4 files changed

+160
-27
lines changed

4 files changed

+160
-27
lines changed

cmd/dep/integration_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,22 @@ func TestIntegration(t *testing.T) {
1919
test.NeedsGit(t)
2020

2121
filepath.Walk(filepath.Join("testdata", "harness_tests"), func(path string, info os.FileInfo, err error) error {
22+
wd, err := os.Getwd()
23+
if err != nil {
24+
panic(err)
25+
}
2226

2327
if filepath.Base(path) == "testcase.json" {
2428
parse := strings.Split(path, string(filepath.Separator))
2529
testName := strings.Join(parse[2:len(parse)-1], "/")
2630

2731
t.Run(testName, func(t *testing.T) {
32+
t.Parallel()
33+
2834
// Set up environment
29-
testCase := test.NewTestCase(t, testName)
35+
testCase := test.NewTestCase(t, testName, wd)
3036
defer testCase.Cleanup()
31-
testProj := test.NewTestProject(t, testCase.InitialPath())
37+
testProj := test.NewTestProject(t, testCase.InitialPath(), wd)
3238
defer testProj.Cleanup()
3339

3440
// Create and checkout the vendor revisions

cmd/dep/remove_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package main
66

77
import (
8+
"os"
89
"testing"
910

1011
"github.com/golang/dep/test"
@@ -15,9 +16,13 @@ func TestRemoveErrors(t *testing.T) {
1516
test.NeedsGit(t)
1617

1718
testName := "remove/unused/case1"
19+
wd, err := os.Getwd()
20+
if err != nil {
21+
panic(err)
22+
}
1823

19-
testCase := test.NewTestCase(t, testName)
20-
testProj := test.NewTestProject(t, testCase.InitialPath())
24+
testCase := test.NewTestCase(t, testName, wd)
25+
testProj := test.NewTestProject(t, testCase.InitialPath(), wd)
2126
defer testProj.Cleanup()
2227

2328
// Create and checkout the vendor revisions

test/integration_testcase.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ type IntegrationTestCase struct {
3232
VendorFinal []string `json:"vendor-final"`
3333
}
3434

35-
func NewTestCase(t *testing.T, name string) *IntegrationTestCase {
36-
wd, err := os.Getwd()
37-
if err != nil {
38-
panic(err)
39-
}
35+
func NewTestCase(t *testing.T, name, wd string) *IntegrationTestCase {
4036
rootPath := filepath.FromSlash(filepath.Join(wd, "testdata", "harness_tests", name))
4137
n := &IntegrationTestCase{
4238
t: t,

test/integration_testproj.go

Lines changed: 144 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55
package test
66

77
import (
8+
"bytes"
89
"io"
10+
"io/ioutil"
911
"os"
12+
"os/exec"
1013
"path/filepath"
14+
"runtime"
1115
"sort"
1216
"strings"
1317
"testing"
18+
19+
"github.com/pkg/errors"
1420
)
1521

1622
const (
@@ -23,41 +29,60 @@ type IntegrationTestProject struct {
2329
t *testing.T
2430
h *Helper
2531
preImports []string
32+
tempdir string
33+
env []string
34+
origWd string
35+
stdout bytes.Buffer
36+
stderr bytes.Buffer
2637
}
2738

28-
func NewTestProject(t *testing.T, initPath string) *IntegrationTestProject {
39+
func NewTestProject(t *testing.T, initPath, wd string) *IntegrationTestProject {
2940
new := &IntegrationTestProject{
30-
t: t,
31-
h: NewHelper(t),
41+
t: t,
42+
origWd: wd,
43+
env: os.Environ(),
3244
}
33-
new.TempDir(ProjectRoot)
45+
new.makeRootTempDir()
3446
new.TempDir(ProjectRoot, "vendor")
3547
new.CopyTree(initPath)
36-
new.h.Setenv("GOPATH", new.h.Path("."))
37-
new.h.Cd(new.Path(ProjectRoot))
48+
49+
// Note that the Travis darwin platform, directories with certain roots such
50+
// as /var are actually links to a dirtree under /private. Without the patch
51+
// below the wd, and therefore the GOPATH, is recorded as "/var/..." but the
52+
// actual process runs in "/private/var/..." and dies due to not being in the
53+
// GOPATH because the roots don't line up.
54+
if runtime.GOOS == "darwin" && needsPrivateLeader(new.tempdir) {
55+
new.Setenv("GOPATH", filepath.Join("/private", new.tempdir))
56+
} else {
57+
new.Setenv("GOPATH", new.tempdir)
58+
}
59+
3860
return new
3961
}
4062

4163
func (p *IntegrationTestProject) Cleanup() {
42-
p.h.Cleanup()
64+
os.RemoveAll(p.tempdir)
4365
}
4466

4567
func (p *IntegrationTestProject) Path(args ...string) string {
46-
return p.h.Path(filepath.Join(args...))
68+
return filepath.Join(p.tempdir, filepath.Join(args...))
4769
}
4870

49-
func (p *IntegrationTestProject) TempDir(args ...string) {
50-
p.h.TempDir(filepath.Join(args...))
71+
func (p *IntegrationTestProject) ProjPath(args ...string) string {
72+
localPath := append([]string{ProjectRoot}, args...)
73+
return p.Path(localPath...)
5174
}
5275

53-
func (p *IntegrationTestProject) TempProjDir(args ...string) {
54-
localPath := append([]string{ProjectRoot}, args...)
55-
p.h.TempDir(filepath.Join(localPath...))
76+
func (p *IntegrationTestProject) TempDir(args ...string) {
77+
fullPath := p.Path(args...)
78+
if err := os.MkdirAll(fullPath, 0755); err != nil && !os.IsExist(err) {
79+
p.t.Fatalf("%+v", errors.Errorf("Unable to create temp directory: %s", fullPath))
80+
}
5681
}
5782

58-
func (p *IntegrationTestProject) ProjPath(args ...string) string {
83+
func (p *IntegrationTestProject) TempProjDir(args ...string) {
5984
localPath := append([]string{ProjectRoot}, args...)
60-
return p.Path(localPath...)
85+
p.TempDir(localPath...)
6186
}
6287

6388
func (p *IntegrationTestProject) VendorPath(args ...string) string {
@@ -67,11 +92,51 @@ func (p *IntegrationTestProject) VendorPath(args ...string) string {
6792
}
6893

6994
func (p *IntegrationTestProject) RunGo(args ...string) {
70-
p.h.RunGo(args...)
95+
cmd := exec.Command("go", args...)
96+
p.stdout.Reset()
97+
p.stderr.Reset()
98+
cmd.Stdout = &p.stdout
99+
cmd.Stderr = &p.stderr
100+
cmd.Dir = p.tempdir
101+
cmd.Env = p.env
102+
status := cmd.Run()
103+
if p.stdout.Len() > 0 {
104+
p.t.Log("go standard output:")
105+
p.t.Log(p.stdout.String())
106+
}
107+
if p.stderr.Len() > 0 {
108+
p.t.Log("go standard error:")
109+
p.t.Log(p.stderr.String())
110+
}
111+
if status != nil {
112+
p.t.Logf("go %v failed unexpectedly: %v", args, status)
113+
p.t.FailNow()
114+
}
71115
}
72116

73117
func (p *IntegrationTestProject) RunGit(dir string, args ...string) {
74-
p.h.RunGit(dir, args...)
118+
cmd := exec.Command("git", args...)
119+
p.stdout.Reset()
120+
p.stderr.Reset()
121+
cmd.Stdout = &p.stdout
122+
cmd.Stderr = &p.stderr
123+
cmd.Dir = dir
124+
cmd.Env = p.env
125+
status := cmd.Run()
126+
if *PrintLogs {
127+
if p.stdout.Len() > 0 {
128+
p.t.Logf("git %v standard output:", args)
129+
p.t.Log(p.stdout.String())
130+
}
131+
if p.stderr.Len() > 0 {
132+
p.t.Logf("git %v standard error:", args)
133+
p.t.Log(p.stderr.String())
134+
}
135+
}
136+
if status != nil {
137+
p.t.Logf("git %v failed unexpectedly: %v", args, status)
138+
p.t.FailNow()
139+
}
75140
}
76141

77142
func (p *IntegrationTestProject) GetVendorGit(ip string) {
@@ -82,7 +147,32 @@ func (p *IntegrationTestProject) GetVendorGit(ip string) {
82147
}
83148

84149
func (p *IntegrationTestProject) DoRun(args []string) error {
85-
return p.h.DoRun(args)
150+
if *PrintLogs {
151+
p.t.Logf("running testdep %v", args)
152+
}
153+
var prog string
154+
prog = filepath.Join(p.origWd, "testdep"+ExeSuffix)
155+
newargs := []string{args[0], "-v"}
156+
newargs = append(newargs, args[1:]...)
157+
cmd := exec.Command(prog, newargs...)
158+
p.stdout.Reset()
159+
p.stderr.Reset()
160+
cmd.Stdout = &p.stdout
161+
cmd.Stderr = &p.stderr
162+
cmd.Env = p.env
163+
cmd.Dir = p.ProjPath("")
164+
status := cmd.Run()
165+
if *PrintLogs {
166+
if p.stdout.Len() > 0 {
167+
p.t.Log("standard output:")
168+
p.t.Log(p.stdout.String())
169+
}
170+
if p.stderr.Len() > 0 {
171+
p.t.Log("standard error:")
172+
p.t.Log(p.stderr.String())
173+
}
174+
}
175+
return status
86176
}
87177

88178
func (p *IntegrationTestProject) CopyTree(src string) {
@@ -159,6 +249,7 @@ func (p *IntegrationTestProject) GetImportPaths() []string {
159249
return result
160250
}
161251

252+
// Take a snapshot of the import paths before test is run
162253
func (p *IntegrationTestProject) RecordImportPaths() {
163254
p.preImports = p.GetImportPaths()
164255
}
@@ -176,3 +267,38 @@ func (p *IntegrationTestProject) CompareImportPaths() {
176267
}
177268
}
178269
}
270+
271+
// makeRootTempdir makes a temporary directory for a run of testgo. If
272+
// the temporary directory was already created, this does nothing.
273+
func (p *IntegrationTestProject) makeRootTempDir() {
274+
if p.tempdir == "" {
275+
var err error
276+
p.tempdir, err = ioutil.TempDir("", "gotest")
277+
p.Must(err)
278+
}
279+
}
280+
281+
// Setenv sets an environment variable to use when running the test go
282+
// command.
283+
func (p *IntegrationTestProject) Setenv(name, val string) {
284+
p.env = append(p.env, name+"="+val)
285+
}
286+
287+
// Must gives a fatal error if err is not nil.
288+
func (p *IntegrationTestProject) Must(err error) {
289+
if err != nil {
290+
p.t.Fatalf("%+v", err)
291+
}
292+
}
293+
294+
// Checks for filepath beginnings that result in the "/private" leader
295+
// on Mac platforms
296+
func needsPrivateLeader(path string) bool {
297+
var roots = []string{"/var", "/tmp", "/etc"}
298+
for _, root := range roots {
299+
if strings.HasPrefix(path, root) {
300+
return true
301+
}
302+
}
303+
return false
304+
}

0 commit comments

Comments
 (0)