Skip to content

Test with Node.js's WASI implementation #192

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

Merged
merged 2 commits into from
May 11, 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
25 changes: 18 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions IntegrationTests/Makefile
Original file line number Diff line number Diff line change
@@ -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 \
Expand All @@ -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
2 changes: 1 addition & 1 deletion IntegrationTests/bin/primary-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
95 changes: 67 additions & 28 deletions IntegrationTests/lib.js
Original file line number Diff line number Diff line change
@@ -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, {
Expand All @@ -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 };