diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f2418e9c..819089a19 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,24 +8,35 @@ jobs: name: Build and Test strategy: matrix: - os: [macos-10.15, macos-11, macos-12, ubuntu-18.04, ubuntu-20.04] - toolchain: - - wasm-5.5.0-RELEASE - - wasm-5.6.0-RELEASE - runs-on: ${{ matrix.os }} + entry: + # Ensure that all host can install toolchain, build project, and run tests + - { os: macos-10.15, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } + - { os: macos-11, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } + - { os: macos-12, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } + - { os: ubuntu-18.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } + + # Ensure that test succeeds with all toolchains and wasi backend combinations + - { os: ubuntu-20.04, toolchain: wasm-5.5.0-RELEASE, wasi-backend: Node } + - { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node } + - { os: ubuntu-20.04, toolchain: wasm-5.5.0-RELEASE, wasi-backend: Wasmer } + - { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Wasmer } + + runs-on: ${{ matrix.entry.os }} steps: - name: Checkout uses: actions/checkout@master with: fetch-depth: 1 - name: Run Test + env: + JAVASCRIPTKIT_WASI_BACKEND: ${{ matrix.entry.wasi-backend }} run: | git clone https://github.com/kylef/swiftenv.git ~/.swiftenv export SWIFTENV_ROOT="$HOME/.swiftenv" export PATH="$SWIFTENV_ROOT/bin:$PATH" eval "$(swiftenv init -)" - SWIFT_VERSION=${{ matrix.toolchain }} make bootstrap - echo ${{ matrix.toolchain }} > .swift-version + SWIFT_VERSION=${{ matrix.entry.toolchain }} make bootstrap + echo ${{ matrix.entry.toolchain }} > .swift-version make test native-build: # Check native build to make it easy to develop applications by Xcode diff --git a/IntegrationTests/Makefile b/IntegrationTests/Makefile index 21e8be315..312977482 100644 --- a/IntegrationTests/Makefile +++ b/IntegrationTests/Makefile @@ -1,6 +1,8 @@ CONFIGURATION ?= debug SWIFT_BUILD_FLAGS ?= +NODEJS = node --experimental-wasi-unstable-preview1 + FORCE: TestSuites/.build/$(CONFIGURATION)/%.wasm: FORCE swift build --package-path TestSuites \ @@ -27,18 +29,18 @@ benchmark_setup: build_rt dist/BenchmarkTests.wasm .PHONY: run_benchmark run_benchmark: - node bin/benchmark-tests.js + $(NODEJS) bin/benchmark-tests.js .PHONY: benchmark benchmark: benchmark_setup run_benchmark .PHONY: primary_test primary_test: build_rt dist/PrimaryTests.wasm - node bin/primary-tests.js + $(NODEJS) bin/primary-tests.js .PHONY: concurrency_test concurrency_test: build_rt dist/ConcurrencyTests.wasm - node bin/concurrency-tests.js + $(NODEJS) bin/concurrency-tests.js .PHONY: test test: concurrency_test primary_test diff --git a/IntegrationTests/bin/primary-tests.js b/IntegrationTests/bin/primary-tests.js index 94bcf7da5..2d977c3fd 100644 --- a/IntegrationTests/bin/primary-tests.js +++ b/IntegrationTests/bin/primary-tests.js @@ -95,7 +95,7 @@ global.callThrowingClosure = (c) => { } }; -const { startWasiTask } = require("../lib"); +const { startWasiTask, WASI } = require("../lib"); startWasiTask("./dist/PrimaryTests.wasm").catch((err) => { console.log(err); diff --git a/IntegrationTests/lib.js b/IntegrationTests/lib.js index c55ed3b4d..ed5c5b493 100644 --- a/IntegrationTests/lib.js +++ b/IntegrationTests/lib.js @@ -1,40 +1,81 @@ const SwiftRuntime = require("javascript-kit-swift").SwiftRuntime; -const WASI = require("@wasmer/wasi").WASI; +const WasmerWASI = require("@wasmer/wasi").WASI; const WasmFs = require("@wasmer/wasmfs").WasmFs; +const NodeWASI = require("wasi").WASI; const promisify = require("util").promisify; const fs = require("fs"); const readFile = promisify(fs.readFile); -const startWasiTask = async (wasmPath) => { - // Instantiate a new WASI Instance - const wasmFs = new WasmFs(); - // Output stdout and stderr to console - const originalWriteSync = wasmFs.fs.writeSync; - wasmFs.fs.writeSync = (fd, buffer, offset, length, position) => { - const text = new TextDecoder("utf-8").decode(buffer); - switch (fd) { - case 1: - console.log(text); - break; - case 2: - console.error(text); - break; +const WASI = { + Wasmer: () => { + // Instantiate a new WASI Instance + const wasmFs = new WasmFs(); + // Output stdout and stderr to console + const originalWriteSync = wasmFs.fs.writeSync; + wasmFs.fs.writeSync = (fd, buffer, offset, length, position) => { + const text = new TextDecoder("utf-8").decode(buffer); + switch (fd) { + case 1: + console.log(text); + break; + case 2: + console.error(text); + break; + } + return originalWriteSync(fd, buffer, offset, length, position); + }; + const wasi = new WasmerWASI({ + args: [], + env: {}, + bindings: { + ...WasmerWASI.defaultBindings, + fs: wasmFs.fs, + }, + }); + + return { + wasiImport: wasi.wasiImport, + start(instance) { + wasi.start(instance); + instance.exports._initialize(); + instance.exports.main(); + } } - return originalWriteSync(fd, buffer, offset, length, position); - }; - let wasi = new WASI({ - args: [], - env: {}, - bindings: { - ...WASI.defaultBindings, - fs: wasmFs.fs, - }, - }); + }, + Node: () => { + const wasi = new NodeWASI({ + args: [], + env: {}, + returnOnExit: true, + }) + + return { + wasiImport: wasi.wasiImport, + start(instance) { + wasi.initialize(instance); + instance.exports.main(); + } + } + }, +}; + +const selectWASIBackend = () => { + const value = process.env["JAVASCRIPTKIT_WASI_BACKEND"] + if (value) { + const backend = WASI[value]; + if (backend) { + return backend; + } + } + return WASI.Node; +}; +const startWasiTask = async (wasmPath, wasiConstructor = selectWASIBackend()) => { const swift = new SwiftRuntime(); // Fetch our Wasm File const wasmBinary = await readFile(wasmPath); + const wasi = wasiConstructor(); // Instantiate the WebAssembly file let { instance } = await WebAssembly.instantiate(wasmBinary, { @@ -45,8 +86,6 @@ const startWasiTask = async (wasmPath) => { swift.setInstance(instance); // Start the WebAssembly WASI instance! wasi.start(instance); - instance.exports._initialize(); - instance.exports.main(); }; -module.exports = { startWasiTask }; +module.exports = { startWasiTask, WASI };