git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 9e075d6fa8d8d5137146130915af95c57bc1b231

Files: 9e075d6fa8d8d5137146130915af95c57bc1b231 / tests / index.js

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

Built with git-ssb-web