@@ -27,11 +27,14 @@ import (
2727 "github.com/googlecloudplatform/gcsfuse/v3/cfg"
2828 "github.com/googlecloudplatform/gcsfuse/v3/internal/cache/metadata"
2929 "github.com/googlecloudplatform/gcsfuse/v3/internal/contentcache"
30+ "github.com/googlecloudplatform/gcsfuse/v3/internal/storage/caching"
3031 "github.com/googlecloudplatform/gcsfuse/v3/internal/storage/fake"
3132 "github.com/googlecloudplatform/gcsfuse/v3/internal/storage/gcs"
33+ storagemock "github.com/googlecloudplatform/gcsfuse/v3/internal/storage/mock"
3234 "github.com/googlecloudplatform/gcsfuse/v3/internal/storage/storageutil"
3335 "github.com/googlecloudplatform/gcsfuse/v3/internal/util"
3436 "github.com/stretchr/testify/assert"
37+ "github.com/stretchr/testify/mock"
3538 "github.com/stretchr/testify/require"
3639 "github.com/stretchr/testify/suite"
3740 "golang.org/x/net/context"
@@ -2155,3 +2158,122 @@ func (t *DirTest) Test_IsTypeCacheDeprecated_true() {
21552158
21562159 assert .True (t .T (), dInode .IsTypeCacheDeprecated ())
21572160}
2161+
2162+ func (t * DirTest ) TestLookUpChild_TypeCacheDeprecated_CacheMiss () {
2163+ mockBucket := new (storagemock.TestifyMockBucket )
2164+ mockBucket .On ("BucketType" ).Return (gcs.BucketType {})
2165+ syncerBucket := gcsx .NewSyncerBucket (1 , ChunkTransferTimeoutSecs , ".gcsfuse_tmp/" , mockBucket )
2166+ config := & cfg.Config {
2167+ MetadataCache : cfg.MetadataCacheConfig {
2168+ TtlSecs : 60 ,
2169+ TypeCacheMaxSizeMb : 4 ,
2170+ },
2171+ EnableTypeCacheDeprecation : true ,
2172+ }
2173+ in := NewDirInode (
2174+ dirInodeID ,
2175+ NewDirName (NewRootName ("" ), dirInodeName ),
2176+ fuseops.InodeAttributes {
2177+ Uid : uid ,
2178+ Gid : gid ,
2179+ Mode : dirMode ,
2180+ },
2181+ false , // implicitDirs
2182+ false , // enableNonexistentTypeCache
2183+ typeCacheTTL ,
2184+ & syncerBucket ,
2185+ & t .clock ,
2186+ & t .clock ,
2187+ config ,
2188+ )
2189+ const name = "file"
2190+ objName := path .Join (dirInodeName , name )
2191+ dirObjName := objName + "/"
2192+ cacheMissErr := & caching.CacheMissError {}
2193+ // Expect cache lookup for file -> CacheMiss
2194+ mockBucket .On ("StatObject" , mock .Anything , mock .MatchedBy (func (req * gcs.StatObjectRequest ) bool {
2195+ return req .Name == objName && req .FetchOnlyFromCache == true
2196+ })).Return (nil , nil , cacheMissErr ).Once ()
2197+ // Expect cache lookup for dir -> CacheMiss
2198+ mockBucket .On ("StatObject" , mock .Anything , mock .MatchedBy (func (req * gcs.StatObjectRequest ) bool {
2199+ return req .Name == dirObjName && req .FetchOnlyFromCache == true
2200+ })).Return (nil , nil , cacheMissErr ).Once ()
2201+ // Expect actual lookup for file -> Success
2202+ minObject := & gcs.MinObject {
2203+ Name : objName ,
2204+ Generation : 1 ,
2205+ MetaGeneration : 1 ,
2206+ Size : 100 ,
2207+ }
2208+ mockBucket .On ("StatObject" , mock .Anything , mock .MatchedBy (func (req * gcs.StatObjectRequest ) bool {
2209+ return req .Name == objName && req .FetchOnlyFromCache == false
2210+ })).Return (minObject , & gcs.ExtendedObjectAttributes {}, nil ).Once ()
2211+ // Expect actual lookup for dir -> NotFound
2212+ mockBucket .On ("StatObject" , mock .Anything , mock .MatchedBy (func (req * gcs.StatObjectRequest ) bool {
2213+ return req .Name == dirObjName && req .FetchOnlyFromCache == false
2214+ })).Return (nil , nil , & gcs.NotFoundError {}).Once ()
2215+
2216+ in .Lock ()
2217+ entry , err := in .LookUpChild (t .ctx , name )
2218+ in .Unlock ()
2219+
2220+ require .NoError (t .T (), err )
2221+ require .NotNil (t .T (), entry )
2222+ assert .Equal (t .T (), objName , entry .FullName .GcsObjectName ())
2223+ mockBucket .AssertExpectations (t .T ())
2224+ }
2225+
2226+ func (t * DirTest ) TestLookUpChild_TypeCacheDeprecated_CacheHit () {
2227+ mockBucket := new (storagemock.TestifyMockBucket )
2228+ mockBucket .On ("BucketType" ).Return (gcs.BucketType {})
2229+ syncerBucket := gcsx .NewSyncerBucket (1 , ChunkTransferTimeoutSecs , ".gcsfuse_tmp/" , mockBucket )
2230+ config := & cfg.Config {
2231+ MetadataCache : cfg.MetadataCacheConfig {
2232+ TtlSecs : 60 ,
2233+ TypeCacheMaxSizeMb : 4 ,
2234+ },
2235+ EnableTypeCacheDeprecation : true ,
2236+ }
2237+ in := NewDirInode (
2238+ dirInodeID ,
2239+ NewDirName (NewRootName ("" ), dirInodeName ),
2240+ fuseops.InodeAttributes {
2241+ Uid : uid ,
2242+ Gid : gid ,
2243+ Mode : dirMode ,
2244+ },
2245+ false , // implicitDirs
2246+ false , // enableNonexistentTypeCache
2247+ typeCacheTTL ,
2248+ & syncerBucket ,
2249+ & t .clock ,
2250+ & t .clock ,
2251+ config ,
2252+ )
2253+ const name = "file"
2254+ objName := path .Join (dirInodeName , name )
2255+ dirObjName := objName + "/"
2256+ // Expect cache lookup for file -> Success
2257+ minObject := & gcs.MinObject {
2258+ Name : objName ,
2259+ Generation : 1 ,
2260+ MetaGeneration : 1 ,
2261+ Size : 100 ,
2262+ }
2263+ mockBucket .On ("StatObject" , mock .Anything , mock .MatchedBy (func (req * gcs.StatObjectRequest ) bool {
2264+ return req .Name == objName && req .FetchOnlyFromCache == true
2265+ })).Return (minObject , & gcs.ExtendedObjectAttributes {}, nil ).Once ()
2266+ // Expect cache lookup for dir -> NotFound (nil, nil)
2267+ mockBucket .On ("StatObject" , mock .Anything , mock .MatchedBy (func (req * gcs.StatObjectRequest ) bool {
2268+ return req .Name == dirObjName && req .FetchOnlyFromCache == true
2269+ })).Return (nil , nil , & gcs.NotFoundError {}).Once ()
2270+
2271+ in .Lock ()
2272+ entry , err := in .LookUpChild (t .ctx , name )
2273+ in .Unlock ()
2274+
2275+ require .NoError (t .T (), err )
2276+ require .NotNil (t .T (), entry )
2277+ assert .Equal (t .T (), objName , entry .FullName .GcsObjectName ())
2278+ mockBucket .AssertExpectations (t .T ())
2279+ }
0 commit comments