git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 9d0e76ab27a7c7ca239e1ef71f84447d37f4acc4

Files: 9d0e76ab27a7c7ca239e1ef71f84447d37f4acc4 / tests / index.js

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

Built with git-ssb-web