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  }