Skip to content

Commit e566a70

Browse files
committed
cmd/releasebot, cmd/release: include long tests in release process
The goal of this change is to reduce the chance of issuing a release with an unintended regression that would be caught by running long tests. This change adds long tests that are run during the -prepare step, in addition to all the existing short tests that are run. Executing the long tests is implemented by adding two new test-only release targets. For a release to be considered complete, all release targets must complete. These test-only targets are built only for the purpose of verifying their tests succeed, or to block the release otherwise. They do not produce release artifacts. The new test-only targets are named after the builder which is used to perform their tests, and they are: • linux-amd64-longtest • windows-amd64-longtest More builders may be added in the future, but care must be taken to ensure the test execution environment is as close as possible to that of build.golang.org post-submit builders, in order to avoid false positives and false negatives. As part of a gradual rollout, this change also adds a flag to skip longtest builders. It's meant to be used in case a long test proves to be flaky, and enough confidence can be gained through testing elsewhere that the failure is not a regression caused by a change merged to the release branch. For now, its default value includes both longtest builders, so they are currently opt-in and this CL is a no-op. After testing proves that it is viable to rely on this (and any issues preventing that from being possible are resolved), the default value of the flag will be changed to the empty string. For golang/go#29252. For golang/go#39054. For golang/go#37827. Fixes golang/go#24614. Change-Id: I33ea6601aade2873f857c63f00a0c11821f35a95 Reviewed-on: https://go-review.googlesource.com/c/build/+/234531 Run-TryBot: Dmitri Shuralyov <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Carlos Amedee <[email protected]> Reviewed-by: Alexander Rakoczy <[email protected]>
1 parent e0af7f0 commit e566a70

File tree

3 files changed

+167
-64
lines changed

3 files changed

+167
-64
lines changed

