Skip to content

Commit 8616293

Browse files
Add tests for mapped directories
1 parent 6f09565 commit 8616293

File tree

7 files changed

+135
-0
lines changed

7 files changed

+135
-0
lines changed

spec/fixtures/wasi-fs-p2.wasm

129 KB
Binary file not shown.

spec/fixtures/wasi-fs.wasm

64.4 KB
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
target = "wasm32-wasip1"

spec/fixtures/wasi-fs/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "wasi-fs"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[workspace]
9+
10+
[dependencies]

spec/fixtures/wasi-fs/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Example WASI program used to test WASI preopened directories
2+
3+
To update:
4+
5+
```shell
6+
cargo build --release && \
7+
wasm-opt -O \
8+
--enable-bulk-memory \
9+
target/wasm32-wasip1/release/wasi-fs.wasm \
10+
-o ../wasi-fs.wasm && \
11+
cargo build --target=wasm32-wasip2 --release && \
12+
cp target/wasm32-wasip2/release/wasi-fs.wasm \
13+
../wasi-fs-p2.wasm
14+
```

spec/fixtures/wasi-fs/src/main.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::io::{Write, Read};
2+
use std::fs::File;
3+
4+
fn main() {
5+
let args: Vec<String> = std::env::args().collect();
6+
7+
let counter_file = File::open(&args[1]).expect("failed to open counter file");
8+
9+
let mut counter_str = String::new();
10+
counter_file.take(100).read_to_string(&mut counter_str)
11+
.expect("failed to read counter file");
12+
let mut counter: u32 = counter_str.trim().parse().expect("failed to parse counter");
13+
14+
counter += 1;
15+
16+
let mut counter_file = File::create(&args[1]).expect("failed to create counter file");
17+
write!(counter_file, "{}", counter).expect("failed to write counter file");
18+
}

spec/unit/wasi_spec.rb

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ module Wasmtime
1212
# Compile module only once for speed
1313
@compiled_wasi_module = @engine.precompile_module(IO.binread("spec/fixtures/wasi-debug.wasm"))
1414
@compiled_wasi_deterministic_module = @engine.precompile_module(IO.binread("spec/fixtures/wasi-deterministic.wasm"))
15+
@compiled_wasi_fs_module = @engine.precompile_module(IO.binread("spec/fixtures/wasi-fs.wasm"))
1516

1617
@compiled_wasi_component = @engine.precompile_component(IO.binread("spec/fixtures/wasi-debug-p2.wasm"))
1718
@compiled_wasi_deterministic_component = @engine.precompile_component(IO.binread("spec/fixtures/wasi-deterministic-p2.wasm"))
19+
@compiled_wasi_fs_component = @engine.precompile_component(IO.binread("spec/fixtures/wasi-fs-p2.wasm"))
1820
end
1921

