acme/autocert: fix racy tests

memCache used an unsynchronized map, which failed go test -race. Add a
mutex and constructor function to fix it.

Change-Id: Iddaa492ea1e3d7747965c6423368baa6556402ed
Reviewed-on: https://go-review.googlesource.com/36545
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/acme/autocert/autocert_test.go b/acme/autocert/autocert_test.go
index 4bcd6d5..7afb213 100644
--- a/acme/autocert/autocert_test.go
+++ b/acme/autocert/autocert_test.go
@@ -22,6 +22,7 @@
 	"net/http"
 	"net/http/httptest"
 	"reflect"
+	"sync"
 	"testing"
 	"time"
 
@@ -51,26 +52,44 @@
 	]
 }`))
 
-type memCache map[string][]byte
+type memCache struct {
+	mu      sync.Mutex
+	keyData map[string][]byte
+}
 
-func (m memCache) Get(ctx context.Context, key string) ([]byte, error) {
-	v, ok := m[key]
+func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+
+	v, ok := m.keyData[key]
 	if !ok {
 		return nil, ErrCacheMiss
 	}
 	return v, nil
 }
 
-func (m memCache) Put(ctx context.Context, key string, data []byte) error {
-	m[key] = data
+func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+
+	m.keyData[key] = data
 	return nil
 }
 
-func (m memCache) Delete(ctx context.Context, key string) error {
-	delete(m, key)
+func (m *memCache) Delete(ctx context.Context, key string) error {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+
+	delete(m.keyData, key)
 	return nil
 }
 
+func newMemCache() *memCache {
+	return &memCache{
+		keyData: make(map[string][]byte),
+	}
+}
+
 func dummyCert(pub interface{}, san ...string) ([]byte, error) {
 	return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
 }
@@ -124,7 +143,7 @@
 func TestGetCertificate_ForceRSA(t *testing.T) {
 	man := &Manager{
 		Prompt:   AcceptTOS,
-		Cache:    make(memCache),
+		Cache:    newMemCache(),
 		ForceRSA: true,
 	}
 	defer man.stopRenew()
@@ -280,8 +299,7 @@
 }
 
 func TestAccountKeyCache(t *testing.T) {
-	cache := make(memCache)
-	m := Manager{Cache: cache}
+	m := Manager{Cache: newMemCache()}
 	ctx := context.Background()
 	k1, err := m.accountKey(ctx)
 	if err != nil {
@@ -315,8 +333,7 @@
 		PrivateKey:  privKey,
 	}
 
-	cache := make(memCache)
-	man := &Manager{Cache: cache}
+	man := &Manager{Cache: newMemCache()}
 	defer man.stopRenew()
 	if err := man.cachePut("example.org", tlscert); err != nil {
 		t.Fatalf("man.cachePut: %v", err)
diff --git a/acme/autocert/renewal_test.go b/acme/autocert/renewal_test.go
index d1ec52f..10c811a 100644
--- a/acme/autocert/renewal_test.go
+++ b/acme/autocert/renewal_test.go
@@ -111,7 +111,7 @@
 	}
 	man := &Manager{
 		Prompt:      AcceptTOS,
-		Cache:       make(memCache),
+		Cache:       newMemCache(),
 		RenewBefore: 24 * time.Hour,
 		Client: &acme.Client{
 			Key:          key,