wa-lang.org/wazero@v1.0.2/imports/wasi_snapshot_preview1/wasi_stdlib_test.go (about)

     1  package wasi_snapshot_preview1
     2  
     3  import (
     4  	"bytes"
     5  	_ "embed"
     6  	"io/fs"
     7  	"strconv"
     8  	"strings"
     9  	"testing"
    10  	"testing/fstest"
    11  
    12  	"wa-lang.org/wazero"
    13  	"wa-lang.org/wazero/internal/testing/require"
    14  	"wa-lang.org/wazero/sys"
    15  )
    16  
    17  // lsWasmCargoWasi was compiled from testdata/cargo-wasi/ls.rs
    18  //
    19  //go:embed testdata/cargo-wasi/ls.wasm
    20  var lsWasmCargoWasi []byte
    21  
    22  // lsZigCc was compiled from testdata/zig-cc/ls.c
    23  //
    24  //go:embed testdata/zig-cc/ls.wasm
    25  var lsZigCc []byte
    26  
    27  // Test_fdReaddir_ls ensures that the behavior we've implemented not only
    28  // matches the wasi spec, but also at least two compilers use of sdks.
    29  func Test_fdReaddir_ls(t *testing.T) {
    30  	for toolchain, bin := range map[string][]byte{
    31  		"cargo-wasi": lsWasmCargoWasi,
    32  		"zig-cc":     lsZigCc,
    33  	} {
    34  		toolchain := toolchain
    35  		bin := bin
    36  		t.Run(toolchain, func(t *testing.T) {
    37  			testFdReaddirLs(t, bin)
    38  		})
    39  	}
    40  }
    41  
    42  func testFdReaddirLs(t *testing.T, bin []byte) {
    43  	t.Run("empty directory", func(t *testing.T) {
    44  		stdout, stderr := compileAndRun(t, wazero.NewModuleConfig().
    45  			WithFS(fstest.MapFS{}), bin)
    46  
    47  		require.Zero(t, stderr)
    48  		require.Zero(t, stdout)
    49  	})
    50  
    51  	t.Run("directory with entries", func(t *testing.T) {
    52  		stdout, stderr := compileAndRun(t, wazero.NewModuleConfig().
    53  			WithFS(fstest.MapFS{
    54  				"-":   {},
    55  				"a-":  {Mode: fs.ModeDir},
    56  				"ab-": {},
    57  			}), bin)
    58  
    59  		require.Zero(t, stderr)
    60  		require.Equal(t, `./-
    61  ./a-
    62  ./ab-
    63  `, stdout)
    64  	})
    65  
    66  	t.Run("directory with tons of entries", func(t *testing.T) {
    67  		testFS := fstest.MapFS{}
    68  		count := 8096
    69  		for i := 0; i < count; i++ {
    70  			testFS[strconv.Itoa(i)] = &fstest.MapFile{}
    71  		}
    72  		stdout, stderr := compileAndRun(t, wazero.NewModuleConfig().
    73  			WithFS(testFS), bin)
    74  
    75  		require.Zero(t, stderr)
    76  		lines := strings.Split(stdout, "\n")
    77  		require.Equal(t, count+1 /* trailing newline */, len(lines))
    78  	})
    79  }
    80  
    81  func compileAndRun(t *testing.T, config wazero.ModuleConfig, bin []byte) (stdout, stderr string) {
    82  	var stdoutBuf, stderrBuf bytes.Buffer
    83  
    84  	r := wazero.NewRuntime(testCtx)
    85  	defer r.Close(testCtx)
    86  
    87  	_, err := Instantiate(testCtx, r)
    88  	require.NoError(t, err)
    89  
    90  	compiled, err := r.CompileModule(testCtx, bin)
    91  	require.NoError(t, err)
    92  
    93  	_, err = r.InstantiateModule(testCtx, compiled, config.WithStdout(&stdoutBuf).WithStderr(&stderrBuf))
    94  	if exitErr, ok := err.(*sys.ExitError); ok {
    95  		require.Zero(t, exitErr.ExitCode())
    96  	} else {
    97  		require.NoError(t, err)
    98  	}
    99  
   100  	stdout = stdoutBuf.String()
   101  	stderr = stderrBuf.String()
   102  	return
   103  }