From: Ian Lance Taylor Date: Thu, 11 Jun 2015 17:40:20 +0000 (-0700) Subject: cmd/go: in testsuite, sleep for less than one second if possible X-Git-Tag: go1.5beta1~288 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9850886fe97ee28b976807f9bec76217662db896;p=gostls13.git 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 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 87ff6e57f5..b34d5a86d1 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -75,6 +75,8 @@ func TestMain(m *testing.M) { case "linux", "darwin", "freebsd", "windows": canRace = canCgo && runtime.GOARCH == "amd64" } + + measureTick("./testgo" + exeSuffix) } // Don't let these environment variables confuse the test. @@ -91,6 +93,28 @@ func TestMain(m *testing.M) { 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. type testgoData struct { t *testing.T @@ -154,6 +178,13 @@ func (tg *testgoData) cd(dir string) { 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 // command. func (tg *testgoData) setenv(name, val string) { @@ -580,9 +611,7 @@ func F() {} tg.run("install", "p1") tg.wantNotStale("p1", "./testgo list mypkg claims p1 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 - // granularity of mtime on the file system. - time.Sleep(time.Second) + tg.sleep() if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil { t.Fatal(err) } else if _, err = f.WriteString(`func G() {}`); err != nil { @@ -938,6 +967,7 @@ func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) { tg.setenv("GOBIN", gobin) tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now())) + tg.sleep() tg.run("test", "main_test") tg.run("install", "main_test") tg.wantNotStale("main_test", "after go install, main listed as stale") @@ -1613,11 +1643,9 @@ func F() { foo.F() }`) tg.setenv("GOPATH", tg.path(".")) checkbar := func(desc string) { - // TODO(iant): Sleep for one "tick", where a tick is - // the granularity of mtime on the file system. - time.Sleep(time.Second) + tg.sleep() 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.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo") tg.run("build", "-v", "-i", "x/y/bar")