wasi: adds preopen test for use in homebrew (#1309)

This adds a test to verify the wazero binary produced by homebrew.
Notably, this was made to be small enough to copy/paste in hex format.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2023-03-30 13:06:51 +08:00
committed by GitHub
parent 44636d02ee
commit 035c0ffaf4
6 changed files with 77 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
;; $wasi_arg is a WASI command which copies null-terminated args to stdout.
(module $wasi_arg
;; $print_args is a WASI command which copies null-terminated args to stdout.
(module $print_args
;; args_get reads command-line argument data.
;;
;; See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-args_getargv-pointerpointeru8-argv_buf-pointeru8---errno
@@ -24,9 +24,9 @@
;; See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memories%E2%91%A7
(memory (export "memory") 1)
;; $iovs are offset/length pairs in memory fd_write copies to the file descriptor.
;; $main will only write one offset/length pair, corresponding to null-terminated args.
(global $iovs i32 i32.const 1024) ;; 1024 is an arbitrary offset larger than the args.
;; $iovs are offset/length pairs in memory fd_write copies to the file
;; descriptor. $main will only write one offset/length pair.
(global $iovs i32 i32.const 1024) ;; 1024 is an arbitrary offset
;; WASI parameters are usually memory offsets, you can ignore values by writing them to an unread offset.
(global $ignored i32 i32.const 32768)

Binary file not shown.

View File

@@ -0,0 +1,42 @@
;; $$print_prestat_dirname is a WASI command which copies the first preopen dirname to stdout.
(module $print_prestat_dirname
(import "wasi_snapshot_preview1" "fd_prestat_get"
(func $wasi.fd_prestat_get (param $fd i32) (param $result.prestat i32) (result (;errno;) i32)))
(import "wasi_snapshot_preview1" "fd_prestat_dir_name"
(func $wasi.fd_prestat_dir_name (param $fd i32) (param $result.path i32) (param $result.path_len i32) (result (;errno;) i32)))
(import "wasi_snapshot_preview1" "fd_write"
(func $wasi.fd_write (param $fd i32) (param $iovs i32) (param $iovs_len i32) (param $result.size i32) (result (;errno;) i32)))
(memory (export "memory") 1 1)
(func $main (export "_start")
;; First, we need to know the size of the prestat dir name.
(call $wasi.fd_prestat_get
(i32.const 3) ;; preopen FD
(i32.const 0) ;; where to write prestat
)
drop ;; ignore the errno returned
;; Next, write the dir name to offset 8 (past the prestat).
(call $wasi.fd_prestat_dir_name
(i32.const 3) ;; preopen FD
(i32.const 8) ;; where to write dir_name
(i32.load (i32.const 4)) ;; length is the last part of the prestat
)
drop ;; ignore the errno returned
;; Now, convert the prestat to an iovec [offset, len] writing offset=8.
(i32.store (i32.const 0) (i32.const 8))
;; Finally, write the dirname to stdout via its iovec [offset, len].
(call $wasi.fd_write
(i32.const 1) ;; stdout
(i32.const 0) ;; where's the iovec
(i32.const 1) ;; only one iovec
(i32.const 0) ;; overwrite the iovec with the ignored result.
)
drop ;; ignore the errno returned
)
)

View File

@@ -8,13 +8,14 @@ import (
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
"github.com/tetratelabs/wazero/internal/fstest"
"github.com/tetratelabs/wazero/internal/testing/require"
)
// wasiArg was compiled from testdata/wasi_arg.wat
// pringArgsWasm was compiled from testdata/wasi_arg.wat
//
//go:embed testdata/wasi_arg.wasm
var wasiArg []byte
//go:embed testdata/print_args.wasm
var pringArgsWasm []byte
func TestInstantiateModule(t *testing.T) {
ctx := context.Background()
@@ -28,7 +29,7 @@ func TestInstantiateModule(t *testing.T) {
sys := wazero.NewModuleConfig().WithStdout(&stdout)
wasi_snapshot_preview1.MustInstantiate(ctx, r)
compiled, err := r.CompileModule(ctx, wasiArg)
compiled, err := r.CompileModule(ctx, pringArgsWasm)
require.NoError(t, err)
// Re-use the same module many times.
@@ -46,3 +47,27 @@ func TestInstantiateModule(t *testing.T) {
require.NoError(t, mod.Close(ctx))
}
}
// printPrestatDirname was compiled from testdata/print_prestat_dirname.wat
//
//go:embed testdata/print_prestat_dirname.wasm
var printPrestatDirname []byte
// TestInstantiateModule_Prestat
func TestInstantiateModule_Prestat(t *testing.T) {
ctx := context.Background()
r := wazero.NewRuntime(ctx)
defer r.Close(ctx)
var stdout bytes.Buffer
wasi_snapshot_preview1.MustInstantiate(ctx, r)
_, err := r.InstantiateWithConfig(ctx, printPrestatDirname, wazero.NewModuleConfig().
WithStdout(&stdout).
WithFSConfig(wazero.NewFSConfig().WithFSMount(fstest.FS, "/wazero")))
require.NoError(t, err)
require.Equal(t, "/wazero", stdout.String())
}

View File

@@ -1,5 +1,4 @@
// Package wasi_snapshot_preview1 is a helper to remove package cycles re-using
// constants.
// Package wasip1 is a helper to remove package cycles re-using constants.
package wasip1
import (