In order to support more configuration, we should stop using context as it is getting gnarly. Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io> Signed-off-by: Adrian Cole <adrian@tetrate.io>
98 lines
2.7 KiB
Go
98 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"testing"
|
|
|
|
"github.com/tetratelabs/wazero"
|
|
"github.com/tetratelabs/wazero/experimental/gojs"
|
|
"github.com/tetratelabs/wazero/internal/platform"
|
|
"github.com/tetratelabs/wazero/internal/testing/maintester"
|
|
"github.com/tetratelabs/wazero/internal/testing/require"
|
|
"github.com/tetratelabs/wazero/sys"
|
|
)
|
|
|
|
// Test_main ensures the following will work:
|
|
//
|
|
// go run stars.go
|
|
func Test_main(t *testing.T) {
|
|
stdout, stderr := maintester.TestMain(t, main, "stars")
|
|
require.Equal(t, "", stderr)
|
|
require.Equal(t, "wazero has 9999999 stars. Does that include you?\n", stdout)
|
|
}
|
|
|
|
// TestMain compiles the wasm on-demand, which uses the runner's Go as opposed
|
|
// to a binary checked in, which would be pinned to one version. This is
|
|
// separate from Test_main to show that compilation doesn't dominate the
|
|
// execution time.
|
|
func TestMain(m *testing.M) {
|
|
// Notably our scratch containers don't have go, so don't fail tests.
|
|
if err := compileFromGo(); err != nil {
|
|
log.Println("Skipping tests due to:", err)
|
|
os.Exit(0)
|
|
}
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
// compileFromGo compiles "stars/main.go" on demand as the binary generated is
|
|
// too big (>7MB) to check into the source tree.
|
|
func compileFromGo() error {
|
|
cmd := exec.Command("go", "build", "-o", "main.wasm", ".")
|
|
cmd.Dir = "stars"
|
|
cmd.Env = append(os.Environ(), "GOARCH=wasm", "GOOS=js", "GOWASM=satconv,signext")
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("go build: %v\n%s", err, out)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Benchmark_main is in the example for GOOS=js to re-use compilation caching
|
|
// infrastructure. This is only used to sporadically check the impact of
|
|
// internal changes as in general, it is known that GOOS=js will be slow due to
|
|
// JavaScript emulation.
|
|
func Benchmark_main(b *testing.B) {
|
|
// Don't benchmark with interpreter as we know it will be slow.
|
|
if !platform.CompilerSupported() {
|
|
b.Skip()
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
// Create a new WebAssembly Runtime.
|
|
r := wazero.NewRuntime(ctx)
|
|
defer r.Close(ctx) // This closes everything this Runtime created.
|
|
|
|
bin, err := os.ReadFile(path.Join("stars", "main.wasm"))
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
compiled, err := r.CompileModule(ctx, bin)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
// Add the imports needed for `GOARCH=wasm GOOS=js`
|
|
gojs.MustInstantiate(ctx, r)
|
|
|
|
// Instead of making real HTTP calls, return fake data.
|
|
cfg := gojs.NewConfig(wazero.NewModuleConfig()).
|
|
WithRoundTripper(&fakeGitHub{})
|
|
|
|
b.Run("gojs.Run", func(b *testing.B) {
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
err = gojs.Run(ctx, r, compiled, cfg)
|
|
if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 {
|
|
b.Fatal(err)
|
|
} else if !ok {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
})
|
|
}
|