git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 5d73da450ff3f8fae6bf5844ed02da668a06e011

Files: 5d73da450ff3f8fae6bf5844ed02da668a06e011 / tests / index.js

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

Built with git-ssb-web