dashboard: unify post-submit & trybot policy in builders.go, not coordinator
This removes a bunch of TODOs about scattered policy and moves it all
into builders.go.
While here,
* add a bunch of tests
* unexport some things
* rename some things
* document some things
* adjust FreeBSD policy as function of branch (per Go 1.12 being
last to support FreeBSD 10.x, and to unblock CL 165801)
* set GO_BUILDER_SET_GOPROXY=coordinator for reverse buildlets,
which is necessary to remove the oauth2 & build special cases
in the config
* change Elias Naur's mobile builder to how I think he wants it
(he was fighting the old system)
* add $HOME on the Solaris smartos builder, which was missing &
causing tests to fail lately
* make the (currently failing) longtest builder have GOPROXY set
* remove an allocation in version.ParseReleaseBranch
Fixes golang/go#9603
Updates golang/go#14594
Change-Id: I50a23ad7cdf478c95b14bee9b3931ba361baacfa
Reviewed-on: https://go-review.googlesource.com/c/build/+/166218
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/dashboard/builders_test.go b/dashboard/builders_test.go
index 555ffe6..ffea2d9 100644
--- a/dashboard/builders_test.go
+++ b/dashboard/builders_test.go
@@ -5,7 +5,7 @@
package dashboard
import (
- "reflect"
+ "fmt"
"strings"
"testing"
"time"
@@ -70,19 +70,289 @@
}
}
-func TestListTrybots(t *testing.T) {
- forProj := func(proj string) {
- t.Run(proj, func(t *testing.T) {
- tryBots := TryBuildersForProject(proj)
- t.Logf("Builders:")
- for _, conf := range tryBots {
- t.Logf(" - %s", conf.Name)
+// TestTrybots tests that a given repo & its branch yields the provided
+// complete set of builders. See also: TestBuilders, which tests both trybots
+// and post-submit builders, both at arbitrary branches.
+func TestTrybots(t *testing.T) {
+ tests := []struct {
+ repo string // "go", "net", etc
+ branch string // of repo
+ want []string
+ }{
+ {
+ repo: "go",
+ branch: "master",
+ want: []string{
+ "freebsd-amd64-12_0",
+ "js-wasm",
+ "linux-386",
+ "linux-amd64",
+ "linux-amd64-race",
+ "misc-compile",
+ "misc-compile-freebsd",
+ "misc-compile-mips",
+ "misc-compile-nacl",
+ "misc-compile-netbsd",
+ "misc-compile-openbsd",
+ "misc-compile-plan9",
+ "misc-compile-ppc",
+ "misc-vet-vetall",
+ "nacl-386",
+ "nacl-amd64p32",
+ "openbsd-amd64-64",
+ "windows-386-2008",
+ "windows-amd64-2016",
+ },
+ },
+ {
+ repo: "go",
+ branch: "release-branch.go1.12",
+ want: []string{
+ "freebsd-amd64-10_3",
+ "freebsd-amd64-12_0",
+ "js-wasm",
+ "linux-386",
+ "linux-amd64",
+ "linux-amd64-race",
+ "misc-compile",
+ "misc-compile-freebsd",
+ "misc-compile-mips",
+ "misc-compile-nacl",
+ "misc-compile-netbsd",
+ "misc-compile-openbsd",
+ "misc-compile-plan9",
+ "misc-compile-ppc",
+ "misc-vet-vetall",
+ "nacl-386",
+ "nacl-amd64p32",
+ "openbsd-amd64-64",
+ "windows-386-2008",
+ "windows-amd64-2016",
+ },
+ },
+ {
+ repo: "mobile",
+ branch: "master",
+ want: []string{
+ "android-amd64-emu",
+ "linux-amd64-androidemu",
+ },
+ },
+ {
+ repo: "sys",
+ branch: "master",
+ want: []string{
+ "freebsd-386-11_2",
+ "freebsd-amd64-11_2",
+ "freebsd-amd64-12_0",
+ "linux-386",
+ "linux-amd64",
+ "netbsd-amd64-8_0",
+ "openbsd-386-64",
+ "openbsd-amd64-64",
+ "windows-386-2008",
+ "windows-amd64-2016",
+ },
+ },
+ }
+ for i, tt := range tests {
+ if tt.branch == "" || tt.repo == "" {
+ t.Errorf("incomplete test entry %d", i)
+ return
+ }
+ t.Run(fmt.Sprintf("%s/%s", tt.repo, tt.branch), func(t *testing.T) {
+ var got []string
+ goBranch := tt.branch // hard-code the common case for now
+ for _, bc := range TryBuildersForProject(tt.repo, tt.branch, goBranch) {
+ got = append(got, bc.Name)
+ }
+ m := map[string]bool{}
+ for _, b := range tt.want {
+ m[b] = true
+ }
+ for _, b := range got {
+ if _, ok := m[b]; !ok {
+ t.Errorf("got unexpected %q", b)
+ }
+ delete(m, b)
+ }
+ for b := range m {
+ t.Errorf("missing expected %q", b)
}
})
}
- forProj("go")
- forProj("net")
- forProj("sys")
+}
+
+// TestBuilderConfig whether a given builder and repo at different
+// branches is either a post-submit builder, trybot, neither, or both.
+func TestBuilderConfig(t *testing.T) {
+ // builderConfigWant is bitmask of 4 different things to assert are wanted:
+ // - being a post-submit builder
+ // - NOT being a post-submit builder
+ // - being a trybot builder
+ // - NOT being a post-submit builder
+ type want uint8
+ const (
+ isTrybot want = 1 << iota
+ notTrybot
+ isBuilder // post-submit
+ notBuilder // not post-submit
+
+ none = notTrybot + notBuilder
+ both = isTrybot + isBuilder
+ onlyPost = notTrybot + isBuilder
+ )
+
+ type builderAndRepo struct {
+ testName string
+ builder string
+ repo string
+ branch string
+ goBranch string
+ }
+ // builder may end in "@go1.N" (as alias for "@release-branch.go1.N") or "@branch-name".
+ // repo may end in "@1.N" (as alias for "@release-branch.go1.N")
+ b := func(builder, repo string) builderAndRepo {
+ br := builderAndRepo{
+ testName: builder + "," + repo,
+ builder: builder,
+ goBranch: "master",
+ repo: repo,
+ branch: "master",
+ }
+ if strings.Contains(builder, "@") {
+ f := strings.SplitN(builder, "@", 2)
+ br.builder = f[0]
+ br.goBranch = f[1]
+ }
+ if strings.Contains(repo, "@") {
+ f := strings.SplitN(repo, "@", 2)
+ br.repo = f[0]
+ br.branch = f[1]
+ }
+ expandBranch := func(s *string) {
+ if strings.HasPrefix(*s, "go1.") {
+ *s = "release-branch." + *s
+ } else if strings.HasPrefix(*s, "1.") {
+ *s = "release-branch.go" + *s
+ }
+ }
+ expandBranch(&br.branch)
+ expandBranch(&br.goBranch)
+ if br.repo == "go" {
+ br.branch = br.goBranch
+ }
+ return br
+ }
+ tests := []struct {
+ br builderAndRepo
+ want want
+ }{
+ {b("linux-amd64", "go"), both},
+ {b("linux-amd64", "net"), both},
+ {b("linux-amd64", "sys"), both},
+
+ // The mobile repo requires Go 1.13+.
+ {b("android-amd64-emu", "go"), onlyPost},
+ {b("android-amd64-emu", "mobile"), both},
+ {b("android-amd64-emu", "mobile@1.10"), none},
+ {b("android-amd64-emu", "mobile@1.11"), none},
+ {b("android-amd64-emu@go1.10", "mobile"), none},
+ {b("android-amd64-emu@go1.11", "mobile"), none},
+ {b("android-amd64-emu@go1.12", "mobile"), none},
+ {b("android-amd64-emu@go1.13", "mobile"), both},
+ {b("android-amd64-emu", "mobile@1.13"), both},
+
+ {b("android-386-emu", "go"), onlyPost},
+ {b("android-386-emu", "mobile"), onlyPost},
+ {b("android-386-emu", "mobile@1.10"), none},
+ {b("android-386-emu", "mobile@1.11"), none},
+ {b("android-386-emu@go1.10", "mobile"), none},
+ {b("android-386-emu@go1.11", "mobile"), none},
+ {b("android-386-emu@go1.12", "mobile"), none},
+ {b("android-386-emu@go1.13", "mobile"), onlyPost},
+ {b("android-386-emu", "mobile@1.13"), onlyPost},
+
+ {b("linux-amd64", "net"), both},
+ {b("linux-amd64", "net@1.12"), both},
+ {b("linux-amd64@go1.12", "net@1.12"), both},
+ {b("linux-amd64", "net@1.11"), both},
+ {b("linux-amd64", "net@1.11"), both},
+ {b("linux-amd64", "net@1.10"), none}, // too old
+ {b("linux-amd64@go1.10", "net"), none}, // too old
+ {b("linux-amd64@go1.11", "net"), both},
+ {b("linux-amd64@go1.11", "net@1.11"), both},
+ {b("linux-amd64@go1.12", "net@1.12"), both},
+
+ // go1.12.html: "Go 1.12 is the last release that is
+ // supported on FreeBSD 10.x [... and 11.1]"
+ {b("freebsd-amd64-10_3", "go"), none},
+ {b("freebsd-amd64-10_3", "net"), none},
+ {b("freebsd-amd64-11_1", "go"), none},
+ {b("freebsd-amd64-11_1", "net"), none},
+ {b("freebsd-amd64-10_3@go1.12", "go"), both},
+ {b("freebsd-amd64-10_3@go1.12", "net@1.12"), both},
+ {b("freebsd-amd64-10_3@go1.11", "go"), both},
+ {b("freebsd-amd64-10_3@go1.11", "net@1.11"), both},
+ {b("freebsd-amd64-11_1@go1.13", "go"), none},
+ {b("freebsd-amd64-11_1@go1.13", "net@1.12"), none},
+ {b("freebsd-amd64-11_1@go1.12", "go"), isBuilder},
+ {b("freebsd-amd64-11_1@go1.12", "net@1.12"), isBuilder},
+ {b("freebsd-amd64-11_1@go1.11", "go"), isBuilder},
+ {b("freebsd-amd64-11_1@go1.11", "net@1.11"), isBuilder},
+
+ // The physical ARM Androids only runs "go":
+ // They run on GOOS=android mode which is not
+ // interesting for x/mobile. The interesting tests run
+ // on the darwin-amd64-wikofever below where
+ // GOOS=darwin.
+ {b("android-arm-wikofever", "go"), isBuilder},
+ {b("android-arm-wikofever", "mobile"), notBuilder},
+ {b("android-arm64-wikofever", "go"), isBuilder},
+ {b("android-arm64-wikofever", "mobile"), notBuilder},
+ {b("android-arm64-wikofever", "net"), notBuilder},
+
+ // A GOOS=darwin variant of the physical ARM Androids
+ // runs x/mobile and nothing else:
+ {b("darwin-amd64-wikofever", "mobile"), isBuilder},
+ {b("darwin-amd64-wikofever", "go"), notBuilder},
+ {b("darwin-amd64-wikofever", "net"), notBuilder},
+
+ // But the emulators run all:
+ {b("android-amd64-emu", "mobile"), isBuilder},
+ {b("android-386-emu", "mobile"), isBuilder},
+ {b("android-amd64-emu", "net"), isBuilder},
+ {b("android-386-emu", "net"), isBuilder},
+ {b("android-amd64-emu", "go"), isBuilder},
+ {b("android-386-emu", "go"), isBuilder},
+ }
+ for _, tt := range tests {
+ t.Run(tt.br.testName, func(t *testing.T) {
+ bc, ok := Builders[tt.br.builder]
+ if !ok {
+ t.Fatalf("unknown builder %q", tt.br.builder)
+ }
+ gotPost := bc.BuildsRepoPostSubmit(tt.br.repo, tt.br.branch, tt.br.goBranch)
+ if tt.want&isBuilder != 0 && !gotPost {
+ t.Errorf("not a post-submit builder, but expected")
+ }
+ if tt.want¬Builder != 0 && gotPost {
+ t.Errorf("unexpectedly a post-submit builder")
+ }
+
+ gotTry := bc.BuildsRepoTryBot(tt.br.repo, tt.br.branch, tt.br.goBranch)
+ if tt.want&isTrybot != 0 && !gotTry {
+ t.Errorf("not trybot, but expected")
+ }
+ if tt.want¬Trybot != 0 && gotTry {
+ t.Errorf("unexpectedly a trybot")
+ }
+
+ if t.Failed() {
+ t.Logf("For: %+v", tt.br)
+ }
+ })
+ }
}
func TestHostConfigsAllUsed(t *testing.T) {
@@ -99,77 +369,3 @@
}
}
}
-
-func TestSubrepoTrybots(t *testing.T) {
- bc := Builders["linux-amd64"]
-
- for _, tt := range []struct {
- repo, branch, goBranch string
- want bool
- }{
- {"mobile", "master", "release-branch.go1.10", false},
- {"mobile", "master", "release-branch.go1.11", false},
- {"mobile", "master", "release-branch.go1.12", false}, // requires Go 1.13+
- {"mobile", "master", "release-branch.go1.13", true},
- {"mobile", "master", "master", true},
-
- {"net", "master", "release-branch.go1.10", false}, // too old
- {"net", "master", "release-branch.go1.11", true},
- {"net", "master", "release-branch.go1.12", true},
- {"net", "master", "release-branch.go1.13", true},
- } {
- got := bc.BuildBranch(tt.repo, tt.branch, tt.goBranch)
- if got != tt.want {
- t.Errorf("BuildBranch(%q, %q, %q) = %v; want %v", tt.repo, tt.branch, tt.goBranch, got, tt.want)
- }
- }
-}
-
-func TestBuildConfigBuildRepo(t *testing.T) {
- tests := []struct {
- builder string
- repo string
- want bool
- }{
- // The physical ARM Androids only runs "go":
- {"android-arm-wikofever", "go", true},
- {"android-arm-wikofever", "mobile", false},
- {"android-arm64-wikofever", "mobile", false},
- {"android-arm64-wikofever", "net", false},
-
- // A GOOS=darwin variant of the physical ARM Androids
- // runs x/mobile and nothing else:
- {"darwin-amd64-wikofever", "mobile", true},
- {"darwin-amd64-wikofever", "go", false},
- {"darwin-amd64-wikofever", "net", false},
-
- // But the emulators run all:
- {"android-amd64-emu", "mobile", true},
- {"android-386-emu", "mobile", true},
- {"android-amd64-emu", "net", true},
- {"android-386-emu", "net", true},
- {"android-amd64-emu", "go", true},
- {"android-386-emu", "go", true},
- }
- for _, tt := range tests {
- bc, ok := Builders[tt.builder]
- if !ok {
- t.Fatalf("unknown builder %q", tt.builder)
- }
- got := bc.BuildRepo(tt.repo)
- if got != tt.want {
- t.Errorf("%s: BuildRepo(%q) = %v; want %v", tt.builder, tt.repo, got, tt.want)
- }
- }
-}
-
-func TestAndroidTrybots(t *testing.T) {
- var got []string
- for _, bc := range TryBuildersForProject("mobile") {
- got = append(got, bc.Name)
- }
- want := []string{"android-amd64-emu", "linux-amd64-androidemu"}
- if !reflect.DeepEqual(got, want) {
- t.Errorf(" got: %q\nwant: %q\n", got, want)
- }
-}