2022
describe "Linker.new" do
@@ -233,13 +235,83 @@ module Wasmtime
233235
end
234236
end
235237
end
238+
239+
it "writes to mapped directory" do
240+
Dir.mkdir(tempfile_path("tmp"))
241+
File.write(tempfile_path(File.join("tmp", "counter")), "0")
242+
243+
wasi_config = WasiConfig.new
244+
.set_argv(["wasi-fs", "/tmp/counter"])
245+
.set_mapped_directory(tempfile_path("tmp"), "/tmp", :all, :all)
246+
247+
expect { run_fs.call(wasi_config) }.not_to raise_error
248+
249+
expect(File.read(tempfile_path(File.join("tmp", "counter")))).to eq("1")
250+
end
251+
252+
it "fails to write to mapped directory if not permitted" do
253+
Dir.mkdir(tempfile_path("tmp"))
254+
File.write(tempfile_path(File.join("tmp", "counter")), "0")
255+
256+
stderr_str = ""
257+
wasi_config = WasiConfig.new
258+
.set_argv(["wasi-fs", "/tmp/counter"])
259+
.set_stderr_buffer(stderr_str, 40000)
260+
.set_mapped_directory(tempfile_path("tmp"), "/tmp", :read, :read)
261+
262+
expect { run_fs.call(wasi_config) }.to raise_error do |error|
263+
expect(error).to be_a(Wasmtime::Error)
264+
end
265+
266+
expect(stderr_str).to match(/failed to create counter file/)
267+
268+
expect(File.read(tempfile_path(File.join("tmp", "counter")))).to eq("0")
269+
end
270+
271+
it "fails to read from mapped directory if not permitted" do
272+
Dir.mkdir(tempfile_path("tmp"))
273+
File.write(tempfile_path(File.join("tmp", "counter")), "0")
274+
275+
stderr_str = ""
276+
wasi_config = WasiConfig.new
277+
.set_argv(["wasi-fs", "/tmp/counter"])
278+
.set_stderr_buffer(stderr_str, 40000)
279+
.set_mapped_directory(tempfile_path("tmp"), "/tmp", :mutate, :write)
280+
281+
expect { run_fs.call(wasi_config) }.to raise_error do |error|
282+
expect(error).to be_a(Wasmtime::Error)
283+
end
284+
285+
expect(stderr_str).to match(/failed to open counter file/)
286+
287+
expect(File.read(tempfile_path(File.join("tmp", "counter")))).to eq("0")
288+
end
289+
290+
it "fails to access non-mapped directories" do
291+
Dir.mkdir(tempfile_path("tmp"))
292+
File.write(tempfile_path(File.join("tmp", "counter")), "0")
293+
294+
stderr_str = ""
295+
wasi_config = WasiConfig.new
296+
.set_argv(["wasi-fs", File.join(tempfile_path("tmp"), "counter")])
297+
.set_stderr_buffer(stderr_str, 40000)
298+
299+
expect { run_fs.call(wasi_config) }.to raise_error do |error|
300+
expect(error).to be_a(Wasmtime::Error)
301+
end
302+
303+
expect(stderr_str).to match(/failed to find a pre-opened file descriptor/)
304+
305+
expect(File.read(tempfile_path(File.join("tmp", "counter")))).to eq("0")
306+
end
236307
end
237308

238309
describe "WasiConfig preview 1" do
239310
it_behaves_like WasiConfig do
240311
let(:run) { method(:run_wasi_module) }
241312
let(:wasi_env) { method(:wasi_module_env) }
242313
let(:run_deterministic) { method(:run_wasi_module_deterministic) }
314+
let(:run_fs) { method(:run_wasi_module_fs) }
243315
end
244316
end
245317

@@ -248,6 +320,7 @@ module Wasmtime
248320
let(:run) { method(:run_wasi_component) }
249321
let(:wasi_env) { method(:wasi_component_env) }
250322
let(:run_deterministic) { method(:run_wasi_component_deterministic) }
323+
let(:run_fs) { method(:run_wasi_component_fs) }
251324
end
252325
end
253326

@@ -272,6 +345,13 @@ def run_wasi_module_deterministic(wasi_config)
272345
.invoke("_start")
273346
end
274347

348+
def run_wasi_module_fs(wasi_config)
349+
linker = Linker.new(@engine)
350+
WASI::P1.add_to_linker_sync(linker)
351+
store = Store.new(@engine, wasi_p1_config: wasi_config)
352+
linker.instantiate(store, Module.deserialize(@engine, @compiled_wasi_fs_module)).invoke("_start")
353+
end
354+
275355
def wasi_module_env
276356
stdout_file = tempfile_path("stdout")
277357

@@ -318,6 +398,17 @@ def run_wasi_component_deterministic(wasi_config)
318398
).call_run(store)
319399
end
320400

401+
def run_wasi_component_fs(wasi_config)
402+
linker = Component::Linker.new(@engine)
403+
WASI::P2.add_to_linker_sync(linker)
404+
store = Store.new(@engine, wasi_config: wasi_config)
405+
Component::WasiCommand.new(
406+
store,
407+
Component::Component.deserialize(@engine, @compiled_wasi_fs_component),
408+
linker
409+
).call_run(store)
410+
end
411+
321412
def tempfile_path(name)
322413
File.join(tmpdir, name)
323414
end

0 commit comments

Comments
 (0)