Commit 9850886f authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/go: in testsuite, sleep for less than one second if possible

Examine the mtime of an existing file to guess a length of time to
sleep to ensure a different mtime.

Change-Id: I9e8b5c9486f5c3c8bd63125e3ed4763ce1ba767d
Reviewed-on: https://go-review.googlesource.com/10932
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent d57c889a
...@@ -75,6 +75,8 @@ func TestMain(m *testing.M) { ...@@ -75,6 +75,8 @@ func TestMain(m *testing.M) {
case "linux", "darwin", "freebsd", "windows": case "linux", "darwin", "freebsd", "windows":
canRace = canCgo && runtime.GOARCH == "amd64" canRace = canCgo && runtime.GOARCH == "amd64"
} }
measureTick("./testgo" + exeSuffix)
} }
// Don't let these environment variables confuse the test. // Don't let these environment variables confuse the test.
...@@ -91,6 +93,28 @@ func TestMain(m *testing.M) { ...@@ -91,6 +93,28 @@ func TestMain(m *testing.M) {
os.Exit(r) os.Exit(r)
} }
// The length of an mtime tick on this system. This is an estimate of
// how long we need to sleep to ensure that the mtime of two files is
// different.
var mtimeTick time.Duration
// measureTick sets mtimeTick by looking at the rounding of the mtime
// of a file.
func measureTick(path string) {
st, err := os.Stat(path)
if err != nil {
// Default to one second, the most conservative value.
mtimeTick = time.Second
return
}
mtime := st.ModTime()
t := time.Microsecond
for mtime.Round(t).Equal(mtime) && t < time.Second {
t *= 10
}
mtimeTick = t
}
// Manage a single run of the testgo binary. // Manage a single run of the testgo binary.
type testgoData struct { type testgoData struct {
t *testing.T t *testing.T
...@@ -154,6 +178,13 @@ func (tg *testgoData) cd(dir string) { ...@@ -154,6 +178,13 @@ func (tg *testgoData) cd(dir string) {
tg.must(os.Chdir(dir)) tg.must(os.Chdir(dir))
} }
// sleep sleeps for one tick, where a tick is a conservative estimate
// of how long it takes for a file modification to get a different
// mtime.
func (tg *testgoData) sleep() {
time.Sleep(mtimeTick)
}
// setenv sets an environment variable to use when running the test go // setenv sets an environment variable to use when running the test go
// command. // command.
func (tg *testgoData) setenv(name, val string) { func (tg *testgoData) setenv(name, val string) {
...@@ -580,9 +611,7 @@ func F() {} ...@@ -580,9 +611,7 @@ func F() {}
tg.run("install", "p1") tg.run("install", "p1")
tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly") tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly")
tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly") tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly")
// TODO(iant): Sleep for one "tick", where a tick is the tg.sleep()
// granularity of mtime on the file system.
time.Sleep(time.Second)
if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil { if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil {
t.Fatal(err) t.Fatal(err)
} else if _, err = f.WriteString(`func G() {}`); err != nil { } else if _, err = f.WriteString(`func G() {}`); err != nil {
...@@ -938,6 +967,7 @@ func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) { ...@@ -938,6 +967,7 @@ func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) {
tg.setenv("GOBIN", gobin) tg.setenv("GOBIN", gobin)
tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata"))
tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now())) tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now()))
tg.sleep()
tg.run("test", "main_test") tg.run("test", "main_test")
tg.run("install", "main_test") tg.run("install", "main_test")
tg.wantNotStale("main_test", "after go install, main listed as stale") tg.wantNotStale("main_test", "after go install, main listed as stale")
...@@ -1613,11 +1643,9 @@ func F() { foo.F() }`) ...@@ -1613,11 +1643,9 @@ func F() { foo.F() }`)
tg.setenv("GOPATH", tg.path(".")) tg.setenv("GOPATH", tg.path("."))
checkbar := func(desc string) { checkbar := func(desc string) {
// TODO(iant): Sleep for one "tick", where a tick is tg.sleep()
// the granularity of mtime on the file system.
time.Sleep(time.Second)
tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now())) tg.must(os.Chtimes(tg.path("src/x/y/foo/foo.go"), time.Now(), time.Now()))
time.Sleep(time.Second) tg.sleep()
tg.run("build", "-v", "-i", "x/y/bar") tg.run("build", "-v", "-i", "x/y/bar")
tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo") tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo")
tg.run("build", "-v", "-i", "x/y/bar") tg.run("build", "-v", "-i", "x/y/bar")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment