cmd/go: convert TestTestCacheInputs to a script test
Updates #28387
Updates #30316
Change-Id: I48c6dd8619ea9602e9617ce11dfa05f1c70a485d
Reviewed-on: https://go-review.googlesource.com/c/go/+/207958
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index c5c5d41..3760703 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -4870,122 +4870,6 @@
}
}
-func TestTestCacheInputs(t *testing.T) {
- tooSlow(t)
-
- if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
- t.Skip("GODEBUG gocacheverify")
- }
- tg := testgo(t)
- defer tg.cleanup()
- tg.parallel()
- tg.makeTempdir()
- tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
- tg.setenv("GOCACHE", tg.path("cache"))
-
- defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))
- defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"))
- tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("x"), 0644))
- old := time.Now().Add(-1 * time.Minute)
- tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old))
- info, err := os.Stat(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))
- if err != nil {
- t.Fatal(err)
- }
- t.Logf("file.txt: old=%v, info.ModTime=%v", old, info.ModTime()) // help debug when Chtimes lies about succeeding
- tg.setenv("TESTKEY", "x")
-
- tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), []byte("#!/bin/sh\nexit 0\n"), 0755))
- tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old, old))
-
- tg.run("test", "testcache")
- tg.run("test", "testcache")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- tg.setenv("TESTKEY", "y")
- tg.run("test", "testcache")
- tg.grepStdoutNot(`\(cached\)`, "did not notice env var change")
- tg.run("test", "testcache")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- tg.run("test", "testcache", "-run=FileSize")
- tg.run("test", "testcache", "-run=FileSize")
- tg.grepStdout(`\(cached\)`, "did not cache")
- tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxx"), 0644))
- tg.run("test", "testcache", "-run=FileSize")
- tg.grepStdoutNot(`\(cached\)`, "did not notice file size change")
- tg.run("test", "testcache", "-run=FileSize")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- tg.run("test", "testcache", "-run=Chdir")
- tg.run("test", "testcache", "-run=Chdir")
- tg.grepStdout(`\(cached\)`, "did not cache")
- tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxxxx"), 0644))
- tg.run("test", "testcache", "-run=Chdir")
- tg.grepStdoutNot(`\(cached\)`, "did not notice file size change")
- tg.run("test", "testcache", "-run=Chdir")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old))
- tg.run("test", "testcache", "-run=FileContent")
- tg.run("test", "testcache", "-run=FileContent")
- tg.grepStdout(`\(cached\)`, "did not cache")
- tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("yyy"), 0644))
- old2 := old.Add(10 * time.Second)
- tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old2, old2))
- tg.run("test", "testcache", "-run=FileContent")
- tg.grepStdoutNot(`\(cached\)`, "did not notice file content change")
- tg.run("test", "testcache", "-run=FileContent")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- tg.run("test", "testcache", "-run=DirList")
- tg.run("test", "testcache", "-run=DirList")
- tg.grepStdout(`\(cached\)`, "did not cache")
- tg.must(os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt")))
- tg.run("test", "testcache", "-run=DirList")
- tg.grepStdoutNot(`\(cached\)`, "did not notice directory change")
- tg.run("test", "testcache", "-run=DirList")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- tg.tempFile("file.txt", "")
- tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"), []byte(`package testcache
-
- import (
- "os"
- "testing"
- )
-
- func TestExternalFile(t *testing.T) {
- os.Open(`+fmt.Sprintf("%q", tg.path("file.txt"))+`)
- _, err := os.Stat(`+fmt.Sprintf("%q", tg.path("file.txt"))+`)
- if err != nil {
- t.Fatal(err)
- }
- }
- `), 0666))
- defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"))
- tg.run("test", "testcache", "-run=ExternalFile")
- tg.run("test", "testcache", "-run=ExternalFile")
- tg.grepStdout(`\(cached\)`, "did not cache")
- tg.must(os.Remove(filepath.Join(tg.tempdir, "file.txt")))
- tg.run("test", "testcache", "-run=ExternalFile")
- tg.grepStdout(`\(cached\)`, "did not cache")
-
- switch runtime.GOOS {
- case "plan9", "windows":
- // no shell scripts
- default:
- tg.run("test", "testcache", "-run=Exec")
- tg.run("test", "testcache", "-run=Exec")
- tg.grepStdout(`\(cached\)`, "did not cache")
- tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old2, old2))
- tg.run("test", "testcache", "-run=Exec")
- tg.grepStdoutNot(`\(cached\)`, "did not notice script change")
- tg.run("test", "testcache", "-run=Exec")
- tg.grepStdout(`\(cached\)`, "did not cache")
- }
-}
-
func TestTestVet(t *testing.T) {
tooSlow(t)
tg := testgo(t)
diff --git a/src/cmd/go/testdata/script/cache_vet.txt b/src/cmd/go/testdata/script/cache_vet.txt
index d61e9bc..928024e 100644
--- a/src/cmd/go/testdata/script/cache_vet.txt
+++ b/src/cmd/go/testdata/script/cache_vet.txt
@@ -1,7 +1,7 @@
env GO111MODULE=off
[short] skip
-[GODEBUG:gocacheverify] skip
+[GODEBUG:gocacheverify=1] skip
[gccgo] skip # gccgo has no standard packages
# Start with a clean build cache:
diff --git a/src/cmd/go/testdata/script/test_cache_inputs.txt b/src/cmd/go/testdata/script/test_cache_inputs.txt
new file mode 100644
index 0000000..46faca0
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_cache_inputs.txt
@@ -0,0 +1,230 @@
+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\)'
+
+env TESTKEY=y
+go test testcache -run=TestLookupEnv
+! stdout '\(cached\)'
+go test testcache -run=TestLookupEnv
+stdout '\(cached\)'
+
+# 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\)'
+
+# 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/ioutil"
+ "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 := ioutil.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)
+ }
+}
+-- 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)
+ }
+}
diff --git a/src/cmd/go/testdata/src/testcache/testcache_test.go b/src/cmd/go/testdata/src/testcache/testcache_test.go
deleted file mode 100644
index 3de7c42..0000000
--- a/src/cmd/go/testdata/src/testcache/testcache_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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/ioutil"
- "os"
- "runtime"
- "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 := ioutil.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) {
- if runtime.GOOS == "plan9" || runtime.GOOS == "windows" {
- t.Skip("non-unix")
- }
-
- // 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)
- }
-}