env GO111MODULE=off # Test that cached test results are invalidated in response to # changes to the external inputs to the test. [short] skip [GODEBUG:gocacheverify=1] skip # We're testing cache behavior, so start with a clean GOCACHE. env GOCACHE=$WORK/cache # Build a helper binary to invoke os.Chtimes. go build -o mkold$GOEXE mkold.go # Make test input files appear to be a minute old. exec ./mkold$GOEXE 1m testcache/file.txt exec ./mkold$GOEXE 1m testcache/script.sh # If the test reads an environment variable, changes to that variable # should invalidate cached test results. env TESTKEY=x go test testcache -run=TestLookupEnv go test testcache -run=TestLookupEnv stdout '\(cached\)' # GODEBUG is always read env GODEBUG=asdf=1 go test testcache -run=TestLookupEnv ! stdout '\(cached\)' go test testcache -run=TestLookupEnv stdout '\(cached\)' env GODEBUG= env TESTKEY=y go test testcache -run=TestLookupEnv ! stdout '\(cached\)' go test testcache -run=TestLookupEnv stdout '\(cached\)' # Changes in arguments forwarded to the test should invalidate cached test # results. go test testcache -run=TestOSArgs -v hello ! stdout '\(cached\)' stdout 'hello' go test testcache -run=TestOSArgs -v goodbye ! stdout '\(cached\)' stdout 'goodbye' # golang.org/issue/36134: that includes the `-timeout` argument. go test testcache -run=TestOSArgs -timeout=20m -v ! stdout '\(cached\)' stdout '-test\.timeout[= ]20m' go test testcache -run=TestOSArgs -timeout=5s -v ! stdout '\(cached\)' stdout '-test\.timeout[= ]5s' # If the test stats a file, changes to the file should invalidate the cache. go test testcache -run=FileSize go test testcache -run=FileSize stdout '\(cached\)' cp 4x.txt testcache/file.txt go test testcache -run=FileSize ! stdout '\(cached\)' go test testcache -run=FileSize stdout '\(cached\)' # Files should be tracked even if the test changes its working directory. go test testcache -run=Chdir go test testcache -run=Chdir stdout '\(cached\)' cp 6x.txt testcache/file.txt go test testcache -run=Chdir ! stdout '\(cached\)' go test testcache -run=Chdir stdout '\(cached\)' # The content of files should affect caching, provided that the mtime also changes. exec ./mkold$GOEXE 1m testcache/file.txt go test testcache -run=FileContent go test testcache -run=FileContent stdout '\(cached\)' cp 2y.txt testcache/file.txt exec ./mkold$GOEXE 50s testcache/file.txt go test testcache -run=FileContent ! stdout '\(cached\)' go test testcache -run=FileContent stdout '\(cached\)' # Directory contents read via os.ReadDirNames should affect caching. go test testcache -run=DirList go test testcache -run=DirList stdout '\(cached\)' rm testcache/file.txt go test testcache -run=DirList ! stdout '\(cached\)' go test testcache -run=DirList stdout '\(cached\)' # Files outside GOROOT and GOPATH should not affect caching. env TEST_EXTERNAL_FILE=$WORK/external.txt go test testcache -run=ExternalFile go test testcache -run=ExternalFile stdout '\(cached\)' rm $WORK/external.txt go test testcache -run=ExternalFile stdout '\(cached\)' # The -benchtime flag without -bench should not affect caching. go test testcache -run=Benchtime -benchtime=1x go test testcache -run=Benchtime -benchtime=1x stdout '\(cached\)' go test testcache -run=Benchtime -bench=Benchtime -benchtime=1x go test testcache -run=Benchtime -bench=Benchtime -benchtime=1x ! stdout '\(cached\)' # golang.org/issue/47355: that includes the `-failfast` argument. go test testcache -run=TestOSArgs -failfast ! stdout '\(cached\)' go test testcache -run=TestOSArgs -failfast stdout '\(cached\)' # golang.org/issue/64638: that includes the `-fullpath` argument. go test testcache -run=TestOSArgs -fullpath ! stdout '\(cached\)' go test testcache -run=TestOSArgs -fullpath stdout '\(cached\)' # Executables within GOROOT and GOPATH should affect caching, # even if the test does not stat them explicitly. [!exec:/bin/sh] skip chmod 0755 ./testcache/script.sh exec ./mkold$GOEXEC 1m testcache/script.sh go test testcache -run=Exec go test testcache -run=Exec stdout '\(cached\)' exec ./mkold$GOEXE 50s testcache/script.sh go test testcache -run=Exec ! stdout '\(cached\)' go test testcache -run=Exec stdout '\(cached\)' -- testcache/file.txt -- xx -- 4x.txt -- xxxx -- 6x.txt -- xxxxxx -- 2y.txt -- yy -- $WORK/external.txt -- This file is outside of GOPATH. -- testcache/script.sh -- #!/bin/sh exit 0 -- testcache/testcache_test.go -- // Copyright 2017 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 testcache import ( "io" "os" "testing" ) func TestChdir(t *testing.T) { os.Chdir("..") defer os.Chdir("testcache") info, err := os.Stat("testcache/file.txt") if err != nil { t.Fatal(err) } if info.Size()%2 != 1 { t.Fatal("even file") } } func TestOddFileContent(t *testing.T) { f, err := os.Open("file.txt") if err != nil { t.Fatal(err) } data, err := io.ReadAll(f) f.Close() if err != nil { t.Fatal(err) } if len(data)%2 != 1 { t.Fatal("even file") } } func TestOddFileSize(t *testing.T) { info, err := os.Stat("file.txt") if err != nil { t.Fatal(err) } if info.Size()%2 != 1 { t.Fatal("even file") } } func TestOddGetenv(t *testing.T) { val := os.Getenv("TESTKEY") if len(val)%2 != 1 { t.Fatal("even env value") } } func TestLookupEnv(t *testing.T) { _, ok := os.LookupEnv("TESTKEY") if !ok { t.Fatal("env missing") } } func TestDirList(t *testing.T) { f, err := os.Open(".") if err != nil { t.Fatal(err) } f.Readdirnames(-1) f.Close() } func TestExec(t *testing.T) { // Note: not using os/exec to make sure there is no unexpected stat. p, err := os.StartProcess("./script.sh", []string{"script"}, new(os.ProcAttr)) if err != nil { t.Fatal(err) } ps, err := p.Wait() if err != nil { t.Fatal(err) } if !ps.Success() { t.Fatalf("script failed: %v", err) } } func TestExternalFile(t *testing.T) { os.Open(os.Getenv("TEST_EXTERNAL_FILE")) _, err := os.Stat(os.Getenv("TEST_EXTERNAL_FILE")) if err != nil { t.Fatal(err) } } func TestOSArgs(t *testing.T) { t.Log(os.Args) } func TestBenchtime(t *testing.T) { } -- mkold.go -- package main import ( "log" "os" "time" ) func main() { d, err := time.ParseDuration(os.Args[1]) if err != nil { log.Fatal(err) } path := os.Args[2] old := time.Now().Add(-d) err = os.Chtimes(path, old, old) if err != nil { log.Fatal(err) } }