@@ -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