]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/{clean,test}: lock testexpire.txt
authorBryan C. Mills <bcmills@google.com>
Tue, 23 Oct 2018 19:39:07 +0000 (15:39 -0400)
committerBryan C. Mills <bcmills@google.com>
Thu, 29 Nov 2018 18:17:56 +0000 (18:17 +0000)
Also check to make sure we don't overwrite a newer timestamp with an
older one.

testexpire.txt may be written concurrently, and a partially-written
timestamp may appear much older than the actual intended one. We don't
want to re-run tests that should still be cached.

Updates #26794

Change-Id: If56348e799f0e7be3c5bc91b4a336e23ad99f791
Reviewed-on: https://go-review.googlesource.com/c/146379
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/go/internal/clean/clean.go
src/cmd/go/internal/test/test.go

index b12bd981a70a038e62299549580147e731dbdcd5..73e04960d2bbdf20a79bc63e26a78569478482a7 100644 (file)
@@ -10,6 +10,7 @@ import (
        "io/ioutil"
        "os"
        "path/filepath"
+       "strconv"
        "strings"
        "time"
 
@@ -17,6 +18,7 @@ import (
        "cmd/go/internal/cache"
        "cmd/go/internal/cfg"
        "cmd/go/internal/load"
+       "cmd/go/internal/lockedfile"
        "cmd/go/internal/modfetch"
        "cmd/go/internal/modload"
        "cmd/go/internal/work"
@@ -146,7 +148,20 @@ func runClean(cmd *base.Command, args []string) {
                // right now are to be ignored.
                dir := cache.DefaultDir()
                if dir != "off" {
-                       err := ioutil.WriteFile(filepath.Join(dir, "testexpire.txt"), []byte(fmt.Sprintf("%d\n", time.Now().UnixNano())), 0666)
+                       f, err := lockedfile.Edit(filepath.Join(dir, "testexpire.txt"))
+                       if err == nil {
+                               now := time.Now().UnixNano()
+                               buf, _ := ioutil.ReadAll(f)
+                               prev, _ := strconv.ParseInt(strings.TrimSpace(string(buf)), 10, 64)
+                               if now > prev {
+                                       if err = f.Truncate(0); err == nil {
+                                               _, err = fmt.Fprintf(f, "%d\n", now)
+                                       }
+                               }
+                               if closeErr := f.Close(); err == nil {
+                                       err = closeErr
+                               }
+                       }
                        if err != nil {
                                base.Errorf("go clean -testcache: %v", err)
                        }
index b38eb4c41dafa3127c5e31d05e4bc456ea6b052b..8dfb3df22d3b9ed4ba93d0b22d16b1550dbdac1a 100644 (file)
@@ -27,6 +27,7 @@ import (
        "cmd/go/internal/cache"
        "cmd/go/internal/cfg"
        "cmd/go/internal/load"
+       "cmd/go/internal/lockedfile"
        "cmd/go/internal/modload"
        "cmd/go/internal/str"
        "cmd/go/internal/work"
@@ -566,7 +567,7 @@ func runTest(cmd *base.Command, args []string) {
        // (We implement go clean -testcache by writing an expiration date
        // instead of searching out and deleting test result cache entries.)
        if dir := cache.DefaultDir(); dir != "off" {
-               if data, _ := ioutil.ReadFile(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' {
+               if data, _ := lockedfile.Read(filepath.Join(dir, "testexpire.txt")); len(data) > 0 && data[len(data)-1] == '\n' {
                        if t, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64); err == nil {
                                testCacheExpire = time.Unix(0, t)
                        }