Files: 4d0111a3323bd33403464ccb1760f2df9aaa623e / tests / index.js
34931 bytesRaw
1 | const tape = require('tape') |
2 | const IPFS = require('ipfs') |
3 | const AbstractContainer = require('primea-abstract-container') |
4 | const Message = require('primea-message') |
5 | const Hypervisor = require('../') |
6 | |
7 | // start ipfs |
8 | const node = new IPFS({ |
9 | start: false |
10 | }) |
11 | |
12 | class BaseContainer extends AbstractContainer { |
13 | onCreation (message) { |
14 | this.kernel.state.code = message.data.byteLength ? message.data : undefined |
15 | const port = message.ports[0] |
16 | if (port) { |
17 | this.kernel.ports.bind('root', port) |
18 | } |
19 | } |
20 | static get typeId () { |
21 | return 9 |
22 | } |
23 | } |
24 | |
25 | node.on('ready', () => { |
26 | tape('basic', async t => { |
27 | t.plan(3) |
28 | let message |
29 | const expectedState = { |
30 | '/': 'zdpuAsvLUNKxnxpKxuipCJz7sH4kmHuu3gVEUEmJ1QuWnikht' |
31 | } |
32 | |
33 | class testVMContainer extends BaseContainer { |
34 | onMessage (m) { |
35 | t.true(m === message, 'should recive a message') |
36 | } |
37 | } |
38 | |
39 | try { |
40 | const hypervisor = new Hypervisor(node.dag) |
41 | hypervisor.registerContainer(testVMContainer) |
42 | |
43 | const rootContainer = await hypervisor.createInstance(testVMContainer.typeId) |
44 | |
45 | const [portRef1, portRef2] = rootContainer.ports.createChannel() |
46 | const initMessage = rootContainer.createMessage({ |
47 | data: Buffer.from('test code'), |
48 | ports: [portRef2] |
49 | }) |
50 | |
51 | rootContainer.createInstance(testVMContainer.typeId, initMessage) |
52 | |
53 | rootContainer.ports.bind('first', portRef1) |
54 | message = rootContainer.createMessage() |
55 | rootContainer.send(portRef1, message) |
56 | |
57 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
58 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
59 | t.equals(hypervisor.scheduler.oldest(), 0) |
60 | await hypervisor.graph.tree(stateRoot, Infinity, true) |
61 | console.log(JSON.stringify(stateRoot, null, 2)) |
62 | } catch (e) { |
63 | console.log(e) |
64 | } |
65 | }) |
66 | |
67 | tape('basic - do not store containers with no ports bound', async t => { |
68 | t.plan(1) |
69 | const expectedState = { |
70 | '/': 'zdpuAop4nt8pqzg7duciSYbZmWfDaBiz87RCtGCbb35ewUrbW' |
71 | } |
72 | |
73 | class testVMContainer extends BaseContainer { |
74 | onCreation () {} |
75 | } |
76 | |
77 | try { |
78 | const hypervisor = new Hypervisor(node.dag) |
79 | hypervisor.registerContainer(testVMContainer) |
80 | |
81 | const root = await hypervisor.createInstance(testVMContainer.typeId) |
82 | const [portRef1, portRef2] = root.ports.createChannel() |
83 | |
84 | root.ports.bind('one', portRef1) |
85 | root.createInstance(testVMContainer.typeId, root.createMessage({ |
86 | ports: [portRef2] |
87 | })) |
88 | |
89 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
90 | |
91 | // await hypervisor.graph.tree(stateRoot, Infinity, true) |
92 | // console.log(JSON.stringify(stateRoot, null, 2)) |
93 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
94 | } catch (e) { |
95 | console.log(e) |
96 | } |
97 | }) |
98 | |
99 | tape('one child contract with saturated ports', async t => { |
100 | t.plan(2) |
101 | let message |
102 | const expectedState = { |
103 | '/': 'zdpuAnfZ1fGUSzNwAovfArzcTfEVbXjVYABprgtjUKMtGb8k5' |
104 | } |
105 | |
106 | class testVMContainer2 extends BaseContainer { |
107 | onMessage (m) { |
108 | t.true(m === message, 'should recive a message') |
109 | } |
110 | static get typeId () { |
111 | return 99 |
112 | } |
113 | } |
114 | |
115 | class testVMContainer extends BaseContainer { |
116 | onMessage (m) { |
117 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
118 | this.kernel.createInstance(testVMContainer2.typeId, this.kernel.createMessage({ |
119 | ports: [portRef2] |
120 | })) |
121 | this.kernel.ports.bind('child', portRef1) |
122 | this.kernel.incrementTicks(2) |
123 | this.kernel.send(portRef1, m) |
124 | } |
125 | } |
126 | |
127 | const hypervisor = new Hypervisor(node.dag) |
128 | hypervisor.registerContainer(testVMContainer) |
129 | hypervisor.registerContainer(testVMContainer2) |
130 | |
131 | const root = await hypervisor.createInstance(testVMContainer.typeId) |
132 | const [portRef1, portRef2] = root.ports.createChannel() |
133 | root.createInstance(testVMContainer.typeId, root.createMessage({ |
134 | ports: [portRef2] |
135 | })) |
136 | |
137 | root.ports.bind('first', portRef1) |
138 | message = root.createMessage({ |
139 | data: 'test' |
140 | }) |
141 | |
142 | root.send(portRef1, message) |
143 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
144 | |
145 | // await hypervisor.graph.tree(stateRoot, Infinity, true) |
146 | // console.log(JSON.stringify(stateRoot, null, 2)) |
147 | t.deepEquals(stateRoot, expectedState, 'expected state') |
148 | }) |
149 | |
150 | tape('one child contract', async t => { |
151 | t.plan(4) |
152 | let message |
153 | const expectedState = { |
154 | '/': 'zdpuArCqpDZtEqjrXrRhMiYLE7QQ1szVr1qLVkiwtDLincGWU' |
155 | } |
156 | let hasResolved = false |
157 | |
158 | class testVMContainer2 extends BaseContainer { |
159 | onMessage (m) { |
160 | t.true(m === message, 'should recive a message') |
161 | return new Promise((resolve, reject) => { |
162 | setTimeout(() => { |
163 | this.kernel.incrementTicks(1) |
164 | hasResolved = true |
165 | resolve() |
166 | }, 200) |
167 | }) |
168 | } |
169 | |
170 | static get typeId () { |
171 | return 99 |
172 | } |
173 | } |
174 | |
175 | class testVMContainer extends BaseContainer { |
176 | onMessage (m) { |
177 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
178 | this.kernel.createInstance(testVMContainer2.typeId, this.kernel.createMessage({ |
179 | ports: [portRef2] |
180 | })) |
181 | this.kernel.ports.bind('child', portRef1) |
182 | this.kernel.send(portRef1, m) |
183 | this.kernel.incrementTicks(1) |
184 | } |
185 | } |
186 | |
187 | const hypervisor = new Hypervisor(node.dag) |
188 | hypervisor.registerContainer(testVMContainer) |
189 | hypervisor.registerContainer(testVMContainer2) |
190 | |
191 | let root = await hypervisor.createInstance(testVMContainer.typeId) |
192 | const rootId = root.id |
193 | const [portRef1, portRef2] = root.ports.createChannel() |
194 | root.createInstance(testVMContainer.typeId, root.createMessage({ |
195 | ports: [portRef2] |
196 | })) |
197 | |
198 | root.ports.bind('first', portRef1) |
199 | message = root.createMessage() |
200 | |
201 | root.send(portRef1, message) |
202 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
203 | t.true(hasResolved, 'should resolve before generating the state root') |
204 | |
205 | // await hypervisor.graph.tree(stateRoot, Infinity, true) |
206 | // console.log(JSON.stringify(stateRoot, null, 2)) |
207 | t.deepEquals(stateRoot, expectedState, 'expected state') |
208 | |
209 | // test reviving the state |
210 | class testVMContainer3 extends BaseContainer { |
211 | onMessage (m) { |
212 | const port = this.kernel.ports.get('child') |
213 | this.kernel.send(port, m) |
214 | this.kernel.incrementTicks(1) |
215 | } |
216 | } |
217 | |
218 | hypervisor.registerContainer(testVMContainer3) |
219 | root = await hypervisor.getInstance(rootId) |
220 | const port = root.ports.get('first') |
221 | root.send(port, message) |
222 | }) |
223 | |
224 | tape('traps', async t => { |
225 | t.plan(1) |
226 | class Root extends BaseContainer { |
227 | async onMessage (m) { |
228 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
229 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
230 | const [portRef5, portRef6] = this.kernel.ports.createChannel() |
231 | |
232 | this.kernel.ports.bind('one', portRef1) |
233 | this.kernel.ports.bind('two', portRef3) |
234 | this.kernel.ports.bind('three', portRef5) |
235 | |
236 | const message1 = this.kernel.createMessage({ |
237 | ports: [portRef2] |
238 | }) |
239 | const message2 = this.kernel.createMessage({ |
240 | ports: [portRef4] |
241 | }) |
242 | const message3 = this.kernel.createMessage({ |
243 | ports: [portRef6] |
244 | }) |
245 | |
246 | this.kernel.createInstance(Root.typeId, message1) |
247 | this.kernel.createInstance(Root.typeId, message2) |
248 | this.kernel.createInstance(Root.typeId, message3) |
249 | |
250 | throw new Error('it is a trap!!!') |
251 | } |
252 | } |
253 | |
254 | const hypervisor = new Hypervisor(node.dag) |
255 | |
256 | hypervisor.registerContainer(Root) |
257 | const root = await hypervisor.createInstance(Root.typeId) |
258 | await root.message(root.createMessage()) |
259 | const stateRoot = await hypervisor.createStateRoot() |
260 | |
261 | t.deepEquals(stateRoot, { |
262 | '/': 'zdpuAtChoDT1Er7c9Ndv6ov4m46wibCNY1HKthoVLUn5n4Rg5' |
263 | }, 'should revert the state') |
264 | }) |
265 | |
266 | tape('message should arrive in the correct oder if sent in order', async t => { |
267 | t.plan(2) |
268 | let runs = 0 |
269 | |
270 | class Root extends BaseContainer { |
271 | onMessage (m) { |
272 | if (!runs) { |
273 | runs++ |
274 | |
275 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
276 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
277 | |
278 | this.kernel.ports.bind('two', portRef3) |
279 | this.kernel.ports.bind('one', portRef1) |
280 | |
281 | const message1 = this.kernel.createMessage({ |
282 | ports: [portRef2] |
283 | }) |
284 | const message2 = this.kernel.createMessage({ |
285 | ports: [portRef4] |
286 | }) |
287 | |
288 | this.kernel.createInstance(First.typeId, message1) |
289 | this.kernel.createInstance(Second.typeId, message2) |
290 | |
291 | this.kernel.send(portRef1, this.kernel.createMessage()) |
292 | this.kernel.send(portRef3, this.kernel.createMessage()) |
293 | } else if (runs === 1) { |
294 | runs++ |
295 | t.equals(m.data, 'first', 'should recive the first message') |
296 | } else if (runs === 2) { |
297 | t.equals(m.data, 'second', 'should recived the second message') |
298 | } |
299 | } |
300 | } |
301 | |
302 | class First extends BaseContainer { |
303 | onMessage (m) { |
304 | this.kernel.incrementTicks(2) |
305 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
306 | data: 'first' |
307 | })) |
308 | } |
309 | |
310 | static get typeId () { |
311 | return 99 |
312 | } |
313 | } |
314 | |
315 | class Second extends BaseContainer { |
316 | onMessage (m) { |
317 | this.kernel.incrementTicks(3) |
318 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
319 | data: 'second' |
320 | })) |
321 | } |
322 | |
323 | static get typeId () { |
324 | return 299 |
325 | } |
326 | } |
327 | |
328 | const hypervisor = new Hypervisor(node.dag) |
329 | |
330 | hypervisor.registerContainer(Root) |
331 | hypervisor.registerContainer(First) |
332 | hypervisor.registerContainer(Second) |
333 | |
334 | const root = await hypervisor.createInstance(Root.typeId) |
335 | |
336 | const [portRef1, portRef2] = root.ports.createChannel() |
337 | root.createInstance(Root.typeId, root.createMessage({ |
338 | ports: [portRef2] |
339 | })) |
340 | |
341 | root.ports.bind('first', portRef1) |
342 | const message = root.createMessage() |
343 | root.send(portRef1, message) |
344 | }) |
345 | |
346 | tape('message should arrive in the correct oder if sent in order', async t => { |
347 | t.plan(2) |
348 | let runs = 0 |
349 | |
350 | class Root extends BaseContainer { |
351 | onMessage (m) { |
352 | if (!runs) { |
353 | runs++ |
354 | |
355 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
356 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
357 | |
358 | this.kernel.ports.bind('one', portRef1) |
359 | this.kernel.ports.bind('two', portRef3) |
360 | |
361 | const message1 = this.kernel.createMessage({ |
362 | ports: [portRef2] |
363 | }) |
364 | const message2 = this.kernel.createMessage({ |
365 | ports: [portRef4] |
366 | }) |
367 | |
368 | this.kernel.createInstance(First.typeId, message1) |
369 | this.kernel.createInstance(Second.typeId, message2) |
370 | |
371 | this.kernel.send(portRef1, this.kernel.createMessage()) |
372 | this.kernel.send(portRef3, this.kernel.createMessage()) |
373 | } else if (runs === 1) { |
374 | runs++ |
375 | t.equals(m.data, 'second', 'should recived the second message') |
376 | } else if (runs === 2) { |
377 | t.equals(m.data, 'first', 'should recive the first message') |
378 | } |
379 | } |
380 | |
381 | static get typeId () { |
382 | return 99 |
383 | } |
384 | } |
385 | |
386 | class First extends BaseContainer { |
387 | onMessage (m) { |
388 | this.kernel.incrementTicks(2) |
389 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
390 | data: 'first' |
391 | })) |
392 | } |
393 | |
394 | static get typeId () { |
395 | return 299 |
396 | } |
397 | } |
398 | |
399 | class Second extends BaseContainer { |
400 | onMessage (m) { |
401 | this.kernel.incrementTicks(1) |
402 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
403 | data: 'second' |
404 | })) |
405 | } |
406 | } |
407 | |
408 | const hypervisor = new Hypervisor(node.dag) |
409 | |
410 | hypervisor.registerContainer(Root) |
411 | hypervisor.registerContainer(First) |
412 | hypervisor.registerContainer(Second) |
413 | |
414 | const root = await hypervisor.createInstance(Root.typeId) |
415 | |
416 | const [portRef1, portRef2] = root.ports.createChannel() |
417 | root.createInstance(Root.typeId, root.createMessage({ |
418 | ports: [portRef2] |
419 | })) |
420 | |
421 | root.ports.bind('first', portRef1) |
422 | const message = root.createMessage() |
423 | root.send(portRef1, message) |
424 | }) |
425 | |
426 | tape('message should arrive in the correct oder if sent in order', async t => { |
427 | t.plan(2) |
428 | let runs = 0 |
429 | |
430 | class Root extends BaseContainer { |
431 | onMessage (m) { |
432 | if (!runs) { |
433 | runs++ |
434 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
435 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
436 | |
437 | this.kernel.ports.bind('one', portRef1) |
438 | this.kernel.ports.bind('two', portRef3) |
439 | |
440 | const message1 = this.kernel.createMessage({ |
441 | ports: [portRef2] |
442 | }) |
443 | const message2 = this.kernel.createMessage({ |
444 | ports: [portRef4] |
445 | }) |
446 | |
447 | this.kernel.createInstance(First.typeId, message1) |
448 | this.kernel.createInstance(Second.typeId, message2) |
449 | |
450 | this.kernel.send(portRef1, this.kernel.createMessage()) |
451 | this.kernel.send(portRef3, this.kernel.createMessage()) |
452 | |
453 | this.kernel.incrementTicks(6) |
454 | } else if (runs === 1) { |
455 | runs++ |
456 | t.equals(m.data, 'first', 'should recive the first message') |
457 | } else if (runs === 2) { |
458 | t.equals(m.data, 'second', 'should recived the second message') |
459 | } |
460 | } |
461 | static get typeId () { |
462 | return 299 |
463 | } |
464 | } |
465 | |
466 | class First extends BaseContainer { |
467 | onMessage (m) { |
468 | this.kernel.incrementTicks(1) |
469 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
470 | data: 'first' |
471 | })) |
472 | } |
473 | static get typeId () { |
474 | return 2 |
475 | } |
476 | } |
477 | |
478 | class Second extends BaseContainer { |
479 | onMessage (m) { |
480 | this.kernel.incrementTicks(2) |
481 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
482 | data: 'second' |
483 | })) |
484 | } |
485 | } |
486 | |
487 | const hypervisor = new Hypervisor(node.dag) |
488 | |
489 | hypervisor.registerContainer(Root) |
490 | hypervisor.registerContainer(First) |
491 | hypervisor.registerContainer(Second) |
492 | |
493 | const root = await hypervisor.createInstance(Root.typeId) |
494 | const [portRef1, portRef2] = root.ports.createChannel() |
495 | root.createInstance(Root.typeId, root.createMessage({ |
496 | ports: [portRef2] |
497 | })) |
498 | |
499 | root.ports.bind('first', portRef1) |
500 | const message = root.createMessage() |
501 | root.send(portRef1, message) |
502 | }) |
503 | |
504 | tape('saturation', async t => { |
505 | t.plan(2) |
506 | let runs = 0 |
507 | |
508 | class Root extends BaseContainer { |
509 | onMessage (m) { |
510 | if (!runs) { |
511 | runs++ |
512 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
513 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
514 | |
515 | this.kernel.ports.bind('one', portRef1) |
516 | this.kernel.ports.bind('two', portRef3) |
517 | |
518 | const message1 = this.kernel.createMessage({ |
519 | ports: [portRef2] |
520 | }) |
521 | const message2 = this.kernel.createMessage({ |
522 | ports: [portRef4] |
523 | }) |
524 | |
525 | this.kernel.createInstance(First.typeId, message1) |
526 | this.kernel.createInstance(Second.typeId, message2) |
527 | |
528 | this.kernel.send(portRef1, this.kernel.createMessage()) |
529 | this.kernel.send(portRef3, this.kernel.createMessage()) |
530 | |
531 | this.kernel.incrementTicks(6) |
532 | } else if (runs === 1) { |
533 | runs++ |
534 | t.equals(m.data, 'first', 'should recive the first message') |
535 | } else if (runs === 2) { |
536 | runs++ |
537 | t.equals(m.data, 'second', 'should recived the second message') |
538 | } |
539 | } |
540 | static get typeId () { |
541 | return 299 |
542 | } |
543 | } |
544 | |
545 | class First extends BaseContainer { |
546 | onMessage (m) { |
547 | this.kernel.incrementTicks(2) |
548 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
549 | data: 'first' |
550 | })) |
551 | } |
552 | static get typeId () { |
553 | return 29 |
554 | } |
555 | } |
556 | |
557 | class Second extends BaseContainer { |
558 | onMessage (m) { |
559 | this.kernel.incrementTicks(3) |
560 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
561 | data: 'second' |
562 | })) |
563 | } |
564 | static get typeId () { |
565 | return 2 |
566 | } |
567 | } |
568 | |
569 | class Waiter extends BaseContainer { |
570 | onCreation () { |
571 | return new Promise((resolve, reject) => { |
572 | setTimeout(() => { |
573 | resolve() |
574 | }, 200) |
575 | }) |
576 | } |
577 | } |
578 | |
579 | const hypervisor = new Hypervisor(node.dag) |
580 | |
581 | hypervisor.registerContainer(Root) |
582 | hypervisor.registerContainer(First) |
583 | hypervisor.registerContainer(Second) |
584 | hypervisor.registerContainer(Waiter) |
585 | |
586 | const root = await hypervisor.createInstance(Root.typeId) |
587 | const [portRef1, portRef2] = root.ports.createChannel() |
588 | |
589 | const message = root.createMessage() |
590 | root.send(portRef1, message) |
591 | root.ports.bind('first', portRef1) |
592 | root.createInstance(Root.typeId, root.createMessage({ |
593 | ports: [portRef2] |
594 | })) |
595 | |
596 | const [portRef3, portRef4] = root.ports.createChannel() |
597 | root.ports.bind('sencond', portRef3) |
598 | root.createInstance(Waiter.typeId, root.createMessage({ |
599 | ports: [portRef4] |
600 | })) |
601 | |
602 | root.incrementTicks(100) |
603 | root.send(portRef1, root.createMessage({data: 'testss'})) |
604 | hypervisor.scheduler.done(root.id) |
605 | }) |
606 | |
607 | tape('message should arrive in the correct order, even in a tie of ticks', async t => { |
608 | t.plan(2) |
609 | |
610 | let runs = 0 |
611 | |
612 | class Root extends BaseContainer { |
613 | onMessage (m) { |
614 | if (!runs) { |
615 | runs++ |
616 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
617 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
618 | |
619 | this.kernel.ports.bind('two', portRef3) |
620 | this.kernel.ports.bind('one', portRef1) |
621 | |
622 | const message1 = this.kernel.createMessage({ |
623 | ports: [portRef2] |
624 | }) |
625 | const message2 = this.kernel.createMessage({ |
626 | ports: [portRef4] |
627 | }) |
628 | |
629 | this.kernel.createInstance(First.typeId, message1) |
630 | this.kernel.createInstance(Second.typeId, message2) |
631 | |
632 | this.kernel.send(portRef1, this.kernel.createMessage()) |
633 | this.kernel.send(portRef3, this.kernel.createMessage()) |
634 | |
635 | this.kernel.incrementTicks(6) |
636 | } else if (runs === 1) { |
637 | runs++ |
638 | t.equals(m.data, 'second', 'should recived the second message') |
639 | } else if (runs === 2) { |
640 | t.equals(m.data, 'first', 'should recive the first message') |
641 | } |
642 | } |
643 | static get typeId () { |
644 | return 299 |
645 | } |
646 | } |
647 | |
648 | class First extends BaseContainer { |
649 | onMessage (m) { |
650 | this.kernel.incrementTicks(2) |
651 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
652 | data: 'first' |
653 | })) |
654 | } |
655 | static get typeId () { |
656 | return 29 |
657 | } |
658 | } |
659 | |
660 | class Second extends BaseContainer { |
661 | onMessage (m) { |
662 | this.kernel.incrementTicks(2) |
663 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
664 | data: 'second' |
665 | })) |
666 | } |
667 | static get typeId () { |
668 | return 2 |
669 | } |
670 | } |
671 | |
672 | const hypervisor = new Hypervisor(node.dag) |
673 | |
674 | hypervisor.registerContainer(Root) |
675 | hypervisor.registerContainer(First) |
676 | hypervisor.registerContainer(Second) |
677 | |
678 | const root = await hypervisor.createInstance(Root.typeId) |
679 | const [portRef1, portRef2] = root.ports.createChannel() |
680 | const message = root.createMessage() |
681 | |
682 | root.send(portRef1, message) |
683 | root.ports.bind('first', portRef1) |
684 | root.createInstance(Root.typeId, root.createMessage({ |
685 | ports: [portRef2] |
686 | })) |
687 | }) |
688 | |
689 | tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => { |
690 | t.plan(2) |
691 | |
692 | let runs = 0 |
693 | |
694 | class Root extends BaseContainer { |
695 | onMessage (m) { |
696 | if (!runs) { |
697 | runs++ |
698 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
699 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
700 | |
701 | this.kernel.ports.bind('one', portRef1) |
702 | this.kernel.ports.bind('two', portRef3) |
703 | |
704 | const message1 = this.kernel.createMessage({ |
705 | ports: [portRef2] |
706 | }) |
707 | const message2 = this.kernel.createMessage({ |
708 | ports: [portRef4] |
709 | }) |
710 | |
711 | this.kernel.createInstance(First.typeId, message1) |
712 | this.kernel.createInstance(Second.typeId, message2) |
713 | |
714 | this.kernel.send(portRef1, this.kernel.createMessage()) |
715 | this.kernel.send(portRef3, this.kernel.createMessage()) |
716 | |
717 | this.kernel.incrementTicks(6) |
718 | } else if (runs === 1) { |
719 | runs++ |
720 | t.equals(m.data, 'first', 'should recive the first message') |
721 | } else if (runs === 2) { |
722 | t.equals(m.data, 'second', 'should recived the second message') |
723 | } |
724 | } |
725 | static get typeId () { |
726 | return 299 |
727 | } |
728 | } |
729 | |
730 | class First extends BaseContainer { |
731 | onMessage (m) { |
732 | this.kernel.incrementTicks(2) |
733 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
734 | data: 'first' |
735 | })) |
736 | } |
737 | static get typeId () { |
738 | return 29 |
739 | } |
740 | } |
741 | |
742 | class Second extends BaseContainer { |
743 | onMessage (m) { |
744 | this.kernel.incrementTicks(2) |
745 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
746 | data: 'second' |
747 | })) |
748 | } |
749 | } |
750 | |
751 | const hypervisor = new Hypervisor(node.dag) |
752 | |
753 | hypervisor.registerContainer(Root) |
754 | hypervisor.registerContainer(First) |
755 | hypervisor.registerContainer(Second) |
756 | |
757 | const root = await hypervisor.createInstance(Root.typeId) |
758 | const [portRef1, portRef2] = root.ports.createChannel() |
759 | const message = root.createMessage() |
760 | |
761 | root.send(portRef1, message) |
762 | root.ports.bind('first', portRef1) |
763 | root.createInstance(Root.typeId, root.createMessage({ |
764 | ports: [portRef2] |
765 | })) |
766 | }) |
767 | |
768 | tape('send to the same container at the same time', async t => { |
769 | t.plan(2) |
770 | |
771 | let runs = 0 |
772 | let instance |
773 | |
774 | class Root extends BaseContainer { |
775 | onMessage (m) { |
776 | let one = this.kernel.ports.get('one') |
777 | if (!one) { |
778 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
779 | this.kernel.ports.bind('one', portRef1) |
780 | const message1 = this.kernel.createMessage({ |
781 | ports: [portRef2] |
782 | }) |
783 | this.kernel.createInstance(First.typeId, message1) |
784 | } else { |
785 | this.kernel.send(one, this.kernel.createMessage()) |
786 | this.kernel.send(one, this.kernel.createMessage()) |
787 | } |
788 | } |
789 | static get typeId () { |
790 | return 299 |
791 | } |
792 | } |
793 | |
794 | class First extends BaseContainer { |
795 | onMessage (m) { |
796 | ++runs |
797 | if (runs === 2) { |
798 | t.equals(instance, this, 'should have same instances') |
799 | } else { |
800 | instance = this |
801 | } |
802 | } |
803 | } |
804 | |
805 | const hypervisor = new Hypervisor(node.dag) |
806 | |
807 | hypervisor.registerContainer(Root) |
808 | hypervisor.registerContainer(First) |
809 | |
810 | const root = await hypervisor.createInstance(Root.typeId) |
811 | const [portRef1, portRef2] = root.ports.createChannel() |
812 | root.ports.bind('first', portRef1) |
813 | root.createInstance(Root.typeId, root.createMessage({ |
814 | ports: [portRef2] |
815 | })) |
816 | |
817 | const message = root.createMessage() |
818 | root.send(portRef1, message) |
819 | await hypervisor.createStateRoot() |
820 | root.send(portRef1, root.createMessage()) |
821 | await hypervisor.createStateRoot() |
822 | t.equals(runs, 2) |
823 | }) |
824 | |
825 | tape('checking ports', async t => { |
826 | t.plan(4) |
827 | const hypervisor = new Hypervisor(node.dag) |
828 | hypervisor.registerContainer(BaseContainer) |
829 | |
830 | const root = await hypervisor.createInstance(BaseContainer.typeId) |
831 | |
832 | const [portRef1, portRef2] = root.ports.createChannel() |
833 | root.createInstance(BaseContainer.typeId, root.createMessage({ |
834 | ports: [portRef2] |
835 | })) |
836 | root.ports.bind('test', portRef1) |
837 | |
838 | try { |
839 | root.createMessage({ |
840 | ports: [portRef1] |
841 | }) |
842 | } catch (e) { |
843 | t.pass('should thow if sending a port that is bound') |
844 | } |
845 | |
846 | try { |
847 | await root.ports.bind('test', portRef1) |
848 | } catch (e) { |
849 | t.pass('should thow if binding an already bound port') |
850 | } |
851 | |
852 | try { |
853 | const [portRef3] = root.ports.createChannel() |
854 | await root.ports.bind('test', portRef3) |
855 | } catch (e) { |
856 | t.pass('should thow if binding an already bound name') |
857 | } |
858 | |
859 | await root.ports.unbind('test') |
860 | const message = root.createMessage({ |
861 | ports: [portRef1] |
862 | }) |
863 | t.equals(message.ports[0], portRef1, 'should create a message if the port is unbound') |
864 | }) |
865 | |
866 | tape('port deletion', async t => { |
867 | const expectedSr = { |
868 | '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md' |
869 | } |
870 | class Root extends BaseContainer { |
871 | onMessage (m) { |
872 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
873 | this.kernel.ports.bind('one', portRef1) |
874 | const message1 = this.kernel.createMessage({ |
875 | ports: [portRef2] |
876 | }) |
877 | |
878 | this.kernel.createInstance(First.typeId, message1) |
879 | this.kernel.send(portRef1, this.kernel.createMessage()) |
880 | this.kernel.incrementTicks(6) |
881 | } |
882 | } |
883 | |
884 | class First extends BaseContainer { |
885 | onMessage (m) { |
886 | this.kernel.incrementTicks(2) |
887 | this.kernel.ports.delete('root') |
888 | } |
889 | static get typeId () { |
890 | return 299 |
891 | } |
892 | } |
893 | |
894 | const hypervisor = new Hypervisor(node.dag) |
895 | |
896 | hypervisor.registerContainer(Root) |
897 | hypervisor.registerContainer(First) |
898 | |
899 | const root = await hypervisor.createInstance(Root.typeId) |
900 | const [portRef1, portRef2] = root.ports.createChannel() |
901 | root.ports.bind('first', portRef1) |
902 | root.createInstance(Root.typeId, root.createMessage({ |
903 | ports: [portRef2] |
904 | })) |
905 | |
906 | const message = root.createMessage() |
907 | root.send(portRef1, message) |
908 | |
909 | const sr = await hypervisor.createStateRoot() |
910 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
911 | await hypervisor.graph.tree(sr, Infinity, true) |
912 | |
913 | t.end() |
914 | }) |
915 | |
916 | tape('clear unbounded ports', async t => { |
917 | const expectedSr = { |
918 | '/': 'zdpuAxVzUQRWaAeFWXq5TgDpZqPaNgNp1ZuEfxbxg7h4qnXmC' |
919 | } |
920 | class Root extends BaseContainer { |
921 | onMessage (m) { |
922 | this.kernel.createInstance(Root.typeId) |
923 | } |
924 | } |
925 | |
926 | const hypervisor = new Hypervisor(node.dag) |
927 | |
928 | hypervisor.registerContainer(Root) |
929 | |
930 | const root = await hypervisor.createInstance(Root.typeId) |
931 | const [portRef1, portRef2] = root.ports.createChannel() |
932 | root.ports.bind('first', portRef1) |
933 | root.createInstance(Root.typeId, root.createMessage({ |
934 | ports: [portRef2] |
935 | })) |
936 | |
937 | const message = root.createMessage() |
938 | root.send(portRef1, message) |
939 | const sr = await hypervisor.createStateRoot() |
940 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
941 | |
942 | t.end() |
943 | }) |
944 | |
945 | tape('should remove subgraphs', async t => { |
946 | const expectedSr = { |
947 | '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md' |
948 | } |
949 | class Root extends BaseContainer { |
950 | onMessage (m) { |
951 | const [, portRef2] = this.kernel.ports.createChannel() |
952 | this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({ |
953 | ports: [portRef2] |
954 | })) |
955 | } |
956 | } |
957 | |
958 | class Sub extends BaseContainer { |
959 | onInitailize (message) { |
960 | this.kernel.ports.bind('root', message.ports[0]) |
961 | const [portRef1, portRef2] = root.ports.createChannel() |
962 | root.ports.bind('child', portRef1) |
963 | root.createInstance(Root.typeId, root.createMessage({ |
964 | ports: [portRef2] |
965 | })) |
966 | } |
967 | static get typeId () { |
968 | return 299 |
969 | } |
970 | } |
971 | |
972 | const hypervisor = new Hypervisor(node.dag) |
973 | |
974 | hypervisor.registerContainer(Root) |
975 | hypervisor.registerContainer(Sub) |
976 | |
977 | const root = await hypervisor.createInstance(Root.typeId) |
978 | const [portRef1, portRef2] = root.ports.createChannel() |
979 | root.ports.bind('first', portRef1) |
980 | root.createInstance(Root.typeId, root.createMessage({ |
981 | ports: [portRef2] |
982 | })) |
983 | |
984 | root.send(portRef1, root.createMessage()) |
985 | const sr = await hypervisor.createStateRoot() |
986 | |
987 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
988 | t.end() |
989 | }) |
990 | |
991 | tape('should not remove connected nodes', async t => { |
992 | const expectedSr = { |
993 | '/': 'zdpuApKrsvsWknDML2Mme9FyZfRnVZ1hTCoKzkooYAWT3dUDV' |
994 | } |
995 | class Root extends BaseContainer { |
996 | onMessage (m) { |
997 | if (m.ports.length) { |
998 | const port = this.kernel.ports.get('test1') |
999 | this.kernel.send(port, m) |
1000 | this.kernel.ports.unbind('test1') |
1001 | } else { |
1002 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
1003 | this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({ |
1004 | ports: [portRef2] |
1005 | })) |
1006 | this.kernel.ports.bind('test1', portRef1) |
1007 | |
1008 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
1009 | this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({ |
1010 | ports: [portRef4] |
1011 | })) |
1012 | this.kernel.ports.bind('test2', portRef3) |
1013 | this.kernel.send(portRef3, this.kernel.createMessage({ |
1014 | data: 'getChannel' |
1015 | })) |
1016 | } |
1017 | } |
1018 | } |
1019 | |
1020 | class Sub extends BaseContainer { |
1021 | onMessage (message) { |
1022 | if (message.data === 'getChannel') { |
1023 | const ports = this.kernel.ports.createChannel() |
1024 | this.kernel.ports.bind('channel', ports[0]) |
1025 | this.kernel.send(message.fromPort, this.kernel.createMessage({ |
1026 | data: 'bindPort', |
1027 | ports: [ports[1]] |
1028 | })) |
1029 | } else if (message.data === 'bindPort') { |
1030 | this.kernel.ports.bind('channel', message.ports[0]) |
1031 | } |
1032 | } |
1033 | static get typeId () { |
1034 | return 299 |
1035 | } |
1036 | } |
1037 | |
1038 | const hypervisor = new Hypervisor(node.dag) |
1039 | |
1040 | hypervisor.registerContainer(Root) |
1041 | hypervisor.registerContainer(Sub) |
1042 | |
1043 | const root = await hypervisor.createInstance(Root.typeId) |
1044 | const [portRef1, portRef2] = root.ports.createChannel() |
1045 | root.ports.bind('first', portRef1) |
1046 | root.createInstance(Root.typeId, root.createMessage({ |
1047 | ports: [portRef2] |
1048 | })) |
1049 | |
1050 | root.send(portRef1, root.createMessage()) |
1051 | const sr = await hypervisor.createStateRoot() |
1052 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
1053 | // await hypervisor.graph.tree(sr, Infinity) |
1054 | |
1055 | t.end() |
1056 | }) |
1057 | |
1058 | tape('should remove multiple subgraphs', async t => { |
1059 | const expectedSr = { |
1060 | '/': 'zdpuAo1qZHhS6obxbGbtvnUxkbAxA6VSbcjYiiTVNWTm37xQv' |
1061 | } |
1062 | class Root extends BaseContainer { |
1063 | onMessage (m) { |
1064 | if (m.ports.length) { |
1065 | const port = this.kernel.ports.get('test1') |
1066 | this.kernel.send(port, m) |
1067 | this.kernel.ports.unbind('test1') |
1068 | this.kernel.ports.unbind('test2') |
1069 | } else { |
1070 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
1071 | this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({ |
1072 | ports: [portRef2] |
1073 | })) |
1074 | this.kernel.ports.bind('test1', portRef1) |
1075 | |
1076 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
1077 | this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({ |
1078 | ports: [portRef4] |
1079 | })) |
1080 | this.kernel.ports.bind('test2', portRef3) |
1081 | this.kernel.send(portRef3, this.kernel.createMessage({ |
1082 | data: 'getChannel' |
1083 | })) |
1084 | } |
1085 | } |
1086 | } |
1087 | |
1088 | class Sub extends BaseContainer { |
1089 | onMessage (message) { |
1090 | if (message.data === 'getChannel') { |
1091 | const ports = this.kernel.ports.createChannel() |
1092 | this.kernel.ports.bind('channel', ports[0]) |
1093 | this.kernel.send(message.fromPort, this.kernel.createMessage({ |
1094 | data: 'bindPort', |
1095 | ports: [ports[1]] |
1096 | })) |
1097 | } else if (message.data === 'bindPort') { |
1098 | this.kernel.ports.bind('channel', message.ports[0]) |
1099 | } |
1100 | } |
1101 | static get typeId () { |
1102 | return 299 |
1103 | } |
1104 | } |
1105 | |
1106 | const hypervisor = new Hypervisor(node.dag) |
1107 | |
1108 | hypervisor.registerContainer(Root) |
1109 | hypervisor.registerContainer(Sub) |
1110 | |
1111 | const root = await hypervisor.createInstance(Root.typeId) |
1112 | |
1113 | const [portRef1, portRef2] = root.ports.createChannel() |
1114 | root.ports.bind('first', portRef1) |
1115 | root.createInstance(Root.typeId, root.createMessage({ |
1116 | ports: [portRef2] |
1117 | })) |
1118 | |
1119 | root.send(portRef1, root.createMessage()) |
1120 | |
1121 | const sr = await hypervisor.createStateRoot() |
1122 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
1123 | |
1124 | t.end() |
1125 | }) |
1126 | |
1127 | tape('response ports', async t => { |
1128 | t.plan(2) |
1129 | let runs = 0 |
1130 | const returnValue = 'this is a test' |
1131 | |
1132 | class testVMContainer extends BaseContainer { |
1133 | onMessage (m) { |
1134 | runs++ |
1135 | if (runs === 1) { |
1136 | return returnValue |
1137 | } else { |
1138 | t.equals(m.data, returnValue, 'should have correct return value') |
1139 | } |
1140 | } |
1141 | } |
1142 | |
1143 | const hypervisor = new Hypervisor(node.dag) |
1144 | |
1145 | hypervisor.registerContainer(testVMContainer) |
1146 | |
1147 | const rootContainer = await hypervisor.createInstance(testVMContainer.typeId) |
1148 | |
1149 | const [portRef1, portRef2] = rootContainer.ports.createChannel() |
1150 | const initMessage = rootContainer.createMessage({ |
1151 | ports: [portRef2] |
1152 | }) |
1153 | |
1154 | rootContainer.createInstance(testVMContainer.typeId, initMessage) |
1155 | |
1156 | rootContainer.ports.bind('first', portRef1) |
1157 | const message = rootContainer.createMessage() |
1158 | const rPort = rootContainer.getResponsePort(message) |
1159 | const rPort2 = rootContainer.getResponsePort(message) |
1160 | |
1161 | t.equals(rPort2, rPort) |
1162 | |
1163 | rootContainer.send(portRef1, message) |
1164 | rootContainer.ports.bind('response', rPort) |
1165 | }) |
1166 | |
1167 | tape('start up', async t => { |
1168 | t.plan(1) |
1169 | class testVMContainer extends BaseContainer { |
1170 | onMessage () {} |
1171 | onStartup () { |
1172 | t.true(true, 'should start up') |
1173 | } |
1174 | } |
1175 | |
1176 | const hypervisor = new Hypervisor(node.dag) |
1177 | hypervisor.registerContainer(testVMContainer) |
1178 | await hypervisor.createInstance(testVMContainer.typeId) |
1179 | hypervisor.getInstance(hypervisor.ROOT_ID) |
1180 | }) |
1181 | |
1182 | tape('large code size', async t => { |
1183 | t.plan(1) |
1184 | const content = Buffer.from(new ArrayBuffer(1000000)) |
1185 | class testVMContainer extends BaseContainer { |
1186 | onMessage () {} |
1187 | } |
1188 | |
1189 | const hypervisor = new Hypervisor(node.dag) |
1190 | hypervisor.registerContainer(testVMContainer) |
1191 | await hypervisor.createInstance(testVMContainer.typeId, new Message({data: content})) |
1192 | const instance = await hypervisor.getInstance(hypervisor.ROOT_ID) |
1193 | t.equals(content.length, instance.code.length) |
1194 | }) |
1195 | }) |
1196 |
Built with git-ssb-web