git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 6acaa620ead87372a23e5cd47bea746c549417da

Files: 6acaa620ead87372a23e5cd47bea746c549417da / tests / index.js

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

Built with git-ssb-web