Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makes filesystem test simpler and removes use of panic in examples #395

Merged
merged 1 commit into from
Mar 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ jobs:
docker buildx build -t wazero:test --platform linux/${{ matrix.arch }} .

- name: Run built test binaries
run: find . -name "*.test" | xargs -Itestbin docker run --platform linux/${{ matrix.arch }} -v $(pwd)/testbin:/test --rm -t wazero:test
# This runs all tests compiled above in sequence. Note: This mounts /tmp to allow t.TempDir() in tests.
run: find . -name "*.test" | xargs -Itestbin docker run --platform linux/${{ matrix.arch }} -v $(pwd)/testbin:/test --tmpfs /tmp --rm -t wazero:test

bench:
name: Benchmark
Expand Down
83 changes: 43 additions & 40 deletions examples/file_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,49 @@ import (
"github.com/tetratelabs/wazero/wasi"
)

// filesystemWasm was compiled from TinyGo testdata/file_system.go
//go:embed testdata/file_system.wasm
var filesystemWasm []byte
// catGo is the TinyGo source
//go:embed testdata/cat.go
var catGo []byte

// catWasm was compiled from catGo
//go:embed testdata/cat.wasm
var catWasm []byte

// Test_Cat writes the input file to stdout, just like `cat`.
//
// This is a basic introduction to the WebAssembly System Interface (WASI).
// See https://github.com/WebAssembly/WASI
func Test_Cat(t *testing.T) {
r := wazero.NewRuntime()

// First, configure where the WebAssembly Module (Wasm) console outputs to (stdout).
stdoutBuf := bytes.NewBuffer(nil)
wasiConfig := wazero.NewWASIConfig().WithStdout(stdoutBuf)

// Next, configure a sand-boxed filesystem to include one file.
file := "cat.go" // arbitrary file
memFS := wazero.WASIMemFS()
err := writeFile(memFS, file, catGo)
require.NoError(t, err)
wasiConfig.WithPreopens(map[string]wasi.FS{".": memFS})

// Since this runs a main function (_start in WASI), configure the arguments.
// Remember, arg[0] is the program name!
wasiConfig.WithArgs("cat", file)

// Now, instantiate WASI with the above configuration.
wasi, err := r.InstantiateModule(wazero.WASISnapshotPreview1WithConfig(wasiConfig))
require.NoError(t, err)
defer wasi.Close()

// Finally, start the `cat` program's main function (in WASI, this is named `_start`).
cat, err := wazero.StartWASICommandFromSource(r, catWasm)
require.NoError(t, err)
defer cat.Close()

// To ensure it worked, verify stdout from WebAssembly had what we expected.
require.Equal(t, string(catGo), stdoutBuf.String())
}

func writeFile(fs wasi.FS, path string, data []byte) error {
f, err := fs.OpenWASI(0, path, wasi.O_CREATE|wasi.O_TRUNC, wasi.R_FD_WRITE, 0, 0)
Expand All @@ -28,40 +68,3 @@ func writeFile(fs wasi.FS, path string, data []byte) error {

return f.Close()
}

func readFile(fs wasi.FS, path string) ([]byte, error) {
f, err := fs.OpenWASI(0, path, 0, 0, 0, 0)
if err != nil {
return nil, err
}

buf := bytes.NewBuffer(nil)

if _, err := io.Copy(buf, f); err != nil {
return buf.Bytes(), nil
}

return buf.Bytes(), f.Close()
}

func Test_file_system(t *testing.T) {
r := wazero.NewRuntime()

memFS := wazero.WASIMemFS()
err := writeFile(memFS, "input.txt", []byte("Hello, file system!"))
require.NoError(t, err)

wasiConfig := wazero.NewWASIConfig().WithPreopens(map[string]wasi.FS{".": memFS})
wasi, err := r.InstantiateModule(wazero.WASISnapshotPreview1WithConfig(wasiConfig))
require.NoError(t, err)
defer wasi.Close()

// Note: TinyGo binaries must be treated as WASI Commands to initialize memory.
mod, err := wazero.StartWASICommandFromSource(r, filesystemWasm)
require.NoError(t, err)
defer mod.Close()

out, err := readFile(memFS, "output.txt")
require.NoError(t, err)
require.Equal(t, "Hello, file system!", string(out))
}
19 changes: 19 additions & 0 deletions examples/testdata/cat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"os"
)

// main is the same as cat: "concatenate and print files."
func main() {
// Start at arg[1] because args[0] is the program name.
for i := 1; i < len(os.Args); i++ {
bytes, err := os.ReadFile(os.Args[i])
if err != nil {
os.Exit(1)
}

// Use write to avoid needing to worry about Windows newlines.
os.Stdout.Write(bytes)
}
}
Binary file added examples/testdata/cat.wasm
Binary file not shown.
Binary file modified examples/testdata/fibonacci.wasm
Binary file not shown.
25 changes: 0 additions & 25 deletions examples/testdata/file_system.go

This file was deleted.

Binary file removed examples/testdata/file_system.wasm
Binary file not shown.
Binary file modified examples/testdata/host_func.wasm
Binary file not shown.
4 changes: 2 additions & 2 deletions examples/testdata/stdio.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ func main() {
for s.Scan() {
line := s.Text()
if _, err := fmt.Printf("Hello, %s!\n", strings.TrimSpace(line)); err != nil {
panic(err)
os.Exit(1)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC when we wrote these examples, we didn't implement exit, yet

}

if _, err := fmt.Fprintln(os.Stderr, "Error Message"); err != nil {
panic(err)
os.Exit(1)
}
}
}
Binary file modified examples/testdata/stdio.wasm
Binary file not shown.