зеркало из https://github.com/golang/build.git
1179 строки
35 KiB
Go
1179 строки
35 KiB
Go
// Copyright 2015 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package dashboard
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"golang.org/x/build/internal/migration"
|
|
)
|
|
|
|
func TestOSARCHAccessors(t *testing.T) {
|
|
valid := func(s string) bool { return s != "" && !strings.Contains(s, "-") }
|
|
for _, conf := range Builders {
|
|
os := conf.GOOS()
|
|
arch := conf.GOARCH()
|
|
osArch := os + "-" + arch
|
|
if !valid(os) || !valid(arch) || !(conf.Name == osArch || strings.HasPrefix(conf.Name, osArch+"-")) {
|
|
t.Errorf("OS+ARCH(%q) = %q, %q; invalid", conf.Name, os, arch)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDistTestsExecTimeout(t *testing.T) {
|
|
tests := []struct {
|
|
c *BuildConfig
|
|
want time.Duration
|
|
}{
|
|
{
|
|
&BuildConfig{
|
|
env: []string{},
|
|
TestHostConf: &HostConfig{},
|
|
},
|
|
20 * time.Minute,
|
|
},
|
|
{
|
|
&BuildConfig{
|
|
env: []string{"GO_TEST_TIMEOUT_SCALE=2"},
|
|
TestHostConf: &HostConfig{},
|
|
},
|
|
40 * time.Minute,
|
|
},
|
|
{
|
|
&BuildConfig{
|
|
env: []string{},
|
|
TestHostConf: &HostConfig{
|
|
env: []string{"GO_TEST_TIMEOUT_SCALE=3"},
|
|
},
|
|
},
|
|
60 * time.Minute,
|
|
},
|
|
// BuildConfig's env takes precedence:
|
|
{
|
|
&BuildConfig{
|
|
env: []string{"GO_TEST_TIMEOUT_SCALE=2"},
|
|
TestHostConf: &HostConfig{
|
|
env: []string{"GO_TEST_TIMEOUT_SCALE=3"},
|
|
},
|
|
},
|
|
40 * time.Minute,
|
|
},
|
|
}
|
|
for i, tt := range tests {
|
|
got := tt.c.DistTestsExecTimeout(nil)
|
|
if got != tt.want {
|
|
t.Errorf("%d. got %v; want %v", i, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestTrybots tests that a given repo & its branch yields the provided complete
|
|
// set of builders. See also: TestPostSubmit, which tests only post-submit
|
|
// builders, and TestBuilderConfig, 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_3",
|
|
// Stopped.
|
|
//"linux-386",
|
|
//"linux-amd64",
|
|
//"linux-amd64-boringcrypto",
|
|
//"linux-amd64-newinliner",
|
|
//"linux-amd64-race",
|
|
//"linux-arm64",
|
|
//"openbsd-amd64-72",
|
|
//"windows-386-2016",
|
|
//"windows-amd64-2016",
|
|
},
|
|
},
|
|
{
|
|
repo: "go",
|
|
branch: "release-branch.go1.22",
|
|
want: []string{
|
|
"freebsd-amd64-12_3",
|
|
// Stopped.
|
|
//"linux-386",
|
|
//"linux-amd64",
|
|
//"linux-amd64-boringcrypto",
|
|
//"linux-amd64-race",
|
|
//"linux-arm64",
|
|
//"openbsd-amd64-72",
|
|
//"windows-386-2016",
|
|
//"windows-amd64-2016",
|
|
|
|
// Include longtest builders on Go repo release branches. See issue 37827.
|
|
// Stopped.
|
|
//"linux-386-longtest",
|
|
//"linux-amd64-longtest",
|
|
//"linux-arm64-longtest",
|
|
//"windows-amd64-longtest",
|
|
},
|
|
},
|
|
{
|
|
repo: "go",
|
|
branch: "release-branch.go1.21",
|
|
want: []string{
|
|
"freebsd-amd64-12_3",
|
|
// Stopped.
|
|
//"linux-386",
|
|
//"linux-amd64",
|
|
//"linux-amd64-boringcrypto",
|
|
//"linux-amd64-race",
|
|
//"linux-arm64",
|
|
//"openbsd-amd64-72",
|
|
//"windows-386-2016",
|
|
//"windows-amd64-2016",
|
|
|
|
// Include longtest builders on Go repo release branches. See issue 37827.
|
|
// Stopped.
|
|
//"linux-386-longtest",
|
|
//"linux-amd64-longtest",
|
|
//"linux-arm64-longtest",
|
|
//"windows-amd64-longtest",
|
|
},
|
|
},
|
|
{
|
|
repo: "mobile",
|
|
branch: "master",
|
|
want: []string{
|
|
"android-amd64-emu",
|
|
"linux-amd64-androidemu",
|
|
// Stopped.
|
|
//"linux-amd64",
|
|
//"linux-amd64-race",
|
|
},
|
|
},
|
|
{
|
|
repo: "sys",
|
|
branch: "master",
|
|
want: []string{
|
|
"freebsd-386-13_0",
|
|
"freebsd-amd64-12_3",
|
|
"freebsd-amd64-13_0",
|
|
// Stopped.
|
|
//"linux-386",
|
|
//"linux-amd64",
|
|
//"linux-amd64-boringcrypto", // GoDeps will exclude, but not in test
|
|
//"linux-amd64-race",
|
|
//"linux-arm64",
|
|
"netbsd-amd64-9_3",
|
|
"openbsd-386-72",
|
|
// Stopped.
|
|
//"openbsd-amd64-72",
|
|
//"windows-386-2016",
|
|
//"windows-amd64-2016",
|
|
},
|
|
},
|
|
{
|
|
repo: "exp",
|
|
branch: "master",
|
|
want: []string{
|
|
// Stopped.
|
|
//"linux-amd64",
|
|
//"linux-amd64-race",
|
|
//"windows-amd64-2016",
|
|
},
|
|
},
|
|
{
|
|
repo: "vulndb",
|
|
branch: "master",
|
|
want: []string{
|
|
// Stopped.
|
|
//"linux-amd64",
|
|
//"linux-amd64-race",
|
|
},
|
|
},
|
|
{
|
|
repo: "website",
|
|
branch: "master",
|
|
want: []string{
|
|
// Stopped.
|
|
//"linux-amd64",
|
|
//"linux-amd64-race",
|
|
},
|
|
},
|
|
}
|
|
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) {
|
|
goBranch := tt.branch // hard-code the common case for now
|
|
got := TryBuildersForProject(tt.repo, tt.branch, goBranch)
|
|
checkBuildersForProject(t, got, tt.want)
|
|
})
|
|
}
|
|
}
|
|
|
|
func checkBuildersForProject(t *testing.T, gotBuilders []*BuildConfig, want []string) {
|
|
t.Helper()
|
|
|
|
var got []string
|
|
for _, bc := range gotBuilders {
|
|
got = append(got, bc.Name)
|
|
}
|
|
m := map[string]bool{}
|
|
for _, b := range 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)
|
|
}
|
|
}
|
|
|
|
// TestPostSubmit tests that a given repo & its branch yields the provided
|
|
// complete set of post-submit builders. See also: TestTrybots, which tests only
|
|
// trybots, and TestBuilderConfig, which tests both trybots and post-submit
|
|
// builders, both at arbitrary branches.
|
|
func TestPostSubmit(t *testing.T) {
|
|
tests := []struct {
|
|
repo string // "go", "net", etc
|
|
branch string // of repo
|
|
want []string
|
|
}{
|
|
{
|
|
repo: "vulndb",
|
|
branch: "master",
|
|
want: []string{
|
|
// Stopped.
|
|
//"linux-amd64",
|
|
//"linux-amd64-longtest",
|
|
//"linux-amd64-race",
|
|
//"linux-amd64-longtest-race",
|
|
},
|
|
},
|
|
{
|
|
repo: "website",
|
|
branch: "master",
|
|
want: []string{
|
|
// Stopped.
|
|
//"linux-amd64",
|
|
//"linux-amd64-longtest",
|
|
//"linux-amd64-race",
|
|
//"linux-amd64-longtest-race",
|
|
},
|
|
},
|
|
}
|
|
for i, tt := range tests {
|
|
if tt.branch == "" || tt.repo == "" {
|
|
t.Fatalf("incomplete test entry %d", i)
|
|
}
|
|
t.Run(fmt.Sprintf("%s/%s", tt.repo, tt.branch), func(t *testing.T) {
|
|
goBranch := tt.branch // hard-code the common case for now
|
|
got := buildersForProject(tt.repo, tt.branch, goBranch, (*BuildConfig).BuildsRepoPostSubmit)
|
|
checkBuildersForProject(t, got, tt.want)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestBuilderConfig tests whether a given builder and repo at different branches is
|
|
// completely disabled ("none"),
|
|
// a TryBot and a post-submit builder ("both"), or
|
|
// a post-submit only builder ("onlyPost").
|
|
func TestBuilderConfig(t *testing.T) {
|
|
// want is a 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
|
|
// Note: a builder cannot be configured as a TryBot without also being a post-submit builder.
|
|
type want uint8
|
|
const (
|
|
isTrybot want = 1 << iota
|
|
notTrybot
|
|
isBuilder // post-submit
|
|
notBuilder // not post-submit
|
|
|
|
// Available combinations:
|
|
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" or "@1.N" (as alias for "@release-branch.go1.N") or "@branch-name".
|
|
// repo (other than "go") may end in "@go1.N" or "@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]
|
|
if br.repo == "go" {
|
|
panic(fmt.Errorf(`b(%q, %q): for "go" repo, must use the @%s suffix on the builder, not on the repo`, builder, repo, br.branch))
|
|
}
|
|
}
|
|
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 // none, both, or onlyPost.
|
|
}{
|
|
{b("linux-amd64", "go"), both},
|
|
{b("linux-amd64", "net"), both},
|
|
{b("linux-amd64", "sys"), both},
|
|
{b("linux-amd64", "website"), both},
|
|
|
|
// Don't test all subrepos on all the builders.
|
|
{b("linux-amd64-ssacheck", "net"), none},
|
|
{b("linux-amd64-ssacheck@go1.99", "net"), none},
|
|
{b("linux-386-softfloat", "crypto"), onlyPost},
|
|
{b("linux-386-softfloat@go1.99", "crypto"), onlyPost},
|
|
|
|
{b("android-amd64-emu", "go"), onlyPost},
|
|
{b("android-amd64-emu", "mobile"), both},
|
|
{b("android-amd64-emu", "crypto"), onlyPost},
|
|
{b("android-amd64-emu", "net"), onlyPost},
|
|
{b("android-amd64-emu", "sync"), onlyPost},
|
|
{b("android-amd64-emu", "sys"), onlyPost},
|
|
{b("android-amd64-emu", "text"), onlyPost},
|
|
{b("android-amd64-emu", "time"), onlyPost},
|
|
{b("android-amd64-emu", "tools"), onlyPost},
|
|
{b("android-amd64-emu", "website"), none},
|
|
|
|
{b("android-386-emu", "go"), onlyPost},
|
|
{b("android-386-emu", "mobile"), onlyPost},
|
|
{b("android-386-emu", "crypto"), onlyPost},
|
|
|
|
{b("linux-amd64", "net"), both},
|
|
|
|
// Builders for linux/loong64 are fully ported to LUCI and stopped in the coordinator.
|
|
{b("linux-loong64-3a5000", "go"), none},
|
|
{b("linux-loong64-3a5000@go1.99", "go"), none},
|
|
{b("linux-loong64-3a5000", "sys"), none},
|
|
{b("linux-loong64-3a5000@go1.99", "sys"), none},
|
|
{b("linux-loong64-3a5000", "net"), none},
|
|
|
|
// OpenBSD 7.2.
|
|
{b("openbsd-amd64-72", "go"), both},
|
|
{b("openbsd-amd64-72@go1.99", "go"), both},
|
|
|
|
// FreeBSD 13.0
|
|
{b("freebsd-amd64-13_0", "go"), onlyPost},
|
|
{b("freebsd-amd64-13_0", "net"), onlyPost},
|
|
{b("freebsd-amd64-13_0", "mobile"), none},
|
|
{b("freebsd-386-13_0", "go"), onlyPost},
|
|
{b("freebsd-386-13_0", "net"), onlyPost},
|
|
{b("freebsd-386-13_0", "mobile"), none},
|
|
|
|
// FreeBSD 12.3
|
|
{b("freebsd-amd64-12_3", "go"), both},
|
|
{b("freebsd-amd64-12_3", "net"), both},
|
|
{b("freebsd-amd64-12_3", "mobile"), none},
|
|
{b("freebsd-386-12_3", "go"), onlyPost},
|
|
{b("freebsd-386-12_3", "net"), onlyPost},
|
|
{b("freebsd-386-12_3", "mobile"), none},
|
|
|
|
// NetBSD
|
|
{b("netbsd-amd64-9_3", "go"), onlyPost},
|
|
{b("netbsd-amd64-9_3", "net"), onlyPost},
|
|
{b("netbsd-amd64-9_3", "sys"), both},
|
|
{b("netbsd-386-9_3", "go"), onlyPost},
|
|
{b("netbsd-386-9_3", "net"), onlyPost},
|
|
|
|
// AIX
|
|
{b("aix-ppc64", "go"), onlyPost},
|
|
{b("aix-ppc64", "net"), onlyPost},
|
|
{b("aix-ppc64", "mobile"), none},
|
|
{b("aix-ppc64", "exp"), none},
|
|
{b("aix-ppc64", "term"), onlyPost},
|
|
|
|
{b("linux-amd64-nocgo", "mobile"), none},
|
|
|
|
// Virtual mobiledevices
|
|
{b("ios-arm64-corellium", "go"), onlyPost},
|
|
{b("android-arm64-corellium", "go"), onlyPost},
|
|
{b("android-arm-corellium", "go"), onlyPost},
|
|
|
|
// Mobile builders that run with GOOS=linux/ios and have
|
|
// a device attached.
|
|
{b("linux-amd64-androidemu", "mobile"), both},
|
|
|
|
// The Android emulator builders can test all repos.
|
|
{b("android-amd64-emu", "mobile"), both},
|
|
{b("android-386-emu", "mobile"), onlyPost},
|
|
{b("android-amd64-emu", "net"), onlyPost},
|
|
{b("android-386-emu", "net"), onlyPost},
|
|
{b("android-amd64-emu", "go"), onlyPost},
|
|
{b("android-386-emu", "go"), onlyPost},
|
|
|
|
// Builders for js/wasm are fully ported to LUCI and stopped in the coordinator.
|
|
{b("js-wasm-node18", "go"), none},
|
|
{b("js-wasm-node18@go1.21", "go"), none},
|
|
{b("js-wasm-node18@go1.20", "go"), none},
|
|
{b("js-wasm-node18", "arch"), none},
|
|
{b("js-wasm-node18", "crypto"), none},
|
|
{b("js-wasm-node18", "sys"), none},
|
|
{b("js-wasm-node18", "net"), none},
|
|
{b("js-wasm-node18", "benchmarks"), none},
|
|
{b("js-wasm-node18", "debug"), none},
|
|
{b("js-wasm-node18", "mobile"), none},
|
|
{b("js-wasm-node18", "perf"), none},
|
|
{b("js-wasm-node18", "talks"), none},
|
|
{b("js-wasm-node18", "tools"), none},
|
|
{b("js-wasm-node18", "tour"), none},
|
|
{b("js-wasm-node18", "website"), none},
|
|
|
|
// Builders for wasip1-wasm are fully ported to LUCI and stopped in the coordinator.
|
|
{b("wasip1-wasm-wazero", "go"), none},
|
|
{b("wasip1-wasm-wazero@go1.21", "go"), none},
|
|
{b("wasip1-wasm-wazero@go1.20", "go"), none},
|
|
{b("wasip1-wasm-wasmtime", "go"), none},
|
|
{b("wasip1-wasm-wasmtime@go1.21", "go"), none},
|
|
{b("wasip1-wasm-wasmtime@go1.20", "go"), none},
|
|
{b("wasip1-wasm-wasmer", "go"), none},
|
|
{b("wasip1-wasm-wasmer@go1.21", "go"), none},
|
|
{b("wasip1-wasm-wasmer@go1.20", "go"), none},
|
|
{b("wasip1-wasm-wasmedge", "go"), none},
|
|
{b("wasip1-wasm-wasmedge@go1.21", "go"), none},
|
|
{b("wasip1-wasm-wasmedge@go1.20", "go"), none},
|
|
{b("wasip1-wasm-wazero", "arch"), none},
|
|
{b("wasip1-wasm-wazero", "crypto"), none},
|
|
{b("wasip1-wasm-wazero", "sys"), none},
|
|
{b("wasip1-wasm-wazero", "net"), none},
|
|
{b("wasip1-wasm-wazero", "benchmarks"), none},
|
|
{b("wasip1-wasm-wazero", "debug"), none},
|
|
{b("wasip1-wasm-wazero", "mobile"), none},
|
|
{b("wasip1-wasm-wazero", "perf"), none},
|
|
{b("wasip1-wasm-wazero", "talks"), none},
|
|
{b("wasip1-wasm-wazero", "tools"), none},
|
|
{b("wasip1-wasm-wazero", "tour"), none},
|
|
{b("wasip1-wasm-wazero", "website"), none},
|
|
{b("wasip1-wasm-wasmtime", "arch"), none},
|
|
{b("wasip1-wasm-wasmtime", "crypto"), none},
|
|
{b("wasip1-wasm-wasmtime", "sys"), none},
|
|
{b("wasip1-wasm-wasmtime", "net"), none},
|
|
{b("wasip1-wasm-wasmtime", "benchmarks"), none},
|
|
{b("wasip1-wasm-wasmtime", "debug"), none},
|
|
{b("wasip1-wasm-wasmtime", "mobile"), none},
|
|
{b("wasip1-wasm-wasmtime", "perf"), none},
|
|
{b("wasip1-wasm-wasmtime", "talks"), none},
|
|
{b("wasip1-wasm-wasmtime", "tools"), none},
|
|
{b("wasip1-wasm-wasmtime", "tour"), none},
|
|
{b("wasip1-wasm-wasmtime", "website"), none},
|
|
{b("wasip1-wasm-wasmer", "arch"), none},
|
|
{b("wasip1-wasm-wasmer", "crypto"), none},
|
|
{b("wasip1-wasm-wasmer", "sys"), none},
|
|
{b("wasip1-wasm-wasmer", "net"), none},
|
|
{b("wasip1-wasm-wasmer", "benchmarks"), none},
|
|
{b("wasip1-wasm-wasmer", "debug"), none},
|
|
{b("wasip1-wasm-wasmer", "mobile"), none},
|
|
{b("wasip1-wasm-wasmer", "perf"), none},
|
|
{b("wasip1-wasm-wasmer", "talks"), none},
|
|
{b("wasip1-wasm-wasmer", "tools"), none},
|
|
{b("wasip1-wasm-wasmer", "tour"), none},
|
|
{b("wasip1-wasm-wasmer", "website"), none},
|
|
{b("wasip1-wasm-wasmedge", "arch"), none},
|
|
{b("wasip1-wasm-wasmedge", "crypto"), none},
|
|
{b("wasip1-wasm-wasmedge", "sys"), none},
|
|
{b("wasip1-wasm-wasmedge", "net"), none},
|
|
{b("wasip1-wasm-wasmedge", "benchmarks"), none},
|
|
{b("wasip1-wasm-wasmedge", "debug"), none},
|
|
{b("wasip1-wasm-wasmedge", "mobile"), none},
|
|
{b("wasip1-wasm-wasmedge", "perf"), none},
|
|
{b("wasip1-wasm-wasmedge", "talks"), none},
|
|
{b("wasip1-wasm-wasmedge", "tools"), none},
|
|
{b("wasip1-wasm-wasmedge", "tour"), none},
|
|
{b("wasip1-wasm-wasmedge", "website"), none},
|
|
|
|
// Race builders. Linux for all, GCE builders for
|
|
// post-submit, and only post-submit for "go" for
|
|
// Darwin (limited resources).
|
|
{b("linux-amd64-race", "go"), both},
|
|
{b("linux-amd64-race", "net"), both},
|
|
{b("windows-amd64-race", "go"), onlyPost},
|
|
{b("windows-amd64-race", "net"), onlyPost},
|
|
{b("freebsd-amd64-race", "go"), onlyPost},
|
|
{b("freebsd-amd64-race", "net"), onlyPost},
|
|
{b("darwin-amd64-race", "go"), onlyPost},
|
|
{b("darwin-amd64-race", "net"), none},
|
|
|
|
// Long test.
|
|
{b("linux-amd64-longtest", "go"), onlyPost},
|
|
{b("linux-amd64-longtest", "net"), onlyPost},
|
|
{b("linux-amd64-longtest@go1.99", "go"), both},
|
|
{b("linux-amd64-longtest@go1.99", "net"), none},
|
|
{b("darwin-amd64-longtest", "go"), onlyPost},
|
|
{b("darwin-amd64-longtest", "net"), onlyPost},
|
|
{b("darwin-amd64-longtest@go1.99", "go"), onlyPost},
|
|
{b("darwin-amd64-longtest@go1.99", "net"), none},
|
|
{b("windows-amd64-longtest", "go"), onlyPost},
|
|
{b("windows-amd64-longtest@go1.99", "go"), both},
|
|
{b("windows-amd64-longtest", "net"), onlyPost},
|
|
{b("windows-amd64-longtest", "exp"), onlyPost},
|
|
{b("windows-amd64-longtest", "mobile"), none},
|
|
{b("linux-386-longtest", "go"), onlyPost},
|
|
{b("linux-386-longtest", "net"), onlyPost},
|
|
{b("linux-386-longtest", "exp"), none},
|
|
{b("linux-386-longtest", "mobile"), none},
|
|
|
|
// Experimental exp repo runs in very few places.
|
|
{b("linux-amd64", "exp"), both},
|
|
{b("linux-amd64-race", "exp"), both},
|
|
{b("linux-amd64-longtest", "exp"), onlyPost},
|
|
{b("windows-386-2016", "exp"), none},
|
|
{b("windows-amd64-2016", "exp"), both},
|
|
{b("darwin-amd64-10_15", "exp"), none},
|
|
{b("darwin-amd64-11_0", "exp"), onlyPost},
|
|
// ... but not on most others:
|
|
{b("freebsd-386-12_3", "exp"), none},
|
|
{b("freebsd-amd64-12_3", "exp"), none},
|
|
{b("js-wasm-node18", "exp"), none},
|
|
{b("wasip1-wasm-wazero", "exp"), none},
|
|
{b("wasip1-wasm-wasmtime", "exp"), none},
|
|
{b("wasip1-wasm-wasmer", "exp"), none},
|
|
{b("wasip1-wasm-wasmedge", "exp"), none},
|
|
|
|
// exp is experimental; it doesn't test against release branches.
|
|
{b("linux-amd64@go1.99", "exp"), none},
|
|
|
|
// the build repo is only really useful for linux-amd64 (where we run it),
|
|
// and darwin-amd64 and perhaps windows-amd64 (for stuff like gomote).
|
|
// No need for any other operating systems to use it.
|
|
{b("linux-amd64", "build"), both},
|
|
{b("linux-amd64-longtest", "build"), onlyPost},
|
|
{b("windows-amd64-2016", "build"), both},
|
|
{b("darwin-amd64-10_15", "build"), none},
|
|
{b("darwin-amd64-11_0", "build"), onlyPost},
|
|
{b("linux-amd64-fedora", "build"), none},
|
|
{b("linux-amd64-clang", "build"), none},
|
|
{b("linux-amd64-sid", "build"), none},
|
|
{b("linux-amd64-bullseye", "build"), none},
|
|
{b("linux-amd64-bookworm", "build"), none},
|
|
{b("linux-amd64-nocgo", "build"), none},
|
|
{b("linux-386-longtest", "build"), none},
|
|
|
|
{b("linux-amd64", "vulndb"), both},
|
|
{b("linux-amd64-longtest", "vulndb"), onlyPost},
|
|
|
|
{b("linux-amd64-sid@go1.22", "pkgsite"), none},
|
|
{b("freebsd-amd64-13_0@go1.22", "pkgsite"), none},
|
|
{b("linux-amd64@go1.20", "pkgsite-metrics"), both},
|
|
|
|
{b("js-wasm-node18", "build"), none},
|
|
{b("wasip1-wasm-wazero", "build"), none},
|
|
{b("wasip1-wasm-wasmtime", "build"), none},
|
|
{b("wasip1-wasm-wasmer", "build"), none},
|
|
{b("wasip1-wasm-wasmedge", "build"), none},
|
|
{b("android-386-emu", "build"), none},
|
|
{b("android-amd64-emu", "build"), none},
|
|
|
|
{b("darwin-amd64-11_0", "go"), onlyPost},
|
|
// Go 1.22 is the last release with macOS 10.15 support:
|
|
{b("darwin-amd64-10_15", "go"), none},
|
|
{b("darwin-amd64-10_15@go1.23", "go"), none},
|
|
{b("darwin-amd64-10_15@go1.22", "go"), onlyPost},
|
|
{b("darwin-amd64-10_15", "net"), none},
|
|
{b("darwin-amd64-10_15@go1.23", "net"), none},
|
|
{b("darwin-amd64-10_15@go1.22", "net"), onlyPost},
|
|
|
|
// The darwin longtest builder added during the Go 1.21 dev cycle:
|
|
{b("darwin-amd64-longtest@go1.21", "go"), onlyPost},
|
|
{b("darwin-amd64-longtest@go1.20", "go"), none},
|
|
|
|
// plan9 only lived at master. We didn't support any past releases.
|
|
// But it's off for now as it's always failing.
|
|
{b("plan9-386", "go"), none}, // temporarily disabled
|
|
{b("plan9-386", "net"), none}, // temporarily disabled
|
|
{b("plan9-386", "exp"), none},
|
|
{b("plan9-386", "mobile"), none},
|
|
{b("plan9-386@go1.99", "go"), none},
|
|
{b("plan9-386@go1.99", "net"), none},
|
|
{b("plan9-amd64-0intro", "go"), onlyPost},
|
|
{b("plan9-amd64-0intro", "exp"), none},
|
|
{b("plan9-amd64-0intro", "mobile"), none},
|
|
{b("plan9-amd64-0intro@go1.99", "go"), none},
|
|
{b("plan9-amd64-0intro", "net"), onlyPost},
|
|
{b("plan9-amd64-0intro@go1.99", "net"), none},
|
|
{b("plan9-arm", "go"), onlyPost},
|
|
{b("plan9-arm", "exp"), none},
|
|
{b("plan9-arm", "mobile"), none},
|
|
{b("plan9-amd64-0intro@go1.99", "go"), none},
|
|
{b("plan9-amd64-0intro", "net"), onlyPost},
|
|
{b("plan9-amd64-0intro@go1.99", "net"), none},
|
|
{b("dragonfly-amd64-622", "go"), onlyPost},
|
|
{b("dragonfly-amd64-622", "net"), onlyPost},
|
|
|
|
{b("linux-amd64-staticlockranking", "go"), onlyPost},
|
|
{b("linux-amd64-staticlockranking", "net"), none},
|
|
|
|
{b("linux-amd64-newinliner", "go"), both},
|
|
{b("linux-amd64-newinliner", "tools"), none},
|
|
{b("linux-amd64-newinliner@go1.22", "go"), none},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.br.testName, func(t *testing.T) {
|
|
// Require a want value that asserts both dimensions: try or not, post or not.
|
|
switch tt.want {
|
|
case none, both, onlyPost:
|
|
// OK.
|
|
default:
|
|
t.Fatalf("tt.want must be one of: none, both, or onlyPost")
|
|
}
|
|
|
|
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 {
|
|
if stopped := migration.BuildersPortedToLUCI[bc.Name] && migration.StopPortedBuilder; stopped {
|
|
t.Logf("not a post-submit builder because it's intentionally stopped")
|
|
} else {
|
|
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 {
|
|
if stopped := migration.BuildersPortedToLUCI[bc.Name] && migration.StopPortedBuilder; stopped {
|
|
t.Logf("not a trybot builder because it's intentionally stopped")
|
|
} else {
|
|
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) {
|
|
knownUnused := map[string]bool{}
|
|
|
|
used := make(map[string]bool)
|
|
for _, conf := range Builders {
|
|
used[conf.HostType] = true
|
|
}
|
|
for hostType := range Hosts {
|
|
if !used[hostType] && !knownUnused[hostType] {
|
|
t.Errorf("host type %q is not referenced from any build config", hostType)
|
|
}
|
|
if used[hostType] && knownUnused[hostType] {
|
|
t.Errorf("host type %q should not be listed in knownUnused since it's in use", hostType)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test that all specified builder owners are non-nil.
|
|
func TestBuilderOwners(t *testing.T) {
|
|
for host, config := range Hosts {
|
|
for i, p := range config.Owners {
|
|
if p == nil {
|
|
t.Errorf("dashboard.Hosts[%q].Owners[%d] is nil, want non-nil", host, i)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// tests that goBranch is optional for repo == "go"
|
|
func TestBuildsRepoAtAllImplicitGoBranch(t *testing.T) {
|
|
builder := Builders["android-amd64-emu"]
|
|
got := builder.buildsRepoAtAll("go", "master", "")
|
|
if !got {
|
|
t.Error("got = false; want true")
|
|
}
|
|
}
|
|
|
|
func TestShouldRunDistTest(t *testing.T) {
|
|
if stopped := migration.BuildersPortedToLUCI["linux-amd64"] && migration.StopPortedBuilder; stopped {
|
|
t.Skip("test can't be used because linux builders are stopped")
|
|
}
|
|
|
|
type buildMode int
|
|
const (
|
|
tryMode buildMode = 0
|
|
postSubmit buildMode = 1
|
|
)
|
|
|
|
tests := []struct {
|
|
builder string
|
|
test string
|
|
mode buildMode
|
|
want bool
|
|
}{
|
|
{"linux-amd64", "api", postSubmit, true},
|
|
{"linux-amd64", "api", tryMode, true},
|
|
{"freebsd-amd64-12_3", "api", postSubmit, true}, // freebsd-amd64-12_3 uses fasterTrybots policy, should still build.
|
|
{"freebsd-amd64-12_3", "api", tryMode, false}, // freebsd-amd64-12_3 uses fasterTrybots policy, should skip in try mode.
|
|
|
|
{"linux-amd64", "reboot", tryMode, true},
|
|
{"linux-amd64-race", "reboot", tryMode, false},
|
|
|
|
{"darwin-amd64-13", "test:foo", postSubmit, false},
|
|
{"darwin-amd64-13", "reboot", postSubmit, false},
|
|
{"darwin-amd64-13", "api", postSubmit, false},
|
|
{"darwin-amd64-13", "codewalk", postSubmit, false},
|
|
{"darwin-amd64-12_0", "test:foo", postSubmit, false},
|
|
}
|
|
for _, tt := range tests {
|
|
bc, ok := Builders[tt.builder]
|
|
if !ok {
|
|
t.Errorf("unknown builder %q", tt.builder)
|
|
continue
|
|
}
|
|
isTry := tt.mode == tryMode
|
|
if isTry && !bc.BuildsRepoTryBot("go", "master", "master") {
|
|
t.Errorf("builder %q is not a trybot, so can't run test %q in try mode", tt.builder, tt.test)
|
|
continue
|
|
}
|
|
got := bc.ShouldRunDistTest(tt.test, isTry)
|
|
if got != tt.want {
|
|
t.Errorf("%q.ShouldRunDistTest(%q, try %v) = %v; want %v", tt.builder, tt.test, isTry, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSlowBotAliases(t *testing.T) {
|
|
for term, name := range slowBotAliases {
|
|
if name == "" {
|
|
// Empty string means known missing builder.
|
|
continue
|
|
}
|
|
if _, ok := Builders[name]; !ok {
|
|
t.Errorf("slowbot term %q references unknown builder %q", term, name)
|
|
}
|
|
}
|
|
|
|
ports, err := listPorts()
|
|
if err != nil {
|
|
t.Fatal("listPorts:", err)
|
|
}
|
|
|
|
done := map[string]bool{}
|
|
|
|
var add bytes.Buffer
|
|
check := func(term string, isArch bool) {
|
|
if done[term] {
|
|
return
|
|
}
|
|
done[term] = true
|
|
_, isBuilderName := Builders[term]
|
|
_, hasAlias := slowBotAliases[term]
|
|
if !isBuilderName && !hasAlias {
|
|
prefix := term
|
|
if isArch {
|
|
prefix = "linux-" + term
|
|
}
|
|
var matches []string
|
|
for name := range Builders {
|
|
if strings.HasPrefix(name, prefix) {
|
|
matches = append(matches, name)
|
|
}
|
|
}
|
|
sort.Strings(matches)
|
|
t.Errorf("term %q has no match in slowBotAliases", term)
|
|
if len(matches) == 1 {
|
|
fmt.Fprintf(&add, "%q: %q,\n", term, matches[0])
|
|
} else if len(matches) > 1 {
|
|
t.Errorf("maybe add: %q: %q, (matches=%q)", term, matches[len(matches)-1], matches)
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, port := range ports {
|
|
goos, goarch, ok := strings.Cut(port, "/")
|
|
if !ok {
|
|
t.Fatalf("unexpected port %q", port)
|
|
}
|
|
check(goos+"-"+goarch, false)
|
|
check(goos, false)
|
|
check(goarch, true)
|
|
}
|
|
|
|
if add.Len() > 0 {
|
|
t.Errorf("Missing items from slowBotAliases:\n%s", add.String())
|
|
}
|
|
}
|
|
|
|
// TestCrossCompileOnlyBuilders checks to make sure that only misc-compile
|
|
// builders and the linux-s390x-crosscompile builder have IsCrossCompileOnly
|
|
// return true.
|
|
func TestCrossCompileOnlyBuilders(t *testing.T) {
|
|
for _, conf := range Builders {
|
|
isMiscCompile := strings.HasPrefix(conf.Name, "misc-compile") || conf.Name == "linux-s390x-crosscompile"
|
|
if ccOnly := conf.IsCrossCompileOnly(); isMiscCompile != ccOnly {
|
|
t.Errorf("builder %q has unexpected IsCrossCompileOnly state (want %t, got %t)", conf.Name, isMiscCompile, ccOnly)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestTryBotsCompileAllPorts verifies that each port (go tool dist list)
|
|
// is covered by either a real TryBot or a misc-compile TryBot.
|
|
//
|
|
// The special pseudo-port 'linux-arm-arm5' is tested in TestMiscCompileLinuxGOARM5.
|
|
func TestTryBotsCompileAllPorts(t *testing.T) {
|
|
if migration.StopLegacyMiscCompileTryBots {
|
|
t.Log("nothing to test since legacy misc-compile trybots are stopped")
|
|
return
|
|
}
|
|
|
|
ports, err := listPorts()
|
|
if err != nil {
|
|
t.Fatal("listPorts:", err)
|
|
}
|
|
|
|
// knownMissing tracks Go ports that that are known to be
|
|
// completely missing TryBot (pre-submit) test coverage.
|
|
//
|
|
// All completed ports should have either a real TryBot or at least a misc-compile TryBot,
|
|
// so this map is meant to be used to temporarily fix tests
|
|
// when the work of adding a new port is actively underway.
|
|
knownMissing := map[string]bool{
|
|
"openbsd-mips64": true, // go.dev/issue/58110
|
|
|
|
"js-wasm": true, // Fully ported to LUCI and stopped in the coordinator.
|
|
"wasip1-wasm": true, // Fully ported to LUCI and stopped in the coordinator.
|
|
}
|
|
|
|
var done = make(map[string]bool)
|
|
check := func(goos, goarch string) {
|
|
if goos == "android" || goos == "ios" {
|
|
// TODO(golang.org/issue/25963): support
|
|
// compilation-only Android and iOS trybots.
|
|
// buildall.bash doesn't set the environment
|
|
// up enough for e.g. compiling android-386
|
|
// from linux-amd64. (Issue #35596 too)
|
|
// iOS likely needs to be built on macOS
|
|
// with Xcode available.
|
|
return
|
|
}
|
|
goosArch := goos + "-" + goarch
|
|
if done[goosArch] {
|
|
return
|
|
}
|
|
for _, conf := range Builders {
|
|
if conf.GOOS() == goos && conf.GOARCH() == goarch &&
|
|
conf.BuildsRepoTryBot("go", "master", "master") {
|
|
|
|
// There's a real TryBot for this GOOS/GOARCH pair.
|
|
done[goosArch] = true
|
|
break
|
|
}
|
|
|
|
if strings.HasPrefix(conf.Name, "misc-compile-") {
|
|
var cGoos, cGoarch string
|
|
for _, v := range conf.env {
|
|
if strings.HasPrefix(v, "GOOS=") {
|
|
cGoos = v[len("GOOS="):]
|
|
}
|
|
if strings.HasPrefix(v, "GOARCH=") {
|
|
cGoarch = v[len("GOARCH="):]
|
|
}
|
|
}
|
|
if cGoos == "" {
|
|
t.Errorf("missing GOOS env var for misc-compile builder %q", conf.Name)
|
|
}
|
|
if cGoarch == "" {
|
|
t.Errorf("missing GOARCH env var for misc-compile builder %q", conf.Name)
|
|
}
|
|
cGoosArch := cGoos + "-" + cGoarch
|
|
if goosArch == cGoosArch {
|
|
// There's a misc-compile TryBot for this GOOS/GOARCH pair.
|
|
done[goosArch] = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if knownMissing[goosArch] && done[goosArch] {
|
|
// Make it visible when a builder is added but the old
|
|
// knownMissing entry isn't removed by failing the test.
|
|
t.Errorf("knownMissing[%q] is true, but a corresponding TryBot (real or misc-compile) exists", goosArch)
|
|
} else if _, ok := done[goosArch]; !ok && !knownMissing[goosArch] {
|
|
t.Errorf("missing real TryBot or misc-compile TryBot for %q", goosArch)
|
|
}
|
|
}
|
|
|
|
for _, port := range ports {
|
|
goos, goarch, ok := strings.Cut(port, "/")
|
|
if !ok {
|
|
t.Fatalf("unexpected port %q", port)
|
|
}
|
|
check(goos, goarch)
|
|
}
|
|
}
|
|
|
|
// The 'linux-arm-arm5' pseduo-port is supported by src/buildall.bash
|
|
// and tests linux/arm with GOARM=5 set. Since it's not a normal port,
|
|
// the TestTryBotsCompileAllPorts wouldn't report if the misc-compile
|
|
// TryBot that covers is accidentally removed. Check it explicitly.
|
|
func TestMiscCompileLinuxGOARM5(t *testing.T) {
|
|
if migration.StopLegacyMiscCompileTryBots {
|
|
t.Log("nothing to test since legacy misc-compile trybots are stopped")
|
|
return
|
|
}
|
|
|
|
for _, b := range Builders {
|
|
if !strings.HasPrefix(b.Name, "misc-compile-") {
|
|
continue
|
|
}
|
|
var hasGOOS, hasGOARCH, hasGOARM bool
|
|
for _, v := range b.env {
|
|
if v == "GOOS=linux" {
|
|
hasGOOS = true
|
|
continue
|
|
}
|
|
if v == "GOARCH=arm" {
|
|
hasGOARCH = true
|
|
continue
|
|
}
|
|
if v == "GOARM=5" {
|
|
hasGOARM = true
|
|
continue
|
|
}
|
|
}
|
|
if hasGOOS && hasGOARCH && hasGOARM {
|
|
// Found it. Nothing left to do.
|
|
return
|
|
}
|
|
}
|
|
// We get here if the linux-arm-arm5 port is no longer checked by
|
|
// a misc-compile TryBot. Report it as a failure in case the coverage
|
|
// was removed accidentally (e.g., as part of a refactor).
|
|
t.Errorf("no misc-compile TryBot coverage for the special 'linux-arm-arm5' pseudo-port")
|
|
}
|
|
|
|
// Test that we have longtest builders and
|
|
// that their environment configurations are okay.
|
|
func TestLongTestBuilder(t *testing.T) {
|
|
for _, name := range []string{"linux-amd64-longtest", "linux-amd64-longtest-race"} {
|
|
name := name
|
|
t.Run(name, func(t *testing.T) {
|
|
long, ok := Builders[name]
|
|
if !ok {
|
|
t.Fatalf("we don't have a %s builder anymore, is that intentional?", name)
|
|
}
|
|
if !long.IsLongTest() {
|
|
t.Errorf("the %s builder isn't a longtest builder, is that intentional?", name)
|
|
}
|
|
var shortDisabled bool
|
|
for _, e := range long.Env() {
|
|
if e == "GO_TEST_SHORT=0" {
|
|
shortDisabled = true
|
|
}
|
|
}
|
|
if !shortDisabled {
|
|
t.Errorf("the %s builder doesn't set GO_TEST_SHORT=0, is that intentional?", name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test that we have race builders and
|
|
// that their environment configurations are okay.
|
|
func TestRaceBuilder(t *testing.T) {
|
|
for _, name := range []string{"linux-amd64-race", "linux-amd64-longtest-race"} {
|
|
name := name
|
|
t.Run(name, func(t *testing.T) {
|
|
race, ok := Builders[name]
|
|
if !ok {
|
|
t.Fatalf("we don't have a %s builder anymore, is that intentional?", name)
|
|
}
|
|
if !race.IsRace() {
|
|
t.Errorf("the %s builder isn't a race builder, is that intentional?", name)
|
|
}
|
|
if script := race.AllScript(); !strings.Contains(script, "race") {
|
|
t.Errorf("the %s builder doesn't use race.bash or race.bat, it uses %s instead, is that intentional?", name, script)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostConfigIsVM(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
config *HostConfig
|
|
want bool
|
|
}{
|
|
{
|
|
desc: "non-ec2-vm",
|
|
config: &HostConfig{
|
|
VMImage: "image-x",
|
|
ContainerImage: "",
|
|
IsEC2: false,
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
desc: "non-ec2-container",
|
|
config: &HostConfig{
|
|
VMImage: "",
|
|
ContainerImage: "container-image-x",
|
|
IsEC2: false,
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
desc: "ec2-container",
|
|
config: &HostConfig{
|
|
VMImage: "image-x",
|
|
ContainerImage: "container-image-x",
|
|
IsEC2: true,
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
desc: "ec2-vm",
|
|
config: &HostConfig{
|
|
VMImage: "image-x",
|
|
ContainerImage: "",
|
|
IsEC2: true,
|
|
},
|
|
want: true,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
if got := tc.config.IsVM(); got != tc.want {
|
|
t.Errorf("HostConfig.IsVM() = %t; want %t", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDefaultPlusExpBuild(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
repo string
|
|
want bool
|
|
}{
|
|
{"exp", true},
|
|
{"build", true},
|
|
{"anything", true},
|
|
{"vulndb", false},
|
|
} {
|
|
got := defaultPlusExpBuild(tc.repo, "", "")
|
|
if got != tc.want {
|
|
t.Errorf("%s: got %t, want %t", tc.repo, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHostsSort(t *testing.T) {
|
|
data, err := os.ReadFile("builders.go")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
table := regexp.MustCompile(`(?s)\nvar Hosts =.*?\n}\n`).FindString(string(data))
|
|
if table == "" {
|
|
t.Fatal("cannot find Hosts table in builders.go")
|
|
}
|
|
m := regexp.MustCompile(`\n\t"([^"]+)":`).FindAllStringSubmatch(table, -1)
|
|
if len(m) < 10 {
|
|
t.Fatalf("cannot find host keys in table")
|
|
}
|
|
var last string
|
|
for _, sub := range m {
|
|
key := sub[1]
|
|
if last > key {
|
|
t.Errorf("Host table unsorted: %s before %s", last, key)
|
|
}
|
|
last = key
|
|
}
|
|
}
|
|
|
|
func TestBuildersPortedToLUCI(t *testing.T) {
|
|
// Check that map keys refer to builder names that exist,
|
|
// otherwise the entry is a no-op. Mostly to catch typos.
|
|
for name := range migration.BuildersPortedToLUCI {
|
|
if _, ok := Builders[name]; !ok {
|
|
t.Errorf("BuildersPortedToLUCI contains an unknown legacy builder name %v", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHostConfigCosArchitecture(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
hostConfig HostConfig
|
|
want CosArch
|
|
}{
|
|
{"default", HostConfig{}, CosArchAMD64},
|
|
{"amd64", HostConfig{cosArchitecture: CosArchAMD64}, CosArchAMD64},
|
|
{"arm64", HostConfig{cosArchitecture: CosArchARM64}, CosArchARM64},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
if got := tc.hostConfig.CosArchitecture(); got != tc.want {
|
|
t.Errorf("HostConfig.CosArchitecture() = %+v; want %+v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// listPorts lists supported Go ports
|
|
// found by running go tool dist list.
|
|
func listPorts() ([]string, error) {
|
|
cmd := exec.Command("go", "tool", "dist", "list")
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
if ee := (*exec.ExitError)(nil); errors.As(err, &ee) {
|
|
out = append(out, ee.Stderr...)
|
|
}
|
|
return nil, fmt.Errorf("%q failed: %s\n%s", cmd, err, out)
|
|
}
|
|
return strings.Fields(string(out)), nil
|
|
}
|