gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/fsimpl/gofer/gofer_test.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gofer 16 17 import ( 18 "testing" 19 20 "gvisor.dev/gvisor/pkg/abi/linux" 21 "gvisor.dev/gvisor/pkg/lisafs" 22 "gvisor.dev/gvisor/pkg/sentry/contexttest" 23 "gvisor.dev/gvisor/pkg/sentry/kernel/time" 24 "gvisor.dev/gvisor/pkg/sentry/pgalloc" 25 ) 26 27 func TestDestroyIdempotent(t *testing.T) { 28 ctx := contexttest.Context(t) 29 fs := filesystem{ 30 mf: pgalloc.MemoryFileFromContext(ctx), 31 inoByKey: make(map[inoKey]uint64), 32 clock: time.RealtimeClockFromContext(ctx), 33 // Test relies on no dentry being held in the cache. 34 dentryCache: &dentryCache{maxCachedDentries: 0}, 35 client: &lisafs.Client{}, 36 } 37 38 parentInode := lisafs.Inode{ 39 ControlFD: 1, 40 Stat: linux.Statx{ 41 Mask: linux.STATX_TYPE | linux.STATX_MODE, 42 Mode: linux.S_IFDIR | 0666, 43 }, 44 } 45 parent, err := fs.newLisafsDentry(ctx, &parentInode) 46 if err != nil { 47 t.Fatalf("fs.newLisafsDentry(): %v", err) 48 } 49 50 childInode := lisafs.Inode{ 51 ControlFD: 2, 52 Stat: linux.Statx{ 53 Mask: linux.STATX_TYPE | linux.STATX_MODE | linux.STATX_SIZE, 54 Mode: linux.S_IFREG | 0666, 55 Size: 0, 56 }, 57 } 58 child, err := fs.newLisafsDentry(ctx, &childInode) 59 if err != nil { 60 t.Fatalf("fs.newLisafsDentry(): %v", err) 61 } 62 parent.opMu.Lock() 63 parent.childrenMu.Lock() 64 parent.cacheNewChildLocked(child, "child") 65 parent.childrenMu.Unlock() 66 parent.opMu.Unlock() 67 68 fs.renameMu.Lock() 69 defer fs.renameMu.Unlock() 70 child.checkCachingLocked(ctx, true /* renameMuWriteLocked */) 71 if got := child.refs.Load(); got != -1 { 72 t.Fatalf("child.refs=%d, want: -1", got) 73 } 74 // Parent will also be destroyed when child reference is removed. 75 if got := parent.refs.Load(); got != -1 { 76 t.Fatalf("parent.refs=%d, want: -1", got) 77 } 78 child.checkCachingLocked(ctx, true /* renameMuWriteLocked */) 79 child.checkCachingLocked(ctx, true /* renameMuWriteLocked */) 80 } 81 82 func TestStringFixedCache(t *testing.T) { 83 names := []string{"a", "b", "c"} 84 cache := stringFixedCache{} 85 86 cache.init(uint64(len(names))) 87 if inited := cache.isInited(); !inited { 88 t.Fatalf("cache.isInited(): %v, want: true", inited) 89 } 90 for _, s := range names { 91 victim := cache.add(s) 92 if victim != "" { 93 t.Fatalf("cache.add(): %v, want: \"\"", victim) 94 } 95 } 96 for _, s := range names { 97 victim := cache.add("something") 98 if victim != s { 99 t.Fatalf("cache.add(): %v, want: %v", victim, s) 100 } 101 } 102 }