Jelajahi Sumber

acme/autocert: fix data race in tests

Change-Id: I0b5001db9a3541592b4ac0d4bba760b974f9b1a0
Reviewed-on: https://go-review.googlesource.com/28415
Reviewed-by: Alex Vaghin <ddos@google.com>
Brad Fitzpatrick 9 tahun lalu
induk
melakukan
9e590154d2
2 mengubah file dengan 20 tambahan dan 4 penghapusan
  1. 18 2
      acme/autocert/autocert.go
  2. 2 2
      acme/autocert/renewal_test.go

+ 18 - 2
acme/autocert/autocert.go

@@ -25,6 +25,7 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
+	"sync/atomic"
 	"time"
 	"time"
 
 
 	"golang.org/x/crypto/acme"
 	"golang.org/x/crypto/acme"
@@ -35,7 +36,7 @@ import (
 var pseudoRand *lockedMathRand
 var pseudoRand *lockedMathRand
 
 
 func init() {
 func init() {
-	src := mathrand.NewSource(timeNow().UnixNano())
+	src := mathrand.NewSource(time.Now().UnixNano())
 	pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
 	pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
 }
 }
 
 
@@ -718,8 +719,23 @@ func (r *lockedMathRand) int63n(max int64) int64 {
 	return n
 	return n
 }
 }
 
 
+func timeNow() time.Time {
+	return clock.Load().(func() time.Time)()
+}
+
 // for easier testing
 // for easier testing
 var (
 var (
-	timeNow          = time.Now
+	// clock stores the time.Now func pointer or a fake
+	// thereof. It's an atomic.Value because tests weren't waiting
+	// for goroutines to shut down during completing causing races.
+	// TODO(crhym3,bradfitz): make tests more well-behaved, and
+	// then revert this back to just a func() time.Time type.
+	// This was the easier quick fix.
+	clock atomic.Value
+
 	testDidRenewLoop = func(next time.Duration, err error) {}
 	testDidRenewLoop = func(next time.Duration, err error) {}
 )
 )
+
+func init() {
+	clock.Store(time.Now)
+}

+ 2 - 2
acme/autocert/renewal_test.go

@@ -22,8 +22,8 @@ import (
 
 
 func TestRenewalNext(t *testing.T) {
 func TestRenewalNext(t *testing.T) {
 	now := time.Now()
 	now := time.Now()
-	timeNow = func() time.Time { return now }
-	defer func() { timeNow = time.Now }()
+	clock.Store(func() time.Time { return now })
+	defer clock.Store(time.Now)
 
 
 	man := &Manager{RenewBefore: 7 * 24 * time.Hour}
 	man := &Manager{RenewBefore: 7 * 24 * time.Hour}
 	tt := []struct {
 	tt := []struct {