github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/test/run_fuse_test.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 //go:build fuse 6 // +build fuse 7 8 package test 9 10 import ( 11 "testing" 12 "time" 13 14 "bazil.org/fuse" 15 "bazil.org/fuse/fs" 16 "bazil.org/fuse/fs/fstestutil" 17 "github.com/keybase/client/go/kbfs/libcontext" 18 "github.com/keybase/client/go/kbfs/libfs" 19 "github.com/keybase/client/go/kbfs/libfuse" 20 "github.com/keybase/client/go/kbfs/libkbfs" 21 "github.com/keybase/client/go/logger" 22 "golang.org/x/net/context" 23 ) 24 25 type fuseEngine struct { 26 fsEngine 27 } 28 29 func createEngine(tb testing.TB) Engine { 30 log := logger.NewTestLogger(tb) 31 debugLog := log.CloneWithAddedDepth(1) 32 fuse.Debug = libfuse.MakeFuseDebugFn(debugLog, false /* superVerbose */) 33 return &fuseEngine{ 34 fsEngine: fsEngine{ 35 name: "fuse", 36 tb: tb, 37 createUser: createUserFuse, 38 }, 39 } 40 } 41 42 func createUserFuse(tb testing.TB, ith int, config *libkbfs.ConfigLocal, 43 opTimeout time.Duration) *fsUser { 44 libfs.AddRootWrapper(config) 45 filesys := libfuse.NewFS(config, nil, false, libfuse.PlatformParams{}) 46 fn := func(mnt *fstestutil.Mount) fs.FS { 47 filesys.SetFuseConn(mnt.Server, mnt.Conn) 48 return filesys 49 } 50 options := libfuse.GetPlatformSpecificMountOptionsForTest() 51 mnt, err := fstestutil.MountedFuncT(tb, fn, &fs.Config{ 52 WithContext: func(ctx context.Context, req fuse.Request) context.Context { 53 if int(opTimeout) > 0 { 54 // Safe to ignore cancel since fuse should clean up the parent 55 ctx, _ = context.WithTimeout(ctx, opTimeout) 56 } 57 ctx = filesys.WithContext(ctx) 58 return ctx 59 }, 60 }, options...) 61 if err != nil { 62 tb.Fatal(err) 63 } 64 tb.Logf("FUSE HasInvalidate=%v", mnt.Conn.Protocol().HasInvalidate()) 65 66 ctx, cancelFn := context.WithCancel(context.Background()) 67 ctx, err = libcontext.NewContextWithCancellationDelayer( 68 libcontext.NewContextReplayable( 69 ctx, func(c context.Context) context.Context { 70 return ctx 71 })) 72 if err != nil { 73 tb.Fatal(err) 74 } 75 76 session, err := config.KBPKI().GetCurrentSession(ctx) 77 if err != nil { 78 tb.Fatal(err) 79 } 80 81 logTags := logger.CtxLogTags{ 82 CtxUserKey: CtxOpUser, 83 } 84 ctx = logger.NewContextWithLogTags(ctx, logTags) 85 ctx = context.WithValue(ctx, CtxUserKey, session.Name) 86 87 // the fsUser.cancel will cancel notification processing; the FUSE 88 // serve loop is terminated by unmounting the filesystem 89 filesys.LaunchNotificationProcessor(ctx) 90 return &fsUser{ 91 mntDir: mnt.Dir, 92 username: session.Name, 93 config: config, 94 cancel: cancelFn, 95 close: mnt.Close, 96 } 97 }