testing: allow specify temp dir by GOTMPDIR environment variable

Allow change the default temp directory returned by t.TempDir()
by environment variable GOTMPDIR.

Fixes #61585

Change-Id: Iba969bb02744e106cf15d80e0eda0245a55fc290
GitHub-Last-Rev: aeacea0095
GitHub-Pull-Request: golang/go#74844
Reviewed-on: https://go-review.googlesource.com/c/go/+/692455
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Sean Liao <sean@liao.dev>
Reviewed-by: Sean Liao <sean@liao.dev>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
AN Long 2025-08-12 14:06:53 +00:00 committed by Gopher Robot
parent 9f6936b8da
commit ba9e1ddccf
4 changed files with 44 additions and 5 deletions

View file

@ -2407,8 +2407,10 @@
// The name of checksum database to use and optionally its public key and
// URL. See https://golang.org/ref/mod#authenticating.
// GOTMPDIR
// The directory where the go command will write
// temporary source files, packages, and binaries.
// Temporary directory used by the go command and testing package.
// Overrides the platform-specific temporary directory such as "/tmp".
// The go command and testing package will write temporary source files,
// packages, and binaries here.
// GOTOOLCHAIN
// Controls which Go toolchain is used. See https://go.dev/doc/toolchain.
// GOVCS

View file

@ -573,8 +573,10 @@ General-purpose environment variables:
The name of checksum database to use and optionally its public key and
URL. See https://golang.org/ref/mod#authenticating.
GOTMPDIR
The directory where the go command will write
temporary source files, packages, and binaries.
Temporary directory used by the go command and testing package.
Overrides the platform-specific temporary directory such as "/tmp".
The go command and testing package will write temporary source files,
packages, and binaries here.
GOTOOLCHAIN
Controls which Go toolchain is used. See https://go.dev/doc/toolchain.
GOVCS

View file

@ -1318,6 +1318,8 @@ func (c *common) Cleanup(f func()) {
// all its subtests complete.
// Each subsequent call to TempDir returns a unique directory;
// if the directory creation fails, TempDir terminates the test by calling Fatal.
// If the environment variable GOTMPDIR is set, the temporary directory will
// be created somewhere beneath it.
func (c *common) TempDir() string {
c.checkFuzzFn("TempDir")
// Use a single parent directory for all the temporary directories
@ -1362,7 +1364,7 @@ func (c *common) TempDir() string {
return -1
}
pattern = strings.Map(mapper, pattern)
c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
c.tempDir, c.tempDirErr = os.MkdirTemp(os.Getenv("GOTMPDIR"), pattern)
if c.tempDirErr == nil {
c.Cleanup(func() {
if err := removeAll(c.tempDir); err != nil {

View file

@ -147,6 +147,39 @@ func testTempDir(t *testing.T) {
}
}
func TestTempDirGOTMPDIR(t *testing.T) {
// The first call to t.TempDir will create a parent temporary directory
// that will contain all temporary directories created by TempDir.
//
// Use os.TempDir (not t.TempDir) to get a temporary directory,
// set GOTMPDIR to that directory,
// and then verify that t.TempDir creates a directory in GOTMPDIR.
customTmpDir := filepath.Join(os.TempDir(), "custom-gotmpdir-test")
if err := os.MkdirAll(customTmpDir, 0777); err != nil {
t.Fatal(err)
}
defer os.RemoveAll(customTmpDir)
t.Setenv("GOTMPDIR", customTmpDir)
dir := t.TempDir()
if dir == "" {
t.Fatal("expected dir")
}
if !strings.HasPrefix(dir, customTmpDir) {
t.Errorf("TempDir did not use GOTMPDIR: got %q, want prefix %q", dir, customTmpDir)
}
fi, err := os.Stat(dir)
if err != nil {
t.Fatal(err)
}
if !fi.IsDir() {
t.Errorf("dir %q is not a dir", dir)
}
}
func TestSetenv(t *testing.T) {
tests := []struct {
name string