@@ -909,6 +909,55 @@ func TestCachingKey_ShouldKeepAllocationsToMinimum(t *testing.T) {
909
909
}
910
910
}
911
911
912
+ func TestMutationInvalidatesCache (t * testing.T ) {
913
+ inmem := objstore .NewInMemBucket ()
914
+
915
+ // We reuse cache between tests (!)
916
+ c := cache .NewMockCache ()
917
+ ctx := context .Background ()
918
+
919
+ const cfgName = "test"
920
+ cfg := NewCachingBucketConfig ()
921
+ cfg .CacheGet (cfgName , c , matchAll , 1024 ^ 2 , time .Minute , time .Minute , time .Minute )
922
+ cfg .CacheExists (cfgName , c , matchAll , time .Minute , time .Minute )
923
+ cfg .CacheAttributes (cfgName , c , matchAll , time .Minute )
924
+
925
+ cb , err := NewCachingBucket ("test" , inmem , cfg , nil , nil )
926
+ require .NoError (t , err )
927
+
928
+ t .Run ("invalidated on upload" , func (t * testing.T ) {
929
+ c .Flush ()
930
+
931
+ // Initial upload bypassing the CachingBucket but read the object back to ensure it is in cache.
932
+ require .NoError (t , inmem .Upload (ctx , "/object-1" , strings .NewReader ("test content 1" )))
933
+ verifyGet (ctx , t , cb , "/object-1" , []byte ("test content 1" ), true , false , cfgName )
934
+ verifyExists (ctx , t , cb , "/object-1" , true , true , true , cfgName )
935
+ verifyObjectAttrs (ctx , t , cb , "/object-1" , 14 , true , false , cfgName )
936
+
937
+ // Do an upload via the CachingBucket and ensure the first read after does not come from cache.
938
+ require .NoError (t , cb .Upload (ctx , "/object-1" , strings .NewReader ("test content 12" )))
939
+ verifyGet (ctx , t , cb , "/object-1" , []byte ("test content 12" ), true , false , cfgName )
940
+ verifyExists (ctx , t , cb , "/object-1" , true , true , true , cfgName )
941
+ verifyObjectAttrs (ctx , t , cb , "/object-1" , 15 , true , false , cfgName )
942
+ })
943
+
944
+ t .Run ("invalidated on delete" , func (t * testing.T ) {
945
+ c .Flush ()
946
+
947
+ // Initial upload bypassing the CachingBucket but read the object back to ensure it is in cache.
948
+ require .NoError (t , inmem .Upload (ctx , "/object-1" , strings .NewReader ("test content 1" )))
949
+ verifyGet (ctx , t , cb , "/object-1" , []byte ("test content 1" ), true , false , cfgName )
950
+ verifyExists (ctx , t , cb , "/object-1" , true , true , true , cfgName )
951
+ verifyObjectAttrs (ctx , t , cb , "/object-1" , 14 , true , false , cfgName )
952
+
953
+ // Delete via the CachingBucket and ensure the first read after does not come from cache but non-existence is cached.
954
+ require .NoError (t , cb .Delete (ctx , "/object-1" ))
955
+ verifyGet (ctx , t , cb , "/object-1" , nil , true , false , cfgName )
956
+ verifyExists (ctx , t , cb , "/object-1" , false , true , true , cfgName )
957
+ verifyObjectAttrs (ctx , t , cb , "/object-1" , - 1 , true , false , cfgName )
958
+ })
959
+ }
960
+
912
961
func BenchmarkCachingKey (b * testing.B ) {
913
962
tests := map [string ]struct {
914
963
run func (bucketID string )
0 commit comments