Coverage for tests/test_wasi.py: 95%

58 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-12-01 19:40 +0000

1import unittest 

2import tempfile 

3 

4from wasmtime import * 

5from pathlib import Path 

6 

7 

8class TestWasi(unittest.TestCase): 

9 def test_config(self): 

10 config = WasiConfig() 

11 config.argv = ['a', 'b'] 

12 config.inherit_argv() 

13 config.env = [['a', 'b']] 

14 config.inherit_env() 

15 

16 with tempfile.NamedTemporaryFile() as f: 

17 config.stdin_file = f.name 

18 config.stdin_file = Path(f.name) 

19 config.inherit_stdin() 

20 config.stdout_file = f.name 

21 config.stdout_file = Path(f.name) 

22 config.inherit_stdout() 

23 config.stderr_file = f.name 

24 config.stderr_file = Path(f.name) 

25 config.inherit_stderr() 

26 

27 with self.assertRaises(WasmtimeError): 

28 config.stdin_file = 'somewhere-over-the-rainboat' 

29 with self.assertRaises(WasmtimeError): 

30 config.stdout_file = 'some-directory/without-a-rainbow' 

31 with self.assertRaises(WasmtimeError): 

32 config.stderr_file = 'some-directory/without-a-rainbow' 

33 config.preopen_dir('wasmtime', 'other', DirPerms.READ_WRITE, FilePerms.READ_WRITE) 

34 config.preopen_dir('wasmtime', 'other2') 

35 

36 def test_preview1(self): 

37 linker = Linker(Engine()) 

38 linker.define_wasi() 

39 

40 module = Module(linker.engine, """ 

41 (module 

42 (import "wasi_snapshot_preview1" "random_get" 

43 (func (param i32 i32) (result i32))) 

44 ) 

45 """) 

46 

47 store = Store(linker.engine) 

48 store.set_wasi(WasiConfig()) 

49 linker.instantiate(store, module) 

50 

51 def preopen_nonexistent(self): 

52 config = WasiConfig() 

53 with self.assertRaises(WasmtimeError): 

54 config.preopen_dir('/path/to/nowhere', '/', DirPerms.READ_ONLY, FilePerms.READ_ONLY) 

55 

56 def test_custom_print(self): 

57 linker = Linker(Engine()) 

58 linker.define_wasi() 

59 

60 stderr = '' 

61 stdout = '' 

62 

63 def on_stdout(data: bytes) -> None: 

64 nonlocal stdout 

65 stdout += data.decode('utf8') 

66 

67 def on_stderr(data: bytes) -> None: 

68 nonlocal stderr 

69 stderr += data.decode('utf8') 

70 

71 module = Module(linker.engine, """ 

72 (module 

73 (import "wasi_snapshot_preview1" "fd_write" 

74 (func $write (param i32 i32 i32 i32) (result i32))) 

75 

76 (memory (export "memory") 1) 

77 

78 (func $print 

79 (i32.store (i32.const 300) (i32.const 100)) ;; iov base 

80 (i32.store (i32.const 304) (i32.const 14)) ;; iov len 

81 

82 (call $write 

83 (i32.const 1) ;; fd 1 is stdout 

84 (i32.const 300) ;; iovecs ptr 

85 (i32.const 1) ;; iovecs len 

86 (i32.const 400)) ;; nwritten ptr 

87 if unreachable end ;; verify no error 

88 

89 (i32.store (i32.const 300) (i32.const 200)) ;; iov base 

90 (i32.store (i32.const 304) (i32.const 14)) ;; iov len 

91 

92 (call $write 

93 (i32.const 2) ;; fd 2 is stderr 

94 (i32.const 300) ;; iovecs ptr 

95 (i32.const 1) ;; iovecs len 

96 (i32.const 400)) ;; nwritten ptr 

97 if unreachable end ;; verify no error 

98 ) 

99 

100 (start $print) 

101 

102 (data (i32.const 100) "Hello, stdout!") 

103 (data (i32.const 200) "Hello, stderr!") 

104 ) 

105 """) 

106 

107 wasi = WasiConfig() 

108 wasi.stdout_custom = on_stdout 

109 wasi.stderr_custom = on_stderr 

110 

111 store = Store(linker.engine) 

112 store.set_wasi(wasi) 

113 linker.instantiate(store, module) 

114 

115 self.assertEqual('Hello, stdout!', stdout) 

116 self.assertEqual('Hello, stderr!', stderr)