github.com/tetratelabs/wazero@v1.2.1/fsconfig_test.go (about)

     1  package wazero
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/tetratelabs/wazero/internal/fsapi"
     7  	"github.com/tetratelabs/wazero/internal/sysfs"
     8  	testfs "github.com/tetratelabs/wazero/internal/testing/fs"
     9  	"github.com/tetratelabs/wazero/internal/testing/require"
    10  )
    11  
    12  // TestFSConfig only tests the cases that change the inputs to sysfs.NewRootFS.
    13  func TestFSConfig(t *testing.T) {
    14  	base := NewFSConfig()
    15  
    16  	testFS := testfs.FS{}
    17  	testFS2 := testfs.FS{"/": &testfs.File{}}
    18  
    19  	tests := []struct {
    20  		name     string
    21  		input    FSConfig
    22  		expected fsapi.FS
    23  	}{
    24  		{
    25  			name:     "empty",
    26  			input:    base,
    27  			expected: fsapi.UnimplementedFS{},
    28  		},
    29  		{
    30  			name:     "WithFSMount",
    31  			input:    base.WithFSMount(testFS, "/"),
    32  			expected: sysfs.Adapt(testFS),
    33  		},
    34  		{
    35  			name:     "WithFSMount overwrites",
    36  			input:    base.WithFSMount(testFS, "/").WithFSMount(testFS2, "/"),
    37  			expected: sysfs.Adapt(testFS2),
    38  		},
    39  		{
    40  			name:     "WithFsMount nil",
    41  			input:    base.WithFSMount(nil, "/"),
    42  			expected: fsapi.UnimplementedFS{},
    43  		},
    44  		{
    45  			name:     "WithDirMount overwrites",
    46  			input:    base.WithFSMount(testFS, "/").WithDirMount(".", "/"),
    47  			expected: sysfs.NewDirFS("."),
    48  		},
    49  		{
    50  			name:  "Composition",
    51  			input: base.WithReadOnlyDirMount(".", "/").WithDirMount("/tmp", "/tmp"),
    52  			expected: func() fsapi.FS {
    53  				f, err := sysfs.NewRootFS(
    54  					[]fsapi.FS{sysfs.NewReadFS(sysfs.NewDirFS(".")), sysfs.NewDirFS("/tmp")},
    55  					[]string{"/", "/tmp"},
    56  				)
    57  				require.NoError(t, err)
    58  				return f
    59  			}(),
    60  		},
    61  	}
    62  
    63  	for _, tt := range tests {
    64  		tc := tt
    65  
    66  		t.Run(tc.name, func(t *testing.T) {
    67  			sysCtx, err := tc.input.(*fsConfig).toFS()
    68  			require.NoError(t, err)
    69  			require.Equal(t, tc.expected, sysCtx)
    70  		})
    71  	}
    72  }
    73  
    74  func TestFSConfig_Errors(t *testing.T) {
    75  	tests := []struct {
    76  		name        string
    77  		input       FSConfig
    78  		expectedErr string
    79  	}{
    80  		{
    81  			name:        "multi-level path not yet supported",
    82  			input:       NewFSConfig().WithDirMount(".", "/usr/bin"),
    83  			expectedErr: "only single-level guest paths allowed: [.:/usr/bin]",
    84  		},
    85  	}
    86  	for _, tt := range tests {
    87  		tc := tt
    88  
    89  		t.Run(tc.name, func(t *testing.T) {
    90  			_, err := tc.input.(*fsConfig).toFS()
    91  			require.EqualError(t, err, tc.expectedErr)
    92  		})
    93  	}
    94  }
    95  
    96  func TestFSConfig_clone(t *testing.T) {
    97  	fc := NewFSConfig().(*fsConfig)
    98  	fc.guestPathToFS["/"] = 0
    99  
   100  	cloned := fc.clone()
   101  
   102  	// Make post-clone changes
   103  	fc.guestPaths = []string{"/"}
   104  	fc.guestPathToFS["/"] = 1
   105  
   106  	// Ensure the guestPathToFS map is not shared
   107  	require.Equal(t, map[string]int{"/": 1}, fc.guestPathToFS)
   108  	require.Equal(t, map[string]int{"/": 0}, cloned.guestPathToFS)
   109  
   110  	// Ensure the guestPaths slice is not shared
   111  	require.Zero(t, len(cloned.guestPaths))
   112  }