Skip to content

Commit 28446de

Browse files
committed
Add test with @wasmer/wasi
1 parent 821b1d2 commit 28446de

File tree

1 file changed

+92
-7
lines changed

1 file changed

+92
-7
lines changed

packages/npm-packages/ruby-wasm-wasi/tools/run-test-unit.mjs

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#!/bin/sh
22
":" //# ; exec /usr/bin/env node --experimental-wasi-unstable-preview1 "$0" "$@"
33

4+
import * as wasmerWasi from "@wasmer/wasi";
45
import fs from "fs/promises";
56
import path from "path";
6-
import { WASI } from "wasi";
7+
import * as nodeWasi from "wasi";
78
import { RubyVM } from "../dist/index.cjs.js";
89

9-
const instantiate = async (rootTestFile) => {
10+
const instantiateNodeWasi = async (rootTestFile) => {
1011
const dirname = path.dirname(new URL(import.meta.url).pathname);
1112
let binaryPath;
1213
let preopens = {
@@ -20,15 +21,15 @@ const instantiate = async (rootTestFile) => {
2021
}
2122
const binary = await fs.readFile(binaryPath);
2223
const rubyModule = await WebAssembly.compile(binary);
23-
const wasi = new WASI({
24+
const wasi = new nodeWasi.WASI({
2425
stdio: "inherit",
2526
args: ["ruby.wasm"].concat(process.argv.slice(2)),
2627
env: {
2728
...process.env,
2829
// Extend fiber stack size to be able to run test-unit
2930
"RUBY_FIBER_MACHINE_STACK_SIZE": String(1024 * 1024 * 20),
3031
},
31-
preopens: preopens,
32+
preopens,
3233
});
3334

3435
const vm = new RubyVM();
@@ -44,12 +45,82 @@ const instantiate = async (rootTestFile) => {
4445
wasi.initialize(instance);
4546

4647
vm.initialize(["ruby.wasm", rootTestFile]);
47-
return { instance, vm };
48+
return { instance, vm, wasi };
4849
};
4950

50-
const main = async () => {
51+
const instantiateWasmerWasi = async (rootTestFile) => {
52+
await wasmerWasi.init();
53+
54+
const memFs = new wasmerWasi.MemFS();
55+
const walk = async (dir) => {
56+
const names = await fs.readdir(dir);
57+
const files = await Promise.all(names.map(async name => {
58+
if ((await fs.stat(path.join(dir, name))).isDirectory()) {
59+
return walk(path.join(dir, name));
60+
} else {
61+
return [path.join(dir, name)];
62+
}
63+
}));
64+
return files.flat();
65+
};
66+
const mkdirpMemFs = (guestPath) => {
67+
const parts = guestPath.split('/');
68+
for (let i = 2; i <= parts.length; i++) {
69+
memFs.createDir(parts.slice(0, i).join('/'));
70+
}
71+
};
72+
const loadToMemFs = async (guestPath, hostPath) => {
73+
const hostFiles = await walk(hostPath);
74+
await Promise.all(hostFiles.map(async hostFile => {
75+
const guestFile = path.join(guestPath, path.relative(hostPath, hostFile));
76+
mkdirpMemFs(path.dirname(guestFile));
77+
const contents = await fs.readFile(hostFile);
78+
memFs.open(guestFile, { write: true, create: true }).write(contents);
79+
}));
80+
};
81+
82+
const dirname = path.dirname(new URL(import.meta.url).pathname);
83+
await loadToMemFs('/__root__/test', path.join(dirname, '../test'));
84+
const preopens = {
85+
__root__: '/__root__',
86+
};
87+
88+
const binaryPath = path.join(dirname, "../dist/ruby+stdlib.wasm");
89+
if (process.env.RUBY_ROOT) {
90+
console.error('For now, testing with RUBY_ROOT is not supported.');
91+
}
92+
93+
const binary = await fs.readFile(binaryPath);
94+
const rubyModule = await WebAssembly.compile(binary);
95+
96+
const wasi = new wasmerWasi.WASI({
97+
args: ["ruby.wasm"].concat(process.argv.slice(2)),
98+
env: {
99+
...process.env,
100+
// Extend fiber stack size to be able to run test-unit
101+
"RUBY_FIBER_MACHINE_STACK_SIZE": String(1024 * 1024 * 20),
102+
},
103+
preopens,
104+
fs: memFs,
105+
});
106+
107+
const vm = new RubyVM();
108+
const imports = wasi.getImports(rubyModule);
109+
vm.addToImports(imports);
110+
111+
const instance = await WebAssembly.instantiate(rubyModule, imports);
112+
wasi.instantiate(instance);
113+
await vm.setInstance(instance);
114+
115+
instance.exports._initialize();
116+
vm.initialize(["ruby.wasm", rootTestFile]);
117+
118+
return { instance, vm, wasi };
119+
};
120+
121+
const test = async (instantiate) => {
51122
const rootTestFile = "/__root__/test/test_unit.rb";
52-
const { vm } = await instantiate(rootTestFile);
123+
const { vm, wasi } = await instantiate(rootTestFile);
53124

54125
Error.stackTraceLimit = Infinity;
55126

@@ -71,6 +142,20 @@ const main = async () => {
71142
require_relative '${rootTestFile}'
72143
Test::Unit::AutoRunner.run
73144
`);
145+
146+
// TODO(makenowjust): override `wasi_snapshot_preview1.fd_write` for output to stdout/stderr.
147+
// See `src/browser.ts`.
148+
if (wasi.getStderrString) {
149+
console.error(wasi.getStderrString());
150+
}
151+
if (wasi.getStdoutString) {
152+
console.log(wasi.getStdoutString());
153+
}
154+
};
155+
156+
const main = async () => {
157+
await test(instantiateNodeWasi);
158+
await test(instantiateWasmerWasi);
74159
};
75160
76161
main();

0 commit comments

Comments
 (0)