diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 4d9486f5f0f82f..cd80e655d2a3b2 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -1841,67 +1841,6 @@ func main() { tg.run("run", tg.path("foo.go")) } -// "go test -c -test.bench=XXX errors" should not hang. -// "go test -c" should also produce reproducible binaries. -// "go test -c" should also appear to write a new binary every time, -// even if it's really just updating the mtime on an existing up-to-date binary. -func TestIssue6480(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - tg.makeTempdir() - tg.cd(tg.path(".")) - tg.run("test", "-c", "-test.bench=XXX", "errors") - tg.run("test", "-c", "-o", "errors2.test", "errors") - - data1, err := ioutil.ReadFile("errors.test" + exeSuffix) - tg.must(err) - data2, err := ioutil.ReadFile("errors2.test") // no exeSuffix because -o above doesn't have it - tg.must(err) - if !bytes.Equal(data1, data2) { - t.Fatalf("go test -c errors produced different binaries when run twice") - } - - start := time.Now() - tg.run("test", "-x", "-c", "-test.bench=XXX", "errors") - tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary") - info, err := os.Stat("errors.test" + exeSuffix) - if err != nil { - t.Fatal(err) - } - start = truncateLike(start, info.ModTime()) - if info.ModTime().Before(start) { - t.Fatalf("mtime of errors.test predates test -c command (%v < %v)", info.ModTime(), start) - } - - start = time.Now() - tg.run("test", "-x", "-c", "-o", "errors2.test", "errors") - tg.grepStderrNot(`[\\/]link|gccgo`, "incorrectly relinked up-to-date test binary") - info, err = os.Stat("errors2.test") - if err != nil { - t.Fatal(err) - } - start = truncateLike(start, info.ModTime()) - if info.ModTime().Before(start) { - t.Fatalf("mtime of errors2.test predates test -c command (%v < %v)", info.ModTime(), start) - } -} - -// truncateLike returns the result of truncating t to the apparent precision of p. -func truncateLike(t, p time.Time) time.Time { - nano := p.UnixNano() - d := 1 * time.Nanosecond - for nano%int64(d) == 0 && d < 1*time.Second { - d *= 10 - } - for nano%int64(d) == 0 && d < 2*time.Second { - d *= 2 - } - return t.Truncate(d) -} - // cmd/cgo: undefined reference when linking a C-library using gccgo func TestIssue7573(t *testing.T) { if !canCgo { diff --git a/src/cmd/go/testdata/script/build_issue6480.txt b/src/cmd/go/testdata/script/build_issue6480.txt new file mode 100644 index 00000000000000..857f364e817430 --- /dev/null +++ b/src/cmd/go/testdata/script/build_issue6480.txt @@ -0,0 +1,125 @@ +# "go test -c -test.bench=XXX errors" should not hang. +# "go test -c" should also produce reproducible binaries. +# "go test -c" should also appear to write a new binary every time, +# even if it's really just updating the mtime on an existing up-to-date binary. + +[gccgo] skip +[short] skip + +# Install some commands to compare mtimes +env GOBIN=$WORK/tmp/bin +go install now mtime before + +# Initial builds +go test -c -test.bench=XXX errors +go test -c -o errors2.test errors +cmp errors.test$GOEXE errors2.test # // errors2.test has no exeSuffix because -o above doesn't have it + +# Check errors.test mtime is updated +exec $GOBIN/now +cp stdout start_time.txt +go test -x -c -test.bench=XXX errors +! stderr '[\\/]link|gccgo' # make sure up-to-date test binary is not relinked +exec $GOBIN/mtime errors.test$GOEXE +cp stdout errors1_mod_time.txt +exec $GOBIN/before start_time.txt errors1_mod_time.txt +rm start_time.txt errors1_mod_time.txt + +# Check errors2.test mtime is updated +exec $GOBIN/now +cp stdout start_time.txt +go test -x -c -o errors2.test errors +! stderr '[\\/]link|gccgo' # make sure up-to-date test binary is not relinked +exec $GOBIN/mtime errors2.test +cp stdout errors2_mod_time.txt +exec $GOBIN/before start_time.txt errors2_mod_time.txt + +-- now/now.go -- +// Writes time.Now() to a file +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + +func main() { + if err := json.NewEncoder(os.Stdout).Encode(time.Now()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- mtime/mtime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" +) + +func main() { + info, err := os.Stat(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.NewEncoder(os.Stdout).Encode(info.ModTime()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- before/before.go -- +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "time" +) + +func truncateLike(t, p time.Time) time.Time { + nano := p.UnixNano() + d := 1 * time.Nanosecond + for nano%int64(d) == 0 && d < 1*time.Second { + d *= 10 + } + for nano%int64(d) == 0 && d < 2*time.Second { + d *= 2 + } + return t.Truncate(d) +} + +func main() { + var t1 time.Time + b1, err := ioutil.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b1, &t1); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + var t2 time.Time + b2, err := ioutil.ReadFile(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b2, &t2); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + t1 = truncateLike(t1, t2) + if !t1.Before(t2) { + fmt.Fprintf(os.Stderr, "time in %v (%v) is not before time in %v (%v)", os.Args[1], t1, os.Args[2], t2) + os.Exit(1) + } +} \ No newline at end of file