Coverage for tests/component/test_linker.py: 100%

113 statements  

« prev     ^ index     » next       coverage.py v7.11.3, created at 2025-12-22 16:28 +0000

1import unittest 

2 

3from wasmtime import Engine, WasmtimeError, Module, Store 

4from wasmtime.component import Linker, Component, LinkerInstance 

5 

6 

7class TestLinker(unittest.TestCase): 

8 def test_smoke(self): 

9 engine = Engine() 

10 linker = Linker(engine) 

11 linker.allow_shadowing = True 

12 linker.allow_shadowing = False 

13 

14 def test_init_linker_instance(self): 

15 with self.assertRaises(WasmtimeError): 

16 LinkerInstance() 

17 

18 def test_root(self): 

19 engine = Engine() 

20 linker = Linker(engine) 

21 with linker.root() as root: 

22 pass 

23 with linker.root() as root: 

24 with self.assertRaises(WasmtimeError): 

25 linker.root() 

26 with linker.root() as root: 

27 pass 

28 

29 def test_add_instance(self): 

30 engine = Engine() 

31 linker = Linker(engine) 

32 with linker.root() as root: 

33 with root.add_instance('x'): 

34 pass 

35 with root.add_instance('y'): 

36 pass 

37 with self.assertRaises(WasmtimeError): 

38 root.add_instance('x') 

39 with self.assertRaises(WasmtimeError): 

40 root.add_instance('y') 

41 with root.add_instance('z'): 

42 pass 

43 

44 with linker.root() as root: 

45 with root.add_instance('again'): 

46 pass 

47 

48 with linker.root() as root: 

49 with root.add_instance('another') as x: 

50 # Reuse `root` while `x` is alive 

51 with self.assertRaises(WasmtimeError): 

52 root.add_instance('y') 

53 

54 # Reuse `x` while `x` is alive 

55 with x.add_instance('x'): 

56 with self.assertRaises(WasmtimeError): 

57 x.add_instance('y') 

58 

59 def test_add_module(self): 

60 engine = Engine() 

61 linker = Linker(engine) 

62 with linker.root() as root: 

63 root.add_module('x', Module(engine, b'(module)')) 

64 root.add_module('y', Module(engine, b'(module)')) 

65 

66 with self.assertRaises(WasmtimeError): 

67 root.add_module('x', Module(engine, b'(module)')) 

68 

69 with root.add_instance('z'): 

70 with self.assertRaises(WasmtimeError): 

71 root.add_module('not-used-yet', Module(engine, b'(module)')) 

72 

73 def test_add_wasip2(self): 

74 engine = Engine() 

75 linker = Linker(engine) 

76 linker.add_wasip2() 

77 

78 with linker.root(): 

79 with self.assertRaises(WasmtimeError): 

80 linker.add_wasip2() 

81 

82 linker.close() 

83 

84 with Linker(engine) as l2: 

85 l2.add_wasip2() 

86 with self.assertRaises(WasmtimeError): 

87 l2.add_wasip2() 

88 l2.allow_shadowing = True 

89 l2.add_wasip2() 

90 

91 def test_host_exception(self): 

92 engine = Engine() 

93 store = Store(engine) 

94 component = Component(engine, """ 

95 (component 

96 (import "x" (func $x)) 

97 (core module $a 

98 (import "" "x" (func)) 

99 (func (export "x") call 0) 

100 ) 

101 (core func $x (canon lower (func $x))) 

102 (core instance $a (instantiate $a 

103 (with "" (instance 

104 (export "x" (func $x)) 

105 )) 

106 )) 

107 (func (export "x") (canon lift (core func $a "x"))) 

108 ) 

109 """) 

110 def host_func(_store): 

111 raise RuntimeError("oh no") 

112 linker = Linker(engine) 

113 with linker.root() as l: 

114 l.add_func('x', host_func) 

115 instance = linker.instantiate(store, component) 

116 func = instance.get_func(store, 'x') 

117 assert(func is not None) 

118 with self.assertRaises(RuntimeError) as cm: 

119 func(store) 

120 self.assertEqual(str(cm.exception), "oh no") 

121 

122 def test_fail_instantiate(self): 

123 engine = Engine() 

124 store = Store(engine) 

125 component = Component(engine, """ 

126 (component 

127 (import "x" (func $x)) 

128 ) 

129 """) 

130 linker = Linker(engine) 

131 with self.assertRaises(WasmtimeError): 

132 linker.instantiate(store, component) 

133 

134 def test_shadow_func(self): 

135 engine = Engine() 

136 store = Store(engine) 

137 linker = Linker(engine) 

138 with linker.root() as l: 

139 l.add_func('x', lambda: None) 

140 with self.assertRaises(WasmtimeError): 

141 l.add_func('x', lambda: None) 

142 linker.allow_shadowing = True 

143 with linker.root() as l: 

144 l.add_func('x', lambda: None) 

145 

146 def test_define_unknown_imports_as_traps(self): 

147 engine = Engine() 

148 store = Store(engine) 

149 component = Component(engine, """ 

150 (component 

151 (import "x" (func $x)) 

152 ) 

153 """) 

154 linker = Linker(engine) 

155 with self.assertRaises(WasmtimeError): 

156 linker.instantiate(store, component) 

157 linker.define_unknown_imports_as_traps(component) 

158 linker.instantiate(store, component)