github.com/grailbio/base@v0.0.11/file/fsnodefuse/err_test.go (about)

     1  package fsnodefuse
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"os"
     7  	"path"
     8  	"sync/atomic"
     9  	"testing"
    10  
    11  	"github.com/grailbio/base/file/fsnode"
    12  	"github.com/grailbio/base/ioctx/fsctx"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  // TestPanic* panic while handling a FUSE operation, then repeat the operation to make
    18  // sure the mount isn't broken.
    19  // TODO: Test operations exhaustively, maybe with something like fuzzing.
    20  
    21  func TestPanicOpen(t *testing.T) {
    22  	const success = "success"
    23  	var (
    24  		info     = fsnode.NewRegInfo("panicOnce")
    25  		panicked int32
    26  	)
    27  	root := fsnode.NewParent(fsnode.NewDirInfo("root"),
    28  		fsnode.ConstChildren(
    29  			fsnode.FuncLeaf(
    30  				info,
    31  				func(ctx context.Context, flag int) (fsctx.File, error) {
    32  					if atomic.AddInt32(&panicked, 1) == 1 {
    33  						panic("it's a panic!")
    34  					}
    35  					return fsnode.Open(ctx, fsnode.ConstLeaf(info, []byte(success)))
    36  				},
    37  			),
    38  		),
    39  	)
    40  	withMounted(t, root, func(mountDir string) {
    41  		_, err := os.Open(path.Join(mountDir, "panicOnce"))
    42  		require.Error(t, err)
    43  		f, err := os.Open(path.Join(mountDir, "panicOnce"))
    44  		require.NoError(t, err)
    45  		defer func() { require.NoError(t, f.Close()) }()
    46  		content, err := ioutil.ReadAll(f)
    47  		require.NoError(t, err)
    48  		assert.Equal(t, success, string(content))
    49  	})
    50  }
    51  
    52  func TestPanicList(t *testing.T) {
    53  	const success = "success"
    54  	var panicked int32
    55  	root := fsnode.NewParent(fsnode.NewDirInfo("root"),
    56  		fsnode.FuncChildren(func(context.Context) ([]fsnode.T, error) {
    57  			if atomic.AddInt32(&panicked, 1) == 1 {
    58  				panic("it's a panic!")
    59  			}
    60  			return []fsnode.T{
    61  				fsnode.ConstLeaf(fsnode.NewRegInfo(success), nil),
    62  			}, nil
    63  		}),
    64  	)
    65  	withMounted(t, root, func(mountDir string) {
    66  		dir, err := os.Open(mountDir)
    67  		require.NoError(t, err)
    68  		ents, _ := dir.Readdirnames(0)
    69  		// It seems like Readdirnames returns nil error despite the panic.
    70  		// TODO: Confirm this is expected.
    71  		assert.Empty(t, ents)
    72  		require.NoError(t, dir.Close())
    73  		dir, err = os.Open(mountDir)
    74  		require.NoError(t, err)
    75  		defer func() { require.NoError(t, dir.Close()) }()
    76  		ents, err = dir.Readdirnames(0)
    77  		assert.NoError(t, err)
    78  		assert.Equal(t, []string{success}, ents)
    79  	})
    80  }