Coverage for tests/test_module.py: 100%

97 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-20 16:25 +0000

1import unittest 

2import tempfile 

3 

4from wasmtime import * 

5 

6 

7class TestModule(unittest.TestCase): 

8 def test_smoke(self): 

9 Module(Engine(), '(module)') 

10 Module(Engine(), bytes(b'\0asm\x01\0\0\0')) 

11 Module(Engine(), bytearray(b'\0asm\x01\0\0\0')) 

12 

13 def test_invalid(self): 

14 with self.assertRaises(AttributeError): 

15 Module.validate(1, b'') # type: ignore 

16 with self.assertRaises(TypeError): 

17 Module.validate(Store(), 2) # type: ignore 

18 with self.assertRaises(TypeError): 

19 Module(1, b'') # type: ignore 

20 with self.assertRaises(TypeError): 

21 Module(Engine(), 2) # type: ignore 

22 with self.assertRaises(WasmtimeError): 

23 Module(Engine(), b'') 

24 with self.assertRaises(WasmtimeError): 

25 Module(Engine(), b'\x00') 

26 

27 def test_validate(self): 

28 engine = Engine() 

29 Module.validate(engine, b'\0asm\x01\0\0\0') 

30 with self.assertRaises(WasmtimeError): 

31 Module.validate(engine, b'') 

32 

33 def test_imports(self): 

34 store = Store() 

35 module = Module(store.engine, '(module)') 

36 self.assertEqual(module.imports, []) 

37 

38 module = Module(store.engine, """ 

39 (module 

40 (import "" "" (func)) 

41 (import "a" "bcd" (global i32)) 

42 (import "" "" (memory 1)) 

43 (import "" "x" (table 1 funcref)) 

44 ) 

45 """) 

46 imports = module.imports 

47 self.assertEqual(len(imports), 4) 

48 self.assertEqual(imports[0].module, "") 

49 self.assertEqual(imports[0].name, "") 

50 ty = imports[0].type 

51 assert(isinstance(ty, FuncType)) 

52 self.assertEqual(ty.params, []) 

53 self.assertEqual(ty.results, []) 

54 

55 self.assertEqual(imports[1].module, "a") 

56 self.assertEqual(imports[1].name, "bcd") 

57 ty = imports[1].type 

58 assert(isinstance(ty, GlobalType)) 

59 self.assertEqual(ty.content, ValType.i32()) 

60 self.assertFalse(ty.mutable) 

61 

62 self.assertEqual(imports[2].module, "") 

63 self.assertEqual(imports[2].name, "") 

64 ty = imports[2].type 

65 assert(isinstance(ty, MemoryType)) 

66 self.assertEqual(ty.limits, Limits(1, None)) 

67 

68 self.assertEqual(imports[3].module, "") 

69 self.assertEqual(imports[3].name, "x") 

70 ty = imports[3].type 

71 assert(isinstance(ty, TableType)) 

72 self.assertEqual(ty.limits, Limits(1, None)) 

73 self.assertEqual(ty.element, ValType.funcref()) 

74 

75 def test_exports(self): 

76 store = Store() 

77 module = Module(store.engine, '(module)') 

78 self.assertEqual(module.exports, []) 

79 

80 module = Module(store.engine, """ 

81 (module 

82 (func (export "a") (param i32 f32) (result f64) 

83 f64.const 0) 

84 (global (export "") (mut i32) (i32.const 1)) 

85 (memory (export "mem") 1) 

86 (table (export "table") 1 funcref) 

87 ) 

88 """) 

89 exports = module.exports 

90 self.assertEqual(len(exports), 4) 

91 self.assertEqual(exports[0].name, "a") 

92 ty = exports[0].type 

93 assert(isinstance(ty, FuncType)) 

94 self.assertEqual(ty.params, [ValType.i32(), ValType.f32()]) 

95 self.assertEqual(ty.results, [ValType.f64()]) 

96 

97 self.assertEqual(exports[1].name, "") 

98 ty = exports[1].type 

99 assert(isinstance(ty, GlobalType)) 

100 self.assertEqual(ty.content, ValType.i32()) 

101 self.assertTrue(ty.mutable) 

102 

103 self.assertEqual(exports[2].name, "mem") 

104 ty = exports[2].type 

105 assert(isinstance(ty, MemoryType)) 

106 self.assertEqual(ty.limits, Limits(1, None)) 

107 

108 self.assertEqual(exports[3].name, "table") 

109 ty = exports[3].type 

110 assert(isinstance(ty, TableType)) 

111 self.assertEqual(ty.limits, Limits(1, None)) 

112 self.assertEqual(ty.element, ValType.funcref()) 

113 

114 def test_serialize(self): 

115 engine = Engine() 

116 module = Module(engine, '(module)') 

117 encoded = module.serialize() 

118 module = Module.deserialize(engine, encoded) 

119 assert(len(module.imports) == 0) 

120 assert(len(module.exports) == 0) 

121 with tempfile.TemporaryDirectory() as d: 

122 path = d + '/module.bin' 

123 with open(path, 'wb') as f: 

124 f.write(encoded) 

125 module = Module.deserialize_file(engine, path) 

126 assert(len(module.imports) == 0) 

127 assert(len(module.exports) == 0) 

128 

129 # Run the destructor for `Module` which has an mmap to the file 

130 # which prevents deletion on Windows. 

131 del module