forked from adamlaska/boulder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache_test.go
More file actions
145 lines (114 loc) · 4.55 KB
/
cache_test.go
File metadata and controls
145 lines (114 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package wfe2
import (
"context"
"errors"
"testing"
"time"
"github.com/jmhodges/clock"
corepb "github.com/letsencrypt/boulder/core/proto"
"github.com/letsencrypt/boulder/metrics"
sapb "github.com/letsencrypt/boulder/sa/proto"
"github.com/letsencrypt/boulder/test"
"google.golang.org/grpc"
)
type recordingBackend struct {
requests []int64
}
func (rb *recordingBackend) GetRegistration(
ctx context.Context,
regID *sapb.RegistrationID,
opts ...grpc.CallOption,
) (*corepb.Registration, error) {
rb.requests = append(rb.requests, regID.Id)
return &corepb.Registration{
Id: regID.Id,
Contact: []string{"example@example.com"},
}, nil
}
func TestCacheAddRetrieve(t *testing.T) {
ctx := context.Background()
backend := &recordingBackend{}
cache := NewAccountCache(backend, 10, time.Second, clock.NewFake(), metrics.NoopRegisterer)
result, err := cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, result.Id, int64(1234))
test.AssertEquals(t, len(backend.requests), 1)
// Request it again. This should hit the cache so our backend should not see additional requests.
result, err = cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, result.Id, int64(1234))
test.AssertEquals(t, len(backend.requests), 1)
}
// Test that the cache copies values before giving them out, so code that receives a cached
// value can't modify the cache's contents.
func TestCacheCopy(t *testing.T) {
ctx := context.Background()
backend := &recordingBackend{}
cache := NewAccountCache(backend, 10, time.Second, clock.NewFake(), metrics.NoopRegisterer)
_, err := cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, len(backend.requests), 1)
test.AssertEquals(t, cache.cache.Len(), 1)
// Request it again. This should hit the cache.
result, err := cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, len(backend.requests), 1)
// Modify a pointer value inside the result
result.Contact[0] = "different@example.com"
result, err = cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, len(backend.requests), 1)
test.AssertDeepEquals(t, result.Contact, []string{"example@example.com"})
}
// Test that the cache expires values.
func TestCacheExpires(t *testing.T) {
ctx := context.Background()
backend := &recordingBackend{}
clk := clock.NewFake()
cache := NewAccountCache(backend, 10, time.Second, clk, metrics.NoopRegisterer)
_, err := cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, len(backend.requests), 1)
// Request it again. This should hit the cache.
_, err = cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, len(backend.requests), 1)
test.AssertEquals(t, cache.cache.Len(), 1)
// "Sleep" 10 seconds to expire the entry
clk.Sleep(10 * time.Second)
// This should not hit the cache
_, err = cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertNotError(t, err, "getting registration")
test.AssertEquals(t, len(backend.requests), 2)
}
type wrongIDBackend struct{}
func (wib wrongIDBackend) GetRegistration(
ctx context.Context,
regID *sapb.RegistrationID,
opts ...grpc.CallOption,
) (*corepb.Registration, error) {
return &corepb.Registration{
Id: regID.Id + 1,
Contact: []string{"example@example.com"},
}, nil
}
func TestWrongId(t *testing.T) {
ctx := context.Background()
cache := NewAccountCache(wrongIDBackend{}, 10, time.Second, clock.NewFake(), metrics.NoopRegisterer)
_, err := cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertError(t, err, "expected error when backend returns wrong ID")
}
type errorBackend struct{}
func (eb errorBackend) GetRegistration(ctx context.Context,
regID *sapb.RegistrationID,
opts ...grpc.CallOption,
) (*corepb.Registration, error) {
return nil, errors.New("some error")
}
func TestErrorPassthrough(t *testing.T) {
ctx := context.Background()
cache := NewAccountCache(errorBackend{}, 10, time.Second, clock.NewFake(), metrics.NoopRegisterer)
_, err := cache.GetRegistration(ctx, &sapb.RegistrationID{Id: 1234})
test.AssertError(t, err, "expected error when backend errors")
test.AssertEquals(t, err.Error(), "some error")
}