From 88b5c6cbc2bf60c22566719e39cfaba519bd0f2e Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Tue, 10 Sep 2024 14:05:59 +0200 Subject: [PATCH] fs: test FOPEN_CACHE_DIR Change-Id: Id42c95c525f628f0274111ba4aa0d86f167b1999 --- fs/dircache_test.go | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 fs/dircache_test.go diff --git a/fs/dircache_test.go b/fs/dircache_test.go new file mode 100644 index 00000000..3d3d999e --- /dev/null +++ b/fs/dircache_test.go @@ -0,0 +1,100 @@ +// Copyright 2023 the Go-FUSE Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fs + +import ( + "context" + "fmt" + "reflect" + "sync" + "syscall" + "testing" + + "github.com/hanwen/go-fuse/v2/fuse" +) + +type dirCacheTestNode struct { + Inode + mu sync.Mutex + openCount int + cachedReads int +} + +var _ = (NodeOpendirHandler)((*dirCacheTestNode)(nil)) + +type countingReaddirenter struct { + FileReaddirenter + *dirCacheTestNode +} + +func (r *countingReaddirenter) Readdirent(ctx context.Context) (*fuse.DirEntry, syscall.Errno) { + de, errno := r.FileReaddirenter.Readdirent(ctx) + r.dirCacheTestNode.mu.Lock() + defer r.dirCacheTestNode.mu.Unlock() + if r.dirCacheTestNode.openCount > 1 { + r.dirCacheTestNode.cachedReads++ + } + return de, errno +} + +func (n *dirCacheTestNode) OpendirHandle(ctx context.Context, flags uint32) (FileHandle, uint32, syscall.Errno) { + n.mu.Lock() + defer n.mu.Unlock() + + n.openCount++ + var entries []fuse.DirEntry + + for i := 0; i < 1024; i++ { + entries = append(entries, fuse.DirEntry{ + Name: fmt.Sprintf("file%04d", i), + Ino: uint64(i + 42), + Mode: fuse.S_IFREG, + }) + } + return &countingReaddirenter{&dirStreamAsFile{ + creator: func(context.Context) (DirStream, syscall.Errno) { + return NewListDirStream(entries), 0 + }, + }, n}, fuse.FOPEN_CACHE_DIR, 0 +} + +func TestDirCacheFlag(t *testing.T) { + root := &dirCacheTestNode{} + opts := Options{} + opts.DisableReadDirPlus = true + mnt, _ := testMount(t, root, &opts) + + s, errno := NewLoopbackDirStream(mnt) + if errno != 0 { + t.Fatalf("NewLoopbackDirStream: %v", errno) + } + + want, errno := readDirStream(s) + if errno != 0 { + t.Fatalf("NewLoopbackDirStream: %v", errno) + } + s.Close() + + s, errno = NewLoopbackDirStream(mnt) + if errno != 0 { + t.Fatalf("NewLoopbackDirStream: %v", errno) + } + got, errno := readDirStream(s) + if errno != 0 { + t.Fatalf("NewLoopbackDirStream: %v", errno) + } + s.Close() + + if !reflect.DeepEqual(got, want) { + t.Fatalf("got %v, want %v", got, want) + } + + root.mu.Lock() + defer root.mu.Unlock() + if root.openCount != 2 || root.cachedReads != 0 { + t.Errorf("got %d, %d want 2,0", root.openCount, root.cachedReads) + } + +}