cmd/release/release.go

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ var (
4444
tarball = flag.String("tarball", "", "Go tree tarball to build, alternative to -rev")
4545
version = flag.String("version", "", "Version string (go1.5.2)")
4646
user = flag.String("user", username(), "coordinator username, appended to 'user-'")
47-
skipTests = flag.Bool("skip_tests", false, "skip tests; run make.bash instead of all.bash (only use if you ran trybots first)")
47+
skipTests = flag.Bool("skip_tests", false, "skip tests; run make.bash but not all.bash (only use if sufficient testing was done elsewhere)")
4848

4949
uploadMode = flag.Bool("upload", false, "Upload files (exclusive to all other flags)")
5050
uploadKick = flag.String("edge_kick_command", "", "Command to run to kick off an edge cache update")
@@ -108,20 +108,26 @@ type Build struct {
108108

109109
Race bool // Build race detector.
110110

111-
Builder string // Key for dashboard.Builders.
111+
Builder string // Key for dashboard.Builders.
112+
TestOnly bool // Run tests only; don't produce a release artifact.
112113

113-
Goarm int // GOARM value if set.
114-
MakeOnly bool // don't run tests; needed by cross-compile builders (s390x)
114+
Goarm int // GOARM value if set.
115+
SkipTests bool // skip tests (run make.bash but not all.bash); needed by cross-compile builders (s390x)
115116
}
116117

117118
func (b *Build) String() string {
118-
if b.Source {
119+
switch {
120+
case b.Source:
119121
return "src"
120-
}
121-
if b.Goarm != 0 {
122+
case b.TestOnly:
123+
// Test-only builds are named after the builder used to
124+
// perform them. For example, "linux-amd64-longtest".
125+
return b.Builder
126+
case b.Goarm != 0:
122127
return fmt.Sprintf("%v-%vv%vl", b.OS, b.Arch, b.Goarm)
128+
default:
129+
return fmt.Sprintf("%v-%v", b.OS, b.Arch)
123130
}
124-
return fmt.Sprintf("%v-%v", b.OS, b.Arch)
125131
}
126132

127133
func (b *Build) toolDir() string { return "go/pkg/tool/" + b.OS + "_" + b.Arch }
@@ -149,13 +155,13 @@ var builds = []*Build{
149155
Goarm: 6, // for compatibility with all Raspberry Pi models.
150156
// The tests take too long for the release packaging.
151157
// Much of the time the whole buildlet times out.
152-
MakeOnly: true,
158+
SkipTests: true,
153159
},
154160
{
155161
OS: "linux",
156162
Arch: "amd64",
157163
Race: true,
158-
Builder: "linux-amd64-jessie", // using Jessie for at least [Go 1.11, Go 1.13] due to golang.org/issue/31336
164+
Builder: "linux-amd64-jessie", // using Jessie for at least [Go 1.11, Go 1.13] due to golang.org/issue/31293
159165
},
160166
{
161167
OS: "linux",
@@ -191,20 +197,32 @@ var builds = []*Build{
191197
Builder: "darwin-amd64-10_15",
192198
},
193199
{
194-
OS: "linux",
195-
Arch: "s390x",
196-
MakeOnly: true,
197-
Builder: "linux-s390x-crosscompile",
200+
OS: "linux",
201+
Arch: "s390x",
202+
SkipTests: true,
203+
Builder: "linux-s390x-crosscompile",
198204
},
199205
// TODO(bradfitz): switch this ppc64 builder to a Kubernetes
200206
// container cross-compiling ppc64 like the s390x one? For
201207
// now, the ppc64le builders (5) are back, so let's see if we
202208
// can just depend on them not going away.
203209
{
204-
OS: "linux",
205-
Arch: "ppc64le",
206-
MakeOnly: true,
207-
Builder: "linux-ppc64le-buildlet",
210+
OS: "linux",
211+
Arch: "ppc64le",
212+
SkipTests: true,
213+
Builder: "linux-ppc64le-buildlet",
214+
},
215+
216+
// Test-only builds.
217+
{
218+
Builder: "linux-amd64-longtest",
219+
OS: "linux", Arch: "amd64",
220+
TestOnly: true,
221+
},
222+
{
223+
Builder: "windows-amd64-longtest",
224+
OS: "windows", Arch: "amd64",
225+
TestOnly: true,
208226
},
209227
}
210228

@@ -236,7 +254,7 @@ func (b *Build) make() error {
236254
}
237255

238256
var hostArch string // non-empty if we're cross-compiling (s390x)
239-
if b.MakeOnly && bc.IsContainer() && (bc.GOARCH() != "amd64" && bc.GOARCH() != "386") {
257+
if b.SkipTests && bc.IsContainer() && (bc.GOARCH() != "amd64" && bc.GOARCH() != "386") {
240258
hostArch = "amd64"
241259
}
242260

@@ -464,7 +482,8 @@ func (b *Build) make() error {
464482
// So far, we've run make.bash. We want to create the release archive next.
465483
// Since the release archive hasn't been tested yet, place it in a temporary
466484
// location. After all.bash runs successfully (or gets explicitly skipped),
467-
// we'll move the release archive to its final location.
485+
// we'll move the release archive to its final location. For TestOnly builds,
486+
// we only care whether tests passed and do not produce release artifacts.
468487
type releaseFile struct {
469488
Untested string // Temporary location of the file before the release has been tested.
470489
Final string // Final location where to move the file after the release has been tested.
@@ -482,7 +501,7 @@ func (b *Build) make() error {
482501
return filepath.Join(stagingDir, *version+"."+b.String()+ext+".untested")
483502
}
484503

485-
if b.OS == "windows" {
504+
if !b.TestOnly && b.OS == "windows" {
486505
untested := stagingFile(".msi")
487506
if err := b.fetchFile(client, untested, "msi"); err != nil {
488507
return err
@@ -491,6 +510,9 @@ func (b *Build) make() error {
491510
Untested: untested,
492511
Final: *version + "." + b.String() + ".msi",
493512
})
513+
}
514+
515+
if b.OS == "windows" {
494516
cleanFiles = append(cleanFiles, "msi")
495517
}
496518

@@ -510,8 +532,8 @@ func (b *Build) make() error {
510532
return fmt.Errorf("verifying file permissions: %v", err)
511533
}
512534

513-
switch b.OS {
514-
default:
535+
switch {
536+
case !b.TestOnly && b.OS != "windows":
515537
untested := stagingFile(".tar.gz")
516538
if err := b.fetchTarball(ctx, client, untested); err != nil {
517539
return fmt.Errorf("fetching and writing tarball: %v", err)
@@ -520,7 +542,7 @@ func (b *Build) make() error {
520542
Untested: untested,
521543
Final: *version + "." + b.String() + ".tar.gz",
522544
})
523-
case "windows":
545+
case !b.TestOnly && b.OS == "windows":
524546
untested := stagingFile(".zip")
525547
if err := b.fetchZip(client, untested); err != nil {
526548
return fmt.Errorf("fetching and writing zip: %v", err)
@@ -529,10 +551,23 @@ func (b *Build) make() error {
529551
Untested: untested,
530552
Final: *version + "." + b.String() + ".zip",
531553
})
554+
case b.TestOnly:
555+
// Use an empty .test-only file to indicate the test outcome.
556+
// This file gets moved from its initial location in the
557+
// release-staging directory to the final release directory
558+
// when the test-only build passes tests successfully.
559+
untested := stagingFile(".test-only")
560+
if err := ioutil.WriteFile(untested, nil, 0600); err != nil {
561+
return fmt.Errorf("writing empty test-only file: %v", err)
562+
}
563+
releases = append(releases, releaseFile{
564+
Untested: untested,
565+
Final: *version + "." + b.String() + ".test-only",
566+
})
532567
}
533568

534569
// Execute build (all.bash) if running tests.
535-
if *skipTests || b.MakeOnly {
570+
if *skipTests || b.SkipTests {
536571
b.logf("Skipping all.bash tests.")
537572
} else {
538573
if u := bc.GoBootstrapURL(buildEnv); u != "" {
@@ -760,9 +795,12 @@ func (b *Build) writeFile(name string, r io.Reader) error {
760795
}
761796

762797
// checkRelocations runs readelf on pkg/linux_amd64/runtime/cgo.a and makes sure
763-
// we don't see R_X86_64_REX_GOTPCRELX. See issue 31293.
798+
// we don't see R_X86_64_REX_GOTPCRELX. See golang.org/issue/31293.
764799
func (b *Build) checkRelocations(client *buildlet.Client) error {
765-
if b.OS != "linux" || b.Arch != "amd64" {
800+
if b.OS != "linux" || b.Arch != "amd64" || b.TestOnly {
801+
// This check is only applicable to linux/amd64 builds.
802+
// However, skip it on test-only builds because they
803+
// don't produce binaries that are shipped to users.
766804
return nil
767805
}
768806
var out bytes.Buffer

cmd/release/release_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ func TestBuildersExist(t *testing.T) {
1919
}
2020
}
2121

22+
func TestTestOnlyBuildsDontSkipTests(t *testing.T) {
23+
for _, b := range builds {
24+
if b.TestOnly && b.SkipTests {
25+
t.Errorf("build %s is configured to run tests only, but also to skip tests; is that intentional?", b)
26+
}
27+
}
28+
}
29+
2230
func TestMinSupportedMacOSVersion(t *testing.T) {
2331
testCases := []struct {
2432
desc string

0 commit comments

Comments
 (0)