@@ -12,9 +12,11 @@ module Wasmtime
12
12
# Compile module only once for speed
13
13
@compiled_wasi_module = @engine . precompile_module ( IO . binread ( "spec/fixtures/wasi-debug.wasm" ) )
14
14
@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" ) )
15
16
16
17
@compiled_wasi_component = @engine . precompile_component ( IO . binread ( "spec/fixtures/wasi-debug-p2.wasm" ) )
17
18
@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" ) )
18
20
end
19
21
20
22
describe "Linker.new" do
@@ -233,13 +235,103 @@ module Wasmtime
233
235
end
234
236
end
235
237
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
307
+
308
+ it "does not accept an invalid host path" do
309
+ wasi_config = WasiConfig . new
310
+ . set_mapped_directory ( tempfile_path ( "tmp" ) , "/tmp" , :all , :all )
311
+
312
+ expect { run_fs . call ( wasi_config ) } . to raise_error do |error |
313
+ expect ( error ) . to be_a ( Wasmtime ::Error )
314
+ # error message is os-specific
315
+ end
316
+ end
317
+
318
+ it "does not accept invalid permissions" do
319
+ wasi_config = WasiConfig . new
320
+ . set_mapped_directory ( tempfile_path ( "tmp" ) , "/tmp" , :mutate , :invalid_permission )
321
+
322
+ expect { run_fs . call ( wasi_config ) } . to raise_error do |error |
323
+ expect ( error ) . to be_a ( Wasmtime ::Error )
324
+ expect ( error . message ) . to match ( /Invalid file_perms: invalid_permission. Use one of :read, :write, or :all/ )
325
+ end
326
+ end
236
327
end
237
328
238
329
describe "WasiConfig preview 1" do
239
330
it_behaves_like WasiConfig do
240
331
let ( :run ) { method ( :run_wasi_module ) }
241
332
let ( :wasi_env ) { method ( :wasi_module_env ) }
242
333
let ( :run_deterministic ) { method ( :run_wasi_module_deterministic ) }
334
+ let ( :run_fs ) { method ( :run_wasi_module_fs ) }
243
335
end
244
336
end
245
337
@@ -248,6 +340,7 @@ module Wasmtime
248
340
let ( :run ) { method ( :run_wasi_component ) }
249
341
let ( :wasi_env ) { method ( :wasi_component_env ) }
250
342
let ( :run_deterministic ) { method ( :run_wasi_component_deterministic ) }
343
+ let ( :run_fs ) { method ( :run_wasi_component_fs ) }
251
344
end
252
345
end
253
346
@@ -272,6 +365,13 @@ def run_wasi_module_deterministic(wasi_config)
272
365
. invoke ( "_start" )
273
366
end
274
367
368
+ def run_wasi_module_fs ( wasi_config )
369
+ linker = Linker . new ( @engine )
370
+ WASI ::P1 . add_to_linker_sync ( linker )
371
+ store = Store . new ( @engine , wasi_p1_config : wasi_config )
372
+ linker . instantiate ( store , Module . deserialize ( @engine , @compiled_wasi_fs_module ) ) . invoke ( "_start" )
373
+ end
374
+
275
375
def wasi_module_env
276
376
stdout_file = tempfile_path ( "stdout" )
277
377
@@ -318,6 +418,17 @@ def run_wasi_component_deterministic(wasi_config)
318
418
) . call_run ( store )
319
419
end
320
420
421
+ def run_wasi_component_fs ( wasi_config )
422
+ linker = Component ::Linker . new ( @engine )
423
+ WASI ::P2 . add_to_linker_sync ( linker )
424
+ store = Store . new ( @engine , wasi_config : wasi_config )
425
+ Component ::WasiCommand . new (
426
+ store ,
427
+ Component ::Component . deserialize ( @engine , @compiled_wasi_fs_component ) ,
428
+ linker
429
+ ) . call_run ( store )
430
+ end
431
+
321
432
def tempfile_path ( name )
322
433
File . join ( tmpdir , name )
323
434
end
0 commit comments