Files: 8fc026b2a62edac0dd238380f77dfa98fb0e5b33 / tests / index.js
10714 bytesRaw
1 | const tape = require('tape') |
2 | const fs = require('fs') |
3 | const path = require('path') |
4 | const Buffer = require('safe-buffer').Buffer |
5 | const {Message, FunctionRef} = require('primea-objects') |
6 | const Hypervisor = require('primea-hypervisor') |
7 | const EgressDriver = require('primea-hypervisor/egressDriver') |
8 | const WasmContainer = require('../') |
9 | |
10 | const level = require('level-browserify') |
11 | const RadixTree = require('dfinity-radix-tree') |
12 | |
13 | const db = level(`${__dirname}/testdb`) |
14 | const WASM_PATH = path.join(__dirname, 'wasm') |
15 | |
16 | let tester |
17 | |
18 | class TestWasmContainer extends WasmContainer { |
19 | constructor (actor) { |
20 | super(actor) |
21 | this._storage = new Map() |
22 | const self = this |
23 | const inter = { |
24 | test: { |
25 | check: (a, b) => { |
26 | tester.equals(a, b) |
27 | }, |
28 | print: (dataRef) => { |
29 | let buf = self.refs.get(dataRef, 'data') |
30 | console.log(buf.toString()) |
31 | } |
32 | } |
33 | } |
34 | this.interface = Object.assign(this.interface, inter) |
35 | } |
36 | } |
37 | |
38 | tape('i64', async t => { |
39 | t.plan(1) |
40 | tester = t |
41 | const tree = new RadixTree({db}) |
42 | let wasm = fs.readFileSync(WASM_PATH + '/i64.wasm') |
43 | |
44 | const hypervisor = new Hypervisor(tree) |
45 | hypervisor.registerContainer(TestWasmContainer) |
46 | |
47 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
48 | const funcRef = module.getFuncRef('main') |
49 | funcRef.gas = 322000 |
50 | |
51 | const message = new Message({ |
52 | funcRef |
53 | }) |
54 | hypervisor.send(message) |
55 | }) |
56 | |
57 | tape('get_gas_budget', async t => { |
58 | t.plan(2) |
59 | tester = t |
60 | const tree = new RadixTree({db}) |
61 | let wasm = fs.readFileSync(WASM_PATH + '/get_gas_budget.wasm') |
62 | |
63 | const hypervisor = new Hypervisor(tree) |
64 | hypervisor.registerContainer(TestWasmContainer) |
65 | |
66 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
67 | const funcRef = module.getFuncRef('main') |
68 | funcRef.gas = 322000 |
69 | |
70 | const message = new Message({ |
71 | funcRef |
72 | }) |
73 | hypervisor.send(message) |
74 | }) |
75 | |
76 | tape('reintinalizing', async t => { |
77 | t.plan(1) |
78 | tester = t |
79 | const tree = new RadixTree({db}) |
80 | let wasm = fs.readFileSync(WASM_PATH + '/reinternalize.wasm') |
81 | |
82 | const hypervisor = new Hypervisor(tree) |
83 | hypervisor.registerContainer(TestWasmContainer) |
84 | |
85 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
86 | const funcRef = module.getFuncRef('main') |
87 | funcRef.gas = 322000 |
88 | |
89 | const message = new Message({ |
90 | funcRef |
91 | }) |
92 | hypervisor.send(message) |
93 | }) |
94 | |
95 | tape('basic', async t => { |
96 | t.plan(1) |
97 | tester = t |
98 | |
99 | const tree = new RadixTree({ |
100 | db |
101 | }) |
102 | |
103 | const wasm = fs.readFileSync(WASM_PATH + '/reciever.wasm') |
104 | |
105 | const hypervisor = new Hypervisor(tree) |
106 | hypervisor.registerContainer(TestWasmContainer) |
107 | |
108 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
109 | const funcRef = module.getFuncRef('receive') |
110 | funcRef.gas = 300 |
111 | |
112 | const message = new Message({ |
113 | funcRef, |
114 | funcArguments: [5] |
115 | }) |
116 | hypervisor.send(message) |
117 | // const stateRoot = await hypervisor.createStateRoot() |
118 | // t.deepEquals(stateRoot, expectedState, 'expected root!') |
119 | }) |
120 | |
121 | tape('empty', async t => { |
122 | t.plan(1) |
123 | tester = t |
124 | const expectedState = Buffer.from('bb15867b26293aa36c774b8c82541dd64212ba9a', 'hex') |
125 | |
126 | const tree = new RadixTree({ |
127 | db |
128 | }) |
129 | |
130 | const wasm = fs.readFileSync(WASM_PATH + '/empty.wasm') |
131 | |
132 | const hypervisor = new Hypervisor(tree) |
133 | hypervisor.registerContainer(TestWasmContainer) |
134 | |
135 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
136 | const funcRef = module.getFuncRef('receive') |
137 | funcRef.gas = 300 |
138 | |
139 | const message = new Message({ |
140 | funcRef, |
141 | funcArguments: [5] |
142 | }) |
143 | hypervisor.send(message) |
144 | const stateRoot = await hypervisor.createStateRoot() |
145 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
146 | }) |
147 | |
148 | tape('two communicating actors', async t => { |
149 | t.plan(1) |
150 | tester = t |
151 | |
152 | const tree = new RadixTree({db}) |
153 | |
154 | const recieverWasm = fs.readFileSync(WASM_PATH + '/reciever.wasm') |
155 | const callerWasm = fs.readFileSync(WASM_PATH + '/caller.wasm') |
156 | |
157 | const hypervisor = new Hypervisor(tree) |
158 | hypervisor.registerContainer(TestWasmContainer) |
159 | |
160 | const {module: receiverMod} = await hypervisor.createActor(TestWasmContainer.typeId, recieverWasm) |
161 | const {module: callerMod} = await hypervisor.createActor(TestWasmContainer.typeId, callerWasm) |
162 | const callFuncRef = callerMod.getFuncRef('call') |
163 | const recvFuncRef = receiverMod.getFuncRef('receive') |
164 | callFuncRef.gas = 100000 |
165 | recvFuncRef.gas = 1000 |
166 | const message = new Message({ |
167 | funcRef: callFuncRef, |
168 | funcArguments: [recvFuncRef] |
169 | }) |
170 | |
171 | hypervisor.send(message) |
172 | }) |
173 | |
174 | tape('two communicating actors with callback', async t => { |
175 | t.plan(1) |
176 | tester = t |
177 | |
178 | const tree = new RadixTree({ |
179 | db |
180 | }) |
181 | |
182 | const recieverWasm = fs.readFileSync(WASM_PATH + '/funcRef_reciever.wasm') |
183 | const callerWasm = fs.readFileSync(WASM_PATH + '/funcRef_caller.wasm') |
184 | |
185 | const hypervisor = new Hypervisor(tree) |
186 | hypervisor.registerContainer(TestWasmContainer) |
187 | |
188 | const {module: callerMod} = await hypervisor.createActor(TestWasmContainer.typeId, callerWasm) |
189 | const {module: receiverMod} = await hypervisor.createActor(TestWasmContainer.typeId, recieverWasm) |
190 | |
191 | const callFuncRef = callerMod.getFuncRef('call') |
192 | const recvFuncRef = receiverMod.getFuncRef('receive') |
193 | callFuncRef.gas = 100000 |
194 | recvFuncRef.gas = 100000 |
195 | |
196 | const message = new Message({ |
197 | funcRef: callFuncRef, |
198 | funcArguments: [recvFuncRef] |
199 | }) |
200 | |
201 | hypervisor.send(message) |
202 | }) |
203 | |
204 | tape('two communicating actors with private callback', async t => { |
205 | t.plan(1) |
206 | tester = t |
207 | |
208 | const tree = new RadixTree({ |
209 | db |
210 | }) |
211 | |
212 | const recieverWasm = fs.readFileSync(WASM_PATH + '/funcRef_reciever.wasm') |
213 | const callerWasm = fs.readFileSync(WASM_PATH + '/private_caller.wasm') |
214 | |
215 | const hypervisor = new Hypervisor(tree) |
216 | hypervisor.registerContainer(TestWasmContainer) |
217 | |
218 | const {module: callerMod} = await hypervisor.createActor(TestWasmContainer.typeId, callerWasm) |
219 | const {module: receiverMod} = await hypervisor.createActor(TestWasmContainer.typeId, recieverWasm) |
220 | |
221 | const callFuncRef = callerMod.getFuncRef('call') |
222 | const recvFuncRef = receiverMod.getFuncRef('receive') |
223 | callFuncRef.gas = 100000 |
224 | recvFuncRef.gas = 100000 |
225 | |
226 | const message = new Message({ |
227 | funcRef: callFuncRef, |
228 | funcArguments: [recvFuncRef] |
229 | }) |
230 | |
231 | hypervisor.send(message) |
232 | }) |
233 | |
234 | tape('externalize/internalize memory', async t => { |
235 | t.plan(1) |
236 | tester = t |
237 | const tree = new RadixTree({ |
238 | db |
239 | }) |
240 | |
241 | const wasm = fs.readFileSync(WASM_PATH + '/memory.wasm') |
242 | |
243 | const hypervisor = new Hypervisor(tree) |
244 | hypervisor.registerContainer(TestWasmContainer) |
245 | |
246 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
247 | const funcRef = module.getFuncRef('test') |
248 | funcRef.gas = 10000 |
249 | |
250 | const message = new Message({funcRef}).on('done', actor => { |
251 | const a = actor.container.get8Memory(0, 5) |
252 | const b = actor.container.get8Memory(5, 5) |
253 | t.deepEquals(a, b, 'should copy memory correctly') |
254 | }) |
255 | hypervisor.send(message) |
256 | }) |
257 | |
258 | tape('externalize/internalize table', async t => { |
259 | t.plan(1) |
260 | tester = t |
261 | const tree = new RadixTree({ |
262 | db |
263 | }) |
264 | |
265 | const wasm = fs.readFileSync(WASM_PATH + '/table.wasm') |
266 | const hypervisor = new Hypervisor(tree) |
267 | hypervisor.registerContainer(TestWasmContainer) |
268 | |
269 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
270 | |
271 | const funcRef = module.getFuncRef('test') |
272 | funcRef.gas = 10000 |
273 | |
274 | const message = new Message({funcRef}).on('done', actor => { |
275 | const a = actor.container.get8Memory(0, 8) |
276 | const b = actor.container.get8Memory(8, 8) |
277 | t.deepEquals(a, b, 'should copy memory correctly') |
278 | }) |
279 | hypervisor.send(message) |
280 | }) |
281 | |
282 | tape('creation', async t => { |
283 | t.plan(1) |
284 | tester = t |
285 | const tree = new RadixTree({db}) |
286 | let wasm = fs.readFileSync(WASM_PATH + '/creation.wasm') |
287 | let receiver = fs.readFileSync(WASM_PATH + '/reciever.wasm') |
288 | |
289 | const hypervisor = new Hypervisor(tree) |
290 | hypervisor.registerContainer(TestWasmContainer) |
291 | |
292 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
293 | const funcRef = module.getFuncRef('main') |
294 | funcRef.gas = 322000 |
295 | |
296 | const message = new Message({ |
297 | funcRef, |
298 | funcArguments: [receiver] |
299 | }) |
300 | hypervisor.send(message) |
301 | }) |
302 | |
303 | tape('storage', async t => { |
304 | tester = t |
305 | const tree = new RadixTree({db}) |
306 | let wasm = fs.readFileSync(WASM_PATH + '/storage.wasm') |
307 | |
308 | const egress = new EgressDriver() |
309 | |
310 | egress.on('message', msg => { |
311 | t.equals(msg.funcArguments[0].toString(), 'hello world') |
312 | t.end() |
313 | }) |
314 | |
315 | const hypervisor = new Hypervisor(tree, [TestWasmContainer], [egress]) |
316 | |
317 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
318 | const funcRef = module.getFuncRef('main') |
319 | funcRef.gas = 322000 |
320 | |
321 | const message = new Message({ |
322 | funcRef |
323 | }) |
324 | |
325 | hypervisor.send(message) |
326 | |
327 | const funcRef2 = module.getFuncRef('load') |
328 | funcRef2.gas = 322000 |
329 | |
330 | await hypervisor.createStateRoot() |
331 | |
332 | const message2 = new Message({ |
333 | funcRef: funcRef2, |
334 | funcArguments: [new FunctionRef({actorID: egress.id, params: ['data']})] |
335 | }) |
336 | |
337 | hypervisor.send(message2) |
338 | }) |
339 | |
340 | tape('link', async t => { |
341 | tester = t |
342 | const tree = new RadixTree({db}) |
343 | let wasm = fs.readFileSync(WASM_PATH + '/link.wasm') |
344 | |
345 | const egress = new EgressDriver() |
346 | |
347 | egress.on('message', msg => { |
348 | t.equals(msg.funcArguments[0].toString(), 'hello world') |
349 | t.end() |
350 | }) |
351 | |
352 | const hypervisor = new Hypervisor(tree, [TestWasmContainer], [egress]) |
353 | |
354 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
355 | const funcRef = module.getFuncRef('main') |
356 | funcRef.gas = 322000 |
357 | |
358 | const message = new Message({ |
359 | funcRef |
360 | }) |
361 | |
362 | hypervisor.send(message) |
363 | |
364 | const funcRef2 = module.getFuncRef('load') |
365 | funcRef2.gas = 322000 |
366 | |
367 | await hypervisor.createStateRoot() |
368 | |
369 | const message2 = new Message({ |
370 | funcRef: funcRef2, |
371 | funcArguments: [new FunctionRef({actorID: egress.id, params: ['data']})] |
372 | }) |
373 | |
374 | hypervisor.send(message2) |
375 | }) |
376 | |
377 | tape('invalid binary', async t => { |
378 | t.plan(1) |
379 | tester = t |
380 | const tree = new RadixTree({db}) |
381 | const wasm = Buffer.from([0]) |
382 | |
383 | const hypervisor = new Hypervisor(tree) |
384 | hypervisor.registerContainer(TestWasmContainer) |
385 | |
386 | try { |
387 | await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
388 | } catch (e) { |
389 | t.pass() |
390 | } |
391 | }) |
392 | |
393 | tape('out of gas', async t => { |
394 | tester = t |
395 | const tree = new RadixTree({db}) |
396 | let wasm = fs.readFileSync(WASM_PATH + '/i64.wasm') |
397 | |
398 | const hypervisor = new Hypervisor(tree) |
399 | hypervisor.registerContainer(TestWasmContainer) |
400 | |
401 | const {module} = await hypervisor.createActor(TestWasmContainer.typeId, wasm) |
402 | const funcRef = module.getFuncRef('main') |
403 | |
404 | const message = new Message({ |
405 | funcRef |
406 | }).on('execution:error', e => { |
407 | t.end() |
408 | }) |
409 | hypervisor.send(message) |
410 | }) |
411 |
Built with git-ssb-web