cmd/coordinator: install x/tools in $GOPATH for misc-vetall builder
This change is required for Alan's vet refactor and change to how
vetall works in CL 149097.
Change-Id: Ia7864c1b2430c696a457d3f0de2820b9037d78ab
Reviewed-on: https://go-review.googlesource.com/c/149658
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index 65aa6ce..7bb9774 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -2218,11 +2218,26 @@
return false
}
-func (st *buildStatus) newTestSet(names []string, benchmarks []*buildgo.BenchmarkItem) *testSet {
+// newTestSet returns a new testSet given the dist test names (strings from "go tool dist test -list")
+// and benchmark items.
+func (st *buildStatus) newTestSet(distTestNames []string, benchmarks []*buildgo.BenchmarkItem) (*testSet, error) {
set := &testSet{
- st: st,
+ st: st,
+ needsXRepo: map[string]string{},
}
- for _, name := range names {
+ for _, name := range distTestNames {
+ // The misc-vetall builder's "vet/*" tests are special: they require golang.org/x/tools
+ // in $GOPATH. So figure out the latest master HEAD git rev for x/tools so we can
+ // populate it later across all sharded builders at the same revision.
+ if strings.HasPrefix(name, "vet/") && set.needsXRepo["tools"] == "" {
+ // TODO: we'll probably need to make this handle branches later. Or maybe we
+ // should just disable misc-vetall on non-master branches.
+ rev, err := getRepoHead("tools")
+ if err != nil {
+ return nil, fmt.Errorf("failed to get master git rev for x/tools: %v", err)
+ }
+ set.needsXRepo["tools"] = rev
+ }
set.items = append(set.items, &testItem{
set: set,
name: name,
@@ -2242,7 +2257,7 @@
done: make(chan token),
})
}
- return set
+ return set, nil
}
func partitionGoTests(builderName string, tests []string) (sets [][]string) {
@@ -2712,11 +2727,10 @@
defer func() { sp.Done(err) }()
return st.bc.Exec(path.Join("go", "bin", "go"), buildlet.ExecOpts{
Output: st,
- // TODO(adg): remove vendor experiment variable after Go 1.6
ExtraEnv: append(st.conf.Env(),
"GOROOT="+goroot,
"GOPATH="+gopath,
- "GO15VENDOREXPERIMENT=1"),
+ ),
Path: []string{"$WORKDIR/go/bin", "$PATH"},
Args: []string{"test", "-short", subrepoPrefix + st.SubName + "/..."},
})
@@ -2775,7 +2789,10 @@
benches = b
}
}
- set := st.newTestSet(testNames, benches)
+ set, err := st.newTestSet(testNames, benches)
+ if err != nil {
+ return nil, err
+ }
st.LogEventTime("starting_tests", fmt.Sprintf("%d tests", len(set.items)))
startTime := time.Now()
@@ -2783,7 +2800,12 @@
if err != nil {
return nil, fmt.Errorf("error discovering workdir for main buildlet, %s: %v", st.bc.Name(), err)
}
+ if err := set.fetchGOPATHDeps(st, st.bc); err != nil {
+ return nil, err
+ }
+
mainBuildletGoroot := st.conf.FilePathJoin(workDir, "go")
+ mainBuildletGopath := st.conf.FilePathJoin(workDir, "gopath")
// We use our original buildlet to run the tests in order, to
// make the streaming somewhat smooth and not incredibly
@@ -2805,7 +2827,7 @@
}
continue
}
- st.runTestsOnBuildlet(st.bc, tis, mainBuildletGoroot)
+ st.runTestsOnBuildlet(st.bc, tis, mainBuildletGoroot, mainBuildletGopath)
}
st.LogEventTime("main_buildlet_broken", st.bc.Name())
}()
@@ -2831,15 +2853,20 @@
log.Printf("error discovering workdir for helper %s: %v", bc.Name(), err)
return
}
+ if err := set.fetchGOPATHDeps(st, bc); err != nil {
+ log.Printf("error populating GOPATH for helper %s: %v", bc.Name(), err)
+ return
+ }
st.LogEventTime("test_helper_set_up", bc.Name())
goroot := st.conf.FilePathJoin(workDir, "go")
+ gopath := st.conf.FilePathJoin(workDir, "gopath")
for !bc.IsBroken() {
tis, ok := set.testsToRunBiggestFirst()
if !ok {
st.LogEventTime("no_new_tests_remain", bc.Name())
return
}
- st.runTestsOnBuildlet(bc, tis, goroot)
+ st.runTestsOnBuildlet(bc, tis, goroot, gopath)
}
st.LogEventTime("test_helper_is_broken", bc.Name())
}(helper)
@@ -3017,8 +3044,8 @@
return 20 * time.Minute
}
-// runTestsOnBuildlet runs tis on bc, using the optional goroot environment variable.
-func (st *buildStatus) runTestsOnBuildlet(bc *buildlet.Client, tis []*testItem, goroot string) {
+// runTestsOnBuildlet runs tis on bc, using the optional goroot & gopath environment variables.
+func (st *buildStatus) runTestsOnBuildlet(bc *buildlet.Client, tis []*testItem, goroot, gopath string) {
names := make([]string, len(tis))
for i, ti := range tis {
names[i] = ti.name
@@ -3063,12 +3090,15 @@
// fail when dist tries to run the binary in dir "$GOROOT/src", since
// "$GOROOT/src" + "./go.exe" doesn't exist. Perhaps LookPath should return
// an absolute path.
- Dir: ".",
- Output: &buf, // see "maybe stream lines" TODO below
- ExtraEnv: append(st.conf.Env(), "GOROOT="+goroot),
- Timeout: timeout,
- Path: []string{"$WORKDIR/go/bin", "$PATH"},
- Args: args,
+ Dir: ".",
+ Output: &buf, // see "maybe stream lines" TODO below
+ ExtraEnv: append(st.conf.Env(),
+ "GOROOT="+goroot,
+ "GOPATH="+gopath,
+ ),
+ Timeout: timeout,
+ Path: []string{"$WORKDIR/go/bin", "$PATH"},
+ Args: args,
})
}
execDuration := time.Since(t0)
@@ -3116,11 +3146,24 @@
st *buildStatus
items []*testItem
+ // needsXRepo is the set of x/$REPO repos needed in $GOPATH
+ // and which git rev that repo should be fetched at.
+ needsXRepo map[string]string // "net" => "88d92db4c548972d942ac2a3531a8a9a34c82ca6"
+
mu sync.Mutex
inOrder [][]*testItem
biggestFirst [][]*testItem
}
+func (s *testSet) fetchGOPATHDeps(sl spanlog.Logger, bc *buildlet.Client) error {
+ for repo, rev := range s.needsXRepo {
+ if err := buildgo.FetchSubrepo(sl, bc, repo, rev); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
// cancelAll cancels all pending tests.
func (s *testSet) cancelAll() {
for _, ti := range s.items {