From 104f07c902f758b2347e3b4e5383dd06e935d401 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 19 Nov 2019 11:49:37 -0500 Subject: [PATCH] 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 --- src/cmd/go/go_test.go | 116 --------- src/cmd/go/testdata/script/cache_vet.txt | 2 +- .../go/testdata/script/test_cache_inputs.txt | 230 ++++++++++++++++++ .../testdata/src/testcache/testcache_test.go | 91 ------- 4 files changed, 231 insertions(+), 208 deletions(-) create mode 100644 src/cmd/go/testdata/script/test_cache_inputs.txt delete mode 100644 src/cmd/go/testdata/src/testcache/testcache_test.go diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index c5c5d411b9b71..3760703fee948 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -4870,122 +4870,6 @@ func TestTestCache(t *testing.T) { } } -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 d61e9bc68da8f..928024e0340c9 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 0000000000000..46faca0f422a4 --- /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 3de7c42faeaf0..0000000000000 --- 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) - } -}