Skip to content

Commit 708c389

Browse files
committed
tests: cover peeking expiration
1 parent 032ecb4 commit 708c389

File tree

2 files changed

+171
-54
lines changed

2 files changed

+171
-54
lines changed

galaxycache_peek_test.go

Lines changed: 148 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ import (
1111
"github.com/vimeo/go-clocks/fake"
1212
)
1313

14-
type testHelpStrGetter func(key string) (string, error)
14+
type testHelpStrGetter func(key string) (string, BackendGetInfo, error)
1515

1616
// Get populates dest with the value identified by key
1717
// The returned data must be unversioned. That is, key must
1818
// uniquely describe the loaded data, without an implicit
1919
// current time, and without relying on cache expiration
2020
// mechanisms.
21-
func (t testHelpStrGetter) Get(_ context.Context, key string, dest Codec) error {
22-
v, err := t(key)
21+
func (t testHelpStrGetter) GetWithInfo(_ context.Context, key string, dest Codec) (BackendGetInfo, error) {
22+
v, bi, err := t(key)
2323
if err != nil {
24-
return err
24+
return BackendGetInfo{}, err
2525
}
26-
return dest.UnmarshalBinary([]byte(v))
26+
return bi, dest.UnmarshalBinary([]byte(v))
2727
}
2828

2929
func TestGalaxycacheGetWithPeek(t *testing.T) {
@@ -50,6 +50,7 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
5050
type checkStep struct {
5151
key string
5252
expVal string
53+
expExpiry time.Time
5354
expErr bool
5455
checkErr func(t testing.TB, idx int, getErr error)
5556
timeoutPeek bool // arrange for a timeout
@@ -64,10 +65,12 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
6465
includeSelf bool
6566
setClock time.Time
6667

68+
expiry time.Time
69+
6770
// getter for locally fetched values (may call t.Error/Errorf,
6871
// but not t.Fatal/Fatalf, as it might be called from another
6972
// goroutine).
70-
localGetter func(t testing.TB, key string) (string, error)
73+
localGetter func(t testing.TB, key string) (string, BackendGetInfo, error)
7174
peekModes map[string]testPeekMode // configure peek modes per-host
7275
fetchModes map[string]testFetchMode // configure fetch modes per-host
7376

@@ -79,9 +82,9 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
7982
includePeers: []int{0, 1, 2},
8083
includeSelf: true,
8184
setClock: baseTime,
82-
localGetter: func(t testing.TB, key string) (string, error) {
85+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
8386
t.Errorf("unexpected local fetch (peek should succeed on peer)")
84-
return "", fmt.Errorf("unexpected call")
87+
return "", BackendGetInfo{}, fmt.Errorf("unexpected call")
8588
},
8689
peekModes: map[string]testPeekMode{
8790
peer0Addr: testPeekModeHit,
@@ -129,13 +132,75 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
129132
peer1Addr: 1,
130133
peer2Addr: 1,
131134
},
135+
}, {
136+
name: "peeks_hit_each_peer_with_expiry",
137+
includePeers: []int{0, 1, 2},
138+
includeSelf: true,
139+
setClock: baseTime,
140+
expiry: baseTime.Add(time.Hour * 84),
141+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
142+
t.Errorf("unexpected local fetch (peek should succeed on peer)")
143+
return "", BackendGetInfo{}, fmt.Errorf("unexpected call")
144+
},
145+
peekModes: map[string]testPeekMode{
146+
peer0Addr: testPeekModeHit,
147+
peer1Addr: testPeekModeHit,
148+
peer2Addr: testPeekModeHit,
149+
},
150+
checkSteps: []checkStep{
151+
{
152+
key: chtest.FallthroughKey(self, peer0),
153+
expVal: peer0Addr + ": peek got: " + chtest.FallthroughKey(self, peer0),
154+
expExpiry: baseTime.Add(time.Hour * 84),
155+
},
156+
{
157+
// second fetch, since the key should now be in the main cache
158+
key: chtest.FallthroughKey(self, peer0),
159+
expVal: peer0Addr + ": peek got: " + chtest.FallthroughKey(self, peer0),
160+
getOpts: GetOptions{
161+
FetchMode: FetchModePeek,
162+
},
163+
expExpiry: baseTime.Add(time.Hour * 84),
164+
},
165+
{
166+
key: chtest.FallthroughKey(self, peer1),
167+
expVal: peer1Addr + ": peek got: " + chtest.FallthroughKey(self, peer1),
168+
expExpiry: baseTime.Add(time.Hour * 84),
169+
},
170+
{
171+
key: chtest.FallthroughKey(self, peer1),
172+
expVal: peer1Addr + ": peek got: " + chtest.FallthroughKey(self, peer1),
173+
getOpts: GetOptions{
174+
FetchMode: FetchModePeek,
175+
},
176+
expExpiry: baseTime.Add(time.Hour * 84),
177+
},
178+
{
179+
key: chtest.FallthroughKey(self, peer2),
180+
expVal: peer2Addr + ": peek got: " + chtest.FallthroughKey(self, peer2),
181+
expExpiry: baseTime.Add(time.Hour * 84),
182+
},
183+
{
184+
key: chtest.FallthroughKey(self, peer2),
185+
expVal: peer2Addr + ": peek got: " + chtest.FallthroughKey(self, peer2),
186+
getOpts: GetOptions{
187+
FetchMode: FetchModePeek,
188+
},
189+
expExpiry: baseTime.Add(time.Hour * 84),
190+
},
191+
},
192+
expPeeks: map[string]int{
193+
peer0Addr: 1,
194+
peer1Addr: 1,
195+
peer2Addr: 1,
196+
},
132197
}, {
133198
name: "peeks_timeout_each_peer",
134199
includePeers: []int{0, 1, 2},
135200
includeSelf: true,
136201
setClock: baseTime,
137-
localGetter: func(t testing.TB, key string) (string, error) {
138-
return "fizzlebat: " + key, nil
202+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
203+
return "fizzlebat: " + key, BackendGetInfo{}, nil
139204
},
140205
peekModes: map[string]testPeekMode{
141206
peer0Addr: testPeekModeStallCtx,
@@ -169,8 +234,8 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
169234
includePeers: []int{0, 1, 2},
170235
includeSelf: true,
171236
setClock: baseTime,
172-
localGetter: func(t testing.TB, key string) (string, error) {
173-
return "fizzlebat: " + key, nil
237+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
238+
return "fizzlebat: " + key, BackendGetInfo{Expiration: baseTime.Add(time.Hour * 3)}, nil
174239
},
175240
peekModes: map[string]testPeekMode{
176241
peer0Addr: testPeekModeMiss,
@@ -182,16 +247,19 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
182247
key: chtest.FallthroughKey(self, peer0),
183248
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer0),
184249
timeoutPeek: false,
250+
expExpiry: baseTime.Add(time.Hour * 3),
185251
},
186252
{
187253
key: chtest.FallthroughKey(self, peer1),
188254
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer1),
189255
timeoutPeek: false,
256+
expExpiry: baseTime.Add(time.Hour * 3),
190257
},
191258
{
192259
key: chtest.FallthroughKey(self, peer2),
193260
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer2),
194261
timeoutPeek: false,
262+
expExpiry: baseTime.Add(time.Hour * 3),
195263
},
196264
},
197265
expPeeks: map[string]int{
@@ -200,12 +268,12 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
200268
peer2Addr: 1,
201269
},
202270
}, {
203-
name: "peeks_error_each_peer",
271+
name: "peeks_error_each_peer_with_expiry",
204272
includePeers: []int{0, 1, 2},
205273
includeSelf: true,
206274
setClock: baseTime,
207-
localGetter: func(t testing.TB, key string) (string, error) {
208-
return "fizzlebat: " + key, nil
275+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
276+
return "fizzlebat: " + key, BackendGetInfo{Expiration: baseTime.Add(time.Minute * 20)}, nil
209277
},
210278
peekModes: map[string]testPeekMode{
211279
peer0Addr: testPeekModeFail,
@@ -217,16 +285,19 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
217285
key: chtest.FallthroughKey(self, peer0),
218286
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer0),
219287
timeoutPeek: false,
288+
expExpiry: baseTime.Add(time.Minute * 20),
220289
},
221290
{
222291
key: chtest.FallthroughKey(self, peer1),
223292
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer1),
224293
timeoutPeek: false,
294+
expExpiry: baseTime.Add(time.Minute * 20),
225295
},
226296
{
227297
key: chtest.FallthroughKey(self, peer2),
228298
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer2),
229299
timeoutPeek: false,
300+
expExpiry: baseTime.Add(time.Minute * 20),
230301
},
231302
},
232303
expPeeks: map[string]int{
@@ -239,8 +310,43 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
239310
includePeers: []int{0, 1, 2},
240311
includeSelf: true,
241312
setClock: baseTime.Add(warmPeriod),
242-
localGetter: func(t testing.TB, key string) (string, error) {
243-
return "fizzlebat: " + key, nil
313+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
314+
return "fizzlebat: " + key, BackendGetInfo{}, nil
315+
},
316+
peekModes: map[string]testPeekMode{
317+
peer0Addr: testPeekModeHit,
318+
peer1Addr: testPeekModeHit,
319+
peer2Addr: testPeekModeHit,
320+
},
321+
checkSteps: []checkStep{
322+
{
323+
key: chtest.FallthroughKey(self, peer0),
324+
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer0),
325+
timeoutPeek: false,
326+
},
327+
{
328+
key: chtest.FallthroughKey(self, peer1),
329+
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer1),
330+
timeoutPeek: false,
331+
},
332+
{
333+
key: chtest.FallthroughKey(self, peer2),
334+
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer2),
335+
timeoutPeek: false,
336+
},
337+
},
338+
expPeeks: map[string]int{
339+
peer0Addr: 0,
340+
peer1Addr: 0,
341+
peer2Addr: 0,
342+
},
343+
}, {
344+
name: "no_peeks_past_warm_expiring",
345+
includePeers: []int{0, 1, 2},
346+
includeSelf: true,
347+
setClock: baseTime.Add(warmPeriod),
348+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
349+
return "fizzlebat: " + key, BackendGetInfo{Expiration: baseTime.Add(time.Hour)}, nil
244350
},
245351
peekModes: map[string]testPeekMode{
246352
peer0Addr: testPeekModeHit,
@@ -252,16 +358,19 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
252358
key: chtest.FallthroughKey(self, peer0),
253359
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer0),
254360
timeoutPeek: false,
361+
expExpiry: baseTime.Add(time.Hour),
255362
},
256363
{
257364
key: chtest.FallthroughKey(self, peer1),
258365
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer1),
259366
timeoutPeek: false,
367+
expExpiry: baseTime.Add(time.Hour),
260368
},
261369
{
262370
key: chtest.FallthroughKey(self, peer2),
263371
expVal: "fizzlebat: " + chtest.FallthroughKey(self, peer2),
264372
timeoutPeek: false,
373+
expExpiry: baseTime.Add(time.Hour),
265374
},
266375
},
267376
expPeeks: map[string]int{
@@ -274,9 +383,9 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
274383
includePeers: []int{0, 1, 2},
275384
includeSelf: true,
276385
setClock: baseTime.Add(warmPeriod),
277-
localGetter: func(t testing.TB, key string) (string, error) {
386+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
278387
t.Errorf("unexpected local fetch (fetch should fail with NotFound on peer)")
279-
return "", fmt.Errorf("unexpected call")
388+
return "", BackendGetInfo{}, fmt.Errorf("unexpected call")
280389
},
281390
peekModes: map[string]testPeekMode{
282391
peer0Addr: testPeekModeMiss,
@@ -333,8 +442,8 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
333442
includePeers: []int{0, 1, 2},
334443
includeSelf: true,
335444
setClock: baseTime.Add(warmPeriod),
336-
localGetter: func(t testing.TB, key string) (string, error) {
337-
return "fizzlebat: " + key, nil
445+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
446+
return "fizzlebat: " + key, BackendGetInfo{}, nil
338447
},
339448
peekModes: map[string]testPeekMode{
340449
peer0Addr: testPeekModeHit,
@@ -382,9 +491,9 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
382491
includePeers: []int{0, 1, 2},
383492
includeSelf: true,
384493
setClock: baseTime.Add(warmPeriod),
385-
localGetter: func(t testing.TB, key string) (string, error) {
494+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
386495
t.Errorf("unexpected local fetch (fetch should fail with NotFound on peer)")
387-
return "", fmt.Errorf("unexpected call")
496+
return "", BackendGetInfo{}, fmt.Errorf("unexpected call")
388497
},
389498
peekModes: map[string]testPeekMode{
390499
peer0Addr: testPeekModeMiss,
@@ -450,8 +559,8 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
450559
includePeers: []int{0, 1, 2},
451560
includeSelf: true,
452561
setClock: baseTime.Add(warmPeriod),
453-
localGetter: func(t testing.TB, key string) (string, error) {
454-
return "", TrivialNotFoundErr{}
562+
localGetter: func(t testing.TB, key string) (string, BackendGetInfo, error) {
563+
return "", BackendGetInfo{}, TrivialNotFoundErr{}
455564
},
456565
peekModes: map[string]testPeekMode{
457566
peer0Addr: testPeekModeMiss,
@@ -518,12 +627,13 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
518627
fc := fake.NewClock(baseTime)
519628

520629
fp := TestProtocol{
521-
TestFetchers: map[string]*TestFetcher{},
522-
dialFails: map[string]struct{}{},
523-
peekModes: tbl.peekModes,
524-
fetchModes: tbl.fetchModes,
525-
hostInVal: true,
526-
clk: fc,
630+
TestFetchers: map[string]*TestFetcher{},
631+
dialFails: map[string]struct{}{},
632+
peekModes: tbl.peekModes,
633+
fetchModes: tbl.fetchModes,
634+
hostInVal: true,
635+
clk: fc,
636+
keyExpiration: tbl.expiry,
527637
}
528638
u := NewUniverse(&fp, self, WithHashOpts(
529639
&HashOptions{Replicas: chArgs.NSegsPerKey, HashFn: chArgs.HashFunc}),
@@ -535,12 +645,12 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
535645
}
536646
defer u.Shutdown()
537647

538-
getter := testHelpStrGetter(func(key string) (string, error) {
648+
getter := testHelpStrGetter(func(key string) (string, BackendGetInfo, error) {
539649
return tbl.localGetter(t, key)
540650
})
541651

542652
peekTimeout := time.Millisecond * 3
543-
g := u.NewGalaxy("easy come; easy go", 256, getter, WithPreviousPeerPeeking(PeekPeerCfg{
653+
g := u.NewGalaxyWithBackendInfo("easy come; easy go", 256, getter, WithPreviousPeerPeeking(PeekPeerCfg{
544654
WarmTime: warmPeriod,
545655
PeekTimeout: peekTimeout},
546656
))
@@ -552,13 +662,14 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
552662
for i, step := range tbl.checkSteps {
553663
c := StringCodec("")
554664
var getErr error
665+
var getInfo GetInfo
555666
if !step.timeoutPeek {
556-
_, getErr = g.GetWithOptions(ctx, step.getOpts, step.key, &c)
667+
getInfo, getErr = g.GetWithOptions(ctx, step.getOpts, step.key, &c)
557668
} else {
558669
doneCh := make(chan struct{})
559670
go func() {
560671
defer close(doneCh)
561-
_, getErr = g.GetWithOptions(ctx, step.getOpts, step.key, &c)
672+
getInfo, getErr = g.GetWithOptions(ctx, step.getOpts, step.key, &c)
562673
}()
563674
fc.AwaitSleepers(1)
564675
fc.Advance(peekTimeout)
@@ -575,6 +686,8 @@ func TestGalaxycacheGetWithPeek(t *testing.T) {
575686
}
576687
t.Errorf("unexpected error fetching step %d; key %q: %s", i, step.key, getErr)
577688
continue
689+
} else if !getInfo.Expiry.Equal(step.expExpiry) {
690+
t.Errorf("unexpected expiry: %s; expected %s", getInfo.Expiry, step.expExpiry)
578691
}
579692
if string(c) != step.expVal {
580693
t.Errorf("unexpected value for key %q in step %d\nwant: %q\n got %q", step.key, i, step.expVal, c)

0 commit comments

Comments
 (0)