Skip to content

cmd/go: test caching is broken with sub-packages when using testing.T.Chdir #79019

@mvdan

Description

@mvdan

Go version

go version go1.27-devel_a3f569adee 2026-04-28 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v4'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/mvdan/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/mvdan/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2037079810=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/mvdan/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/mvdan/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/mvdan/tip'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/mvdan/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/home/mvdan/tip/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.27-devel_a3f569adee 2026-04-28 14:51:38 -0700'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Run a package whose tests use testing.T.Chdir, alongside another test in the same package that reads a file via a relative path. The relative-path file is then modified between go test invocations.

# We sleep for more than 2s to exceed cmd/go's modTimeCutoff,
# otherwise it refuses to save anything into the test cache.
exec sleep 3

# First run: populates the test cache with a PASS.
go test ./pkg
stdout '^ok'
! stdout 'cached'

# Verify the cache hits when nothing changes.
go test ./pkg
stdout 'cached'

# Modify the testdata file that TestB reads.
cp pkg/testdata/input.txt.modified pkg/testdata/input.txt

# We should now get a cache miss again.
go test ./pkg
! stdout 'cached'

-- go.mod --
module test

go 1.24
-- pkg/subdir/.keep --
-- pkg/testdata/input.txt --
original
-- pkg/testdata/input.txt.modified --
MODIFIED
-- pkg/repro_test.go --
package pkg

import (
	"os"
	"testing"
)

func TestA(t *testing.T) { t.Chdir("subdir") }
func TestB(t *testing.T) { os.ReadFile("testdata/input.txt") }

What did you see happen?

The third go test ./pkg reports (cached) even though pkg/testdata/input.txt was modified between the second and third runs.

# First run: populates the test cache with a PASS. (0.149s)
> go test ./pkg
[stdout]
ok  	test/pkg	0.002s

> stdout '^ok'
> ! stdout 'cached'
# Verify the cache hits when nothing changes. (0.044s)
> go test ./pkg
[stdout]
ok  	test/pkg	(cached)

> stdout 'cached'
# Modify the testdata file that TestB reads. (0.000s)
> cp pkg/testdata/input.txt.modified pkg/testdata/input.txt
# We should now get a cache miss again. (0.043s)
> go test ./pkg
[stdout]
ok  	test/pkg	(cached)

> ! stdout 'cached'
FAIL: repro-tchdir-cache.txtar:19: unexpected match for `cached` found in stdout: cached

What did you expect to see?

The third run should be a cache miss and re-run TestB, since TestB reads testdata/input.txt and that file changed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.FixPendingIssues that have a fix which has not yet been reviewed or submitted.GoCommandcmd/goNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    Status

    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions