@@ -27,19 +27,22 @@ import (
2727 "github.com/trickstercache/trickster/v2/pkg/cache/filesystem"
2828 fso "github.com/trickstercache/trickster/v2/pkg/cache/filesystem/options"
2929 "github.com/trickstercache/trickster/v2/pkg/cache/index/options"
30- "github.com/trickstercache/trickster/v2/pkg/cache/memory"
3130 co "github.com/trickstercache/trickster/v2/pkg/cache/options"
3231 "github.com/trickstercache/trickster/v2/pkg/cache/status"
3332)
3433
3534func TestIndexedClient (t * testing.T ) {
36- const provider = "memory"
37-
38- // init memory cache client
39- cacheConfig := co.Options {Provider : provider }
40- mc := memory .New ("test" , & cacheConfig )
41-
4235 t .Run ("basic" , func (t * testing.T ) {
36+ const provider = "filesystem"
37+
38+ // init filesystem cache client
39+ cacheConfig := co.Options {
40+ Provider : provider ,
41+ Filesystem : & fso.Options {
42+ CachePath : t .TempDir (),
43+ },
44+ }
45+ fsc := filesystem .NewCache ("test" , & cacheConfig )
4346 // init indexed client
4447 ic := NewIndexedClient ("test" , provider , & options.Options {
4548 ReapInterval : time .Second * time .Duration (10 ),
@@ -49,7 +52,7 @@ func TestIndexedClient(t *testing.T) {
4952 MaxSizeBytes : 100 ,
5053 MaxSizeBackoffBytes : 30 ,
5154 IndexExpiry : 1 * time .Hour ,
52- }, mc )
55+ }, fsc )
5356 t .Log ("basic" )
5457 state := getIndexedClientState (ic )
5558 require .Equal (t , int64 (0 ), state .ObjectCount )
@@ -65,7 +68,8 @@ func TestIndexedClient(t *testing.T) {
6568
6669 // store & retrieve
6770 val := []byte ("bar" )
68- require .NoError (t , ic .Store (key , val , 0 ))
71+ ttl := 60 * time .Second
72+ require .NoError (t , ic .Store (key , val , ttl ))
6973
7074 state = getIndexedClientState (ic )
7175 require .Equal (t , int64 (1 ), state .ObjectCount )
@@ -95,6 +99,16 @@ func TestIndexedClient(t *testing.T) {
9599 })
96100
97101 t .Run ("atime" , func (t * testing.T ) {
102+ const provider = "filesystem"
103+
104+ // init filesystem cache client
105+ cacheConfig := co.Options {
106+ Provider : provider ,
107+ Filesystem : & fso.Options {
108+ CachePath : t .TempDir (),
109+ },
110+ }
111+ fsc := filesystem .NewCache ("test" , & cacheConfig )
98112 // init indexed client
99113 ic := NewIndexedClient ("test" , provider , & options.Options {
100114 ReapInterval : time .Second * time .Duration (10 ),
@@ -104,11 +118,12 @@ func TestIndexedClient(t *testing.T) {
104118 MaxSizeBytes : 100 ,
105119 MaxSizeBackoffBytes : 30 ,
106120 IndexExpiry : 1 * time .Hour ,
107- }, mc )
121+ }, fsc )
108122
109123 // store & retrieve
110124 val := []byte ("bar" )
111- require .NoError (t , ic .Store ("foo" , val , 0 ))
125+ ttl := 60 * time .Second
126+ require .NoError (t , ic .Store ("foo" , val , ttl ))
112127 // expect atime to be set
113128 o , ok := ic .Objects .Load ("foo" )
114129 require .True (t , ok )
@@ -202,6 +217,16 @@ func TestIndexedClient(t *testing.T) {
202217 // test the actual flush loop by forcing it to flush, this utilizes goroutines
203218 // and should detect more potential race conditions vs the existing flush tests that use
204219 // flush internal methods
220+
221+ // Create fresh filesystem cache for this subtest
222+ freshCacheConfig := co.Options {
223+ Provider : provider ,
224+ Filesystem : & fso.Options {
225+ CachePath : t .TempDir (),
226+ },
227+ }
228+ freshFs := filesystem .NewCache ("flushTest" , & freshCacheConfig )
229+ ttl := 60 * time .Second
205230 ic1 := NewIndexedClient ("flushTest" , provider , & options.Options {
206231 ReapInterval : time .Second * 60 * 60 * 24 ,
207232 FlushInterval : time .Second * 60 * 60 * 24 ,
@@ -210,12 +235,12 @@ func TestIndexedClient(t *testing.T) {
210235 MaxSizeBytes : 100 ,
211236 MaxSizeBackoffBytes : 30 ,
212237 IndexExpiry : 1 * time .Hour ,
213- }, mc )
238+ }, freshFs )
214239 defer ic1 .Close ()
215240 for i := range 5 {
216241 index := fmt .Sprintf ("%d" , i )
217242 key := "key." + index
218- require .NoError (t , ic1 .Store (key , []byte ("value1." + index ), 0 ))
243+ require .NoError (t , ic1 .Store (key , []byte ("value1." + index ), ttl ))
219244 }
220245 _ , s , err := ic1 .Client .Retrieve (IndexKey )
221246 require .Equal (t , cache .ErrKNF , err )
@@ -231,6 +256,16 @@ func TestIndexedClient(t *testing.T) {
231256 // test the actual reap loop by forcing it to reap, this utilizes goroutines
232257 // and should detect more potential race conditions vs the existing reap tests that use
233258 // reap internal methods
259+
260+ // Create fresh filesystem cache for this subtest
261+ freshCacheConfig := co.Options {
262+ Provider : provider ,
263+ Filesystem : & fso.Options {
264+ CachePath : t .TempDir (),
265+ },
266+ }
267+ freshFs := filesystem .NewCache ("reapTest" , & freshCacheConfig )
268+ ttl := 60 * time .Second
234269 ic2 := NewIndexedClient ("reapTest" , provider , & options.Options {
235270 ReapInterval : time .Second * 60 * 60 * 24 ,
236271 FlushInterval : time .Second * 60 * 60 * 24 ,
@@ -239,14 +274,14 @@ func TestIndexedClient(t *testing.T) {
239274 MaxSizeBytes : 10000 ,
240275 MaxSizeBackoffBytes : 300 ,
241276 IndexExpiry : 1 * time .Hour ,
242- }, mc )
277+ }, freshFs )
243278 defer ic2 .Close ()
244279
245280 // write 5 objects, expect 5 objects
246281 for i := range 5 {
247282 index := fmt .Sprintf ("%d" , i )
248283 key := "key." + index
249- require .NoError (t , ic2 .Store (key , []byte ("value1." + index ), 0 ))
284+ require .NoError (t , ic2 .Store (key , []byte ("value1." + index ), ttl ))
250285 }
251286 state := getIndexedClientState (ic2 )
252287 require .Equal (t , int64 (5 ), state .ObjectCount )
@@ -262,7 +297,7 @@ func TestIndexedClient(t *testing.T) {
262297 for i := range 5 {
263298 index := fmt .Sprintf ("%d" , i )
264299 key := "another.key." + index
265- require .NoError (t , ic2 .Store (key , []byte ("value1." + index ), 0 ))
300+ require .NoError (t , ic2 .Store (key , []byte ("value1." + index ), ttl ))
266301 }
267302 state = getIndexedClientState (ic2 )
268303 require .Equal (t , int64 (10 ), state .ObjectCount )
@@ -276,90 +311,100 @@ func TestIndexedClient(t *testing.T) {
276311 })
277312 })
278313
279- /* converting */
280- // init indexed client
281- ic := NewIndexedClient ("test" , provider , & options.Options {
282- ReapInterval : time .Second * time .Duration (10 ),
283- FlushInterval : time .Second * time .Duration (10 ),
284- MaxSizeObjects : 5 ,
285- MaxSizeBackoffObjects : 3 ,
286- MaxSizeBytes : 100 ,
287- MaxSizeBackoffBytes : 30 ,
288- IndexExpiry : 1 * time .Hour ,
289- }, mc , func (ico * IndexedClientOptions ) {
290- ico .NeedsFlushInterval = true
291- ico .NeedsReapInterval = true
292- })
293- t .Log ("wip, converting prior test" )
294- ttl := 60 * time .Second
314+ t .Run ("reap eviction" , func (t * testing.T ) {
315+ const provider = "filesystem"
295316
296- // add expired key to cover the case that the reaper remove it
297- ic .Store ("test.1" , []byte ("test_value" ), ttl )
317+ // init filesystem cache client
318+ cacheConfig := co.Options {
319+ Provider : provider ,
320+ Filesystem : & fso.Options {
321+ CachePath : t .TempDir (),
322+ },
323+ }
324+ fsc := filesystem .NewCache ("test" , & cacheConfig )
325+ // init indexed client
326+ ic := NewIndexedClient ("test" , provider , & options.Options {
327+ ReapInterval : time .Second * time .Duration (10 ),
328+ FlushInterval : time .Second * time .Duration (10 ),
329+ MaxSizeObjects : 5 ,
330+ MaxSizeBackoffObjects : 3 ,
331+ MaxSizeBytes : 100 ,
332+ MaxSizeBackoffBytes : 30 ,
333+ IndexExpiry : 1 * time .Hour ,
334+ }, fsc , func (ico * IndexedClientOptions ) {
335+ ico .NeedsFlushInterval = true
336+ ico .NeedsReapInterval = true
337+ })
338+ ttl := 60 * time .Second
298339
299- // add key with no expiration which should not be reaped
300- ic .Store ("test.2 " , []byte ("test_value" ), ttl )
340+ // add expired key to cover the case that the reaper remove it
341+ ic .Store ("test.1 " , []byte ("test_value" ), ttl )
301342
302- // add key with future expiration which should not be reaped
303- ic .Store ("test.3 " , []byte ("test_value" ), ttl )
343+ // add key with no expiration which should not be reaped
344+ ic .Store ("test.2 " , []byte ("test_value" ), ttl )
304345
305- // trigger a reap that will only remove expired elements but not size down the full cache
306- keyCount := len (ic .Objects .Keys ())
307- ic .reap ()
308- require .Equal (t , keyCount , len (ic .Objects .Keys ()))
346+ // add key with future expiration which should not be reaped
347+ ic .Store ("test.3" , []byte ("test_value" ), ttl )
309348
310- state := getIndexedClientState ( ic )
311- require . Equal ( t , int64 ( 3 ), state . ObjectCount )
312- require . Equal ( t , int64 ( 30 ), state . CacheSize )
313- require .Len (t , state . Objects , 3 )
349+ // trigger a reap that will only remove expired elements but not size down the full cache
350+ keyCount := len ( ic . Objects . Keys () )
351+ ic . reap ( )
352+ require .Equal (t , keyCount , len ( ic . Objects . Keys ()) )
314353
315- // add key with future expiration which should not be reaped
316- ic .Store ("test.4" , []byte ("test_value" ), ttl )
354+ state := getIndexedClientState (ic )
355+ require .Equal (t , int64 (3 ), state .ObjectCount )
356+ require .Equal (t , int64 (30 ), state .CacheSize )
357+ require .Len (t , state .Objects , 3 )
317358
318- // add key with future expiration which should not be reaped
319- ic .Store ("test.5 " , []byte ("test_value" ), ttl )
359+ // add key with future expiration which should not be reaped
360+ ic .Store ("test.4 " , []byte ("test_value" ), ttl )
320361
321- // add key with future expiration which should not be reaped
322- ic .Store ("test.6 " , []byte ("test_value" ), ttl )
362+ // add key with future expiration which should not be reaped
363+ ic .Store ("test.5 " , []byte ("test_value" ), ttl )
323364
324- // trigger size-based reap eviction of some elements
325- keyCount = len (ic .Objects .Keys ())
326- require .Equal (t , 6 , keyCount )
327- ic .reap ()
365+ // add key with future expiration which should not be reaped
366+ ic .Store ("test.6" , []byte ("test_value" ), ttl )
328367
329- _ , ok := ic .Objects .Load ("test.1" )
330- require .False (t , ok , "expected key %s to be missing" , "test.1" )
368+ // trigger size-based reap eviction of some elements
369+ keyCount = len (ic .Objects .Keys ())
370+ require .Equal (t , 6 , keyCount )
371+ ic .reap ()
331372
332- _ , ok = ic .Objects .Load ("test.2 " )
333- require .False (t , ok , "expected key test.2 to be missing" )
373+ _ , ok : = ic .Objects .Load ("test.1 " )
374+ require .False (t , ok , "expected key %s to be missing" , "test.1 " )
334375
335- _ , ok = ic .Objects .Load ("test.3 " )
336- require .False (t , ok , "expected key test.3 to be missing" )
376+ _ , ok = ic .Objects .Load ("test.2 " )
377+ require .False (t , ok , "expected key test.2 to be missing" )
337378
338- _ , ok = ic .Objects .Load ("test.4 " )
339- require .False (t , ok , "expected key test.4 to be missing" )
379+ _ , ok = ic .Objects .Load ("test.3 " )
380+ require .False (t , ok , "expected key test.3 to be missing" )
340381
341- _ , ok = ic .Objects .Load ("test.5 " )
342- require .True (t , ok , "expected key test.5 to be present " )
382+ _ , ok = ic .Objects .Load ("test.4 " )
383+ require .False (t , ok , "expected key test.4 to be missing " )
343384
344- _ , ok = ic .Objects .Load ("test.6 " )
345- require .True (t , ok , "expected key test.6 to be present" )
385+ _ , ok = ic .Objects .Load ("test.5 " )
386+ require .True (t , ok , "expected key test.5 to be present" )
346387
347- // add key with large body to reach byte size threshold
348- ic . Store ( " test.7" , [] byte ( "test_value00000000000000000000000000000000000000000000000000000000000000000000000000000" ), ttl )
388+ _ , ok = ic . Objects . Load ( "test.6" )
389+ require . True ( t , ok , "expected key test.6 to be present" )
349390
350- // trigger a byte-based reap
351- keyCount = len (ic .Objects .Keys ())
352- require .Equal (t , 3 , keyCount )
353- ic .reap ()
354- require .Len (t , ic .Objects .Keys (), 0 )
391+ // add key with large body to reach byte size threshold
392+ ic .Store ("test.7" , []byte ("test_value00000000000000000000000000000000000000000000000000000000000000000000000000000" ), ttl )
355393
356- // expect index to be empty
357- objects := ic .Objects .ToObjects ()
358- require .Len (t , objects , 0 )
359- state = getIndexedClientState (ic )
360- require .Len (t , state .Objects , 0 )
361- require .Equal (t , int64 (0 ), state .ObjectCount )
362- require .Equal (t , int64 (0 ), state .CacheSize )
394+ // trigger a byte-based reap
395+ keyCount = len (ic .Objects .Keys ())
396+ require .Equal (t , 3 , keyCount )
397+ ic .reap ()
398+ require .Len (t , ic .Objects .Keys (), 0 )
399+
400+ // expect index to be empty
401+ objects := ic .Objects .ToObjects ()
402+ require .Len (t , objects , 0 )
403+ state = getIndexedClientState (ic )
404+ require .Len (t , state .Objects , 0 )
405+ require .Equal (t , int64 (0 ), state .ObjectCount )
406+ require .Equal (t , int64 (0 ), state .CacheSize )
407+ })
363408}
364409
365410type indexedClientState struct {
0 commit comments