github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/test/run_dokan_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 dokan
     6  // +build dokan
     7  
     8  package test
     9  
    10  import (
    11  	"sync"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/keybase/client/go/kbfs/dokan"
    16  	"github.com/keybase/client/go/kbfs/libdokan"
    17  	"github.com/keybase/client/go/kbfs/libkbfs"
    18  	"github.com/keybase/client/go/logger"
    19  	"golang.org/x/net/context"
    20  )
    21  
    22  type dokanEngine struct {
    23  	fsEngine
    24  }
    25  
    26  func createEngine(tb testing.TB) Engine {
    27  	return &dokanEngine{
    28  		fsEngine: fsEngine{
    29  			name:       "dokan",
    30  			tb:         tb,
    31  			createUser: createUserDokan,
    32  		},
    33  	}
    34  }
    35  
    36  func createUserDokan(tb testing.TB, ith int, config *libkbfs.ConfigLocal,
    37  	opTimeout time.Duration) *fsUser {
    38  	driveLetter := 'T' + byte(ith)
    39  	if driveLetter > 'Z' {
    40  		tb.Error("Too many users - out of drive letters")
    41  	}
    42  
    43  	createSuccess := false
    44  
    45  	lock := getDriveLetterLock(driveLetter)
    46  	lock.Lock()
    47  	defer func() {
    48  		if !createSuccess {
    49  			lock.Unlock()
    50  		}
    51  	}()
    52  
    53  	ctx := context.Background()
    54  
    55  	session, err := config.KBPKI().GetCurrentSession(ctx)
    56  	if err != nil {
    57  		tb.Fatal(err)
    58  	}
    59  
    60  	ctx, cancelFn := context.WithCancel(ctx)
    61  	logTags := logger.CtxLogTags{
    62  		CtxUserKey: CtxOpUser,
    63  	}
    64  	ctx = logger.NewContextWithLogTags(ctx, logTags)
    65  	ctx = context.WithValue(ctx, CtxUserKey, session.Name)
    66  
    67  	fs, err := libdokan.NewFS(ctx, config, logger.NewTestLogger(tb))
    68  	if err != nil {
    69  		tb.Fatal(err)
    70  	}
    71  
    72  	if opTimeout > 0 {
    73  		tb.Logf("Ignoring op timeout for Dokan test")
    74  	}
    75  
    76  	mnt, err := dokan.Mount(&dokan.Config{
    77  		FileSystem: fs,
    78  		Path:       string([]byte{driveLetter, ':'}),
    79  		MountFlags: libdokan.DefaultMountFlags,
    80  	})
    81  	if err != nil {
    82  		tb.Fatal(err)
    83  	}
    84  
    85  	createSuccess = true
    86  	return &fsUser{
    87  		mntDir:   mnt.Dir,
    88  		username: session.Name,
    89  		config:   config,
    90  		cancel:   cancelFn,
    91  		close: func() {
    92  			dokan.Unmount(mnt.Dir)
    93  			lock.Unlock()
    94  		},
    95  	}
    96  }
    97  
    98  var driveLetterLocks ['Z' - 'A']sync.Mutex
    99  
   100  func getDriveLetterLock(driveLetter byte) *sync.Mutex {
   101  	return &driveLetterLocks[driveLetter-'A']
   102  }