git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 67f17984adbe450a9a06aa0987f1b232af5f3120

Files: 67f17984adbe450a9a06aa0987f1b232af5f3120 / tests / index.js

31612 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 return 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
475 const [portRef1, portRef2] = root.ports.createChannel()
476 const [portRef3, portRef4] = root.ports.createChannel()
477
478 const message = root.createMessage()
479 await Promise.all([
480 root.send(portRef1, message),
481 root.ports.bind('first', portRef1),
482 root.send(creationPort, root.createMessage({
483 data: {
484 type: Root.typeId
485 },
486 ports: [portRef2]
487 })),
488 root.ports.bind('sencond', portRef3),
489 root.send(creationPort, root.createMessage({
490 data: {
491 type: Waiter.typeId
492 },
493 ports: [portRef4]
494 }))
495 ])
496
497 root.incrementTicks(100)
498 await root.send(portRef1, root.createMessage({
499 data: 'testss'
500 }))
501 root.shutdown()
502 } catch (e) {
503 console.log(e)
504 }
505 })
506
507 tape('send to the same container at the same time', async t => {
508 t.plan(2)
509
510 let runs = 0
511 let instance
512
513 const hypervisor = new Hypervisor(node.dag)
514 const creationPort = hypervisor.creationService.getPort()
515
516 class Root extends BaseContainer {
517 async onMessage (m) {
518 let one = this.kernel.ports.get('one')
519 if (!one) {
520 const [portRef1, portRef2] = this.kernel.ports.createChannel()
521 const message1 = this.kernel.createMessage({
522 data: {
523 type: First.typeId
524 },
525 ports: [portRef2]
526 })
527 await this.kernel.send(creationPort, message1)
528 return this.kernel.ports.bind('one', portRef1)
529 } else {
530 return Promise.all([
531 this.kernel.send(one, this.kernel.createMessage()),
532 this.kernel.send(one, this.kernel.createMessage())
533 ])
534 }
535 }
536 static get typeId () {
537 return 299
538 }
539 }
540
541 class First extends BaseContainer {
542 onMessage (m) {
543 ++runs
544 if (runs === 2) {
545 t.equals(instance, this, 'should have same instances')
546 } else {
547 instance = this
548 }
549 }
550 }
551
552 try {
553 hypervisor.registerContainer(Root)
554 hypervisor.registerContainer(First)
555
556 let root = await hypervisor.send(creationPort, new Message({
557 data: {
558 type: Root.typeId
559 }
560 }))
561
562 hypervisor.pin(root)
563 root = await hypervisor.getInstance(root.id)
564
565 const [portRef1, portRef2] = root.ports.createChannel()
566 await Promise.all([
567 root.ports.bind('first', portRef1),
568 root.send(creationPort, root.createMessage({
569 data: {
570 type: Root.typeId
571 },
572 ports: [portRef2]
573 }))
574 ])
575
576 const message = root.createMessage()
577
578 await root.send(portRef1, message)
579 root.shutdown()
580 await hypervisor.createStateRoot()
581 await root.send(portRef1, root.createMessage())
582 await hypervisor.createStateRoot()
583 t.equals(runs, 2)
584 } catch (e) {
585 console.log(e)
586 }
587 })
588
589 tape('checking ports', async t => {
590 t.plan(4)
591 const hypervisor = new Hypervisor(node.dag)
592 const creationPort = hypervisor.creationService.getPort()
593 hypervisor.registerContainer(BaseContainer)
594
595 let root = await hypervisor.send(creationPort, new Message({
596 data: {
597 type: BaseContainer.typeId
598 }
599 }))
600
601 hypervisor.pin(root)
602 root = await hypervisor.getInstance(root.id)
603
604 const [portRef1, portRef2] = root.ports.createChannel()
605 root.send(creationPort, root.createMessage({
606 data: {
607 type: BaseContainer.typeId
608 },
609 ports: [portRef2]
610 }))
611 await root.ports.bind('test', portRef1)
612
613 try {
614 root.createMessage({
615 ports: [portRef1]
616 })
617 } catch (e) {
618 t.pass('should thow if sending a port that is bound')
619 }
620
621 try {
622 await root.ports.bind('test', portRef1)
623 } catch (e) {
624 t.pass('should thow if binding an already bound port')
625 }
626
627 try {
628 const [portRef3] = root.ports.createChannel()
629 await root.ports.bind('test', portRef3)
630 } catch (e) {
631 t.pass('should thow if binding an already bound name')
632 }
633
634 await root.ports.unbind('test')
635 const message = root.createMessage({
636 ports: [portRef1]
637 })
638 t.equals(message.ports[0], portRef1, 'should create a message if the port is unbound')
639 })
640
641 tape('port deletion', async t => {
642 const expectedSr = {
643 '/': 'zdpuAxKfu5nMTfpz6uHPqXdHZFQDZdRUer8zcQ6nvC4pTQsop'
644 }
645
646 const hypervisor = new Hypervisor(node.dag)
647 const creationPort = hypervisor.creationService.getPort()
648
649 class Root extends BaseContainer {
650 async onMessage (m) {
651 const [portRef1, portRef2] = this.kernel.ports.createChannel()
652 const message1 = this.kernel.createMessage({
653 data: {
654 type: First.typeId
655 },
656 ports: [portRef2]
657 })
658
659 await Promise.all([
660 this.kernel.send(creationPort, message1),
661 this.kernel.send(portRef1, this.kernel.createMessage())
662 ])
663 this.kernel.incrementTicks(6)
664 return this.kernel.ports.bind('one', portRef1)
665 }
666 }
667
668 class First extends BaseContainer {
669 onMessage (m) {
670 this.kernel.incrementTicks(2)
671 return this.kernel.ports.delete('root')
672 }
673 static get typeId () {
674 return 299
675 }
676 }
677
678 hypervisor.registerContainer(Root)
679 hypervisor.registerContainer(First)
680
681 let root = await hypervisor.send(creationPort, new Message({
682 data: {
683 type: Root.typeId
684 }
685 }))
686
687 hypervisor.pin(root)
688 root = await hypervisor.getInstance(root.id)
689
690 const [portRef1, portRef2] = root.ports.createChannel()
691 await root.ports.bind('first', portRef1)
692 await root.send(creationPort, root.createMessage({
693 data: {
694 type: Root.typeId
695 },
696 ports: [portRef2]
697 }))
698
699 const message = root.createMessage()
700 await root.send(portRef1, message)
701
702 root.shutdown()
703
704 const sr = await hypervisor.createStateRoot()
705 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
706 await hypervisor.graph.tree(sr, Infinity, true)
707
708 t.end()
709 })
710
711 tape('clear unbounded ports', async t => {
712 const expectedSr = {
713 '/': 'zdpuAxKfu5nMTfpz6uHPqXdHZFQDZdRUer8zcQ6nvC4pTQsop'
714 }
715
716 const hypervisor = new Hypervisor(node.dag)
717 const creationPort = hypervisor.creationService.getPort()
718
719 class Root extends BaseContainer {
720 onMessage (m) {
721 return this.kernel.send(creationPort, new Message({
722 data: {
723 type: Root.typeId
724 }
725 }))
726 }
727 }
728
729 hypervisor.registerContainer(Root)
730
731 let root = await hypervisor.send(creationPort, new Message({
732 data: {
733 type: Root.typeId
734 }
735 }))
736
737 root = await hypervisor.getInstance(root.id)
738 hypervisor.pin(root)
739
740 const [portRef1, portRef2] = root.ports.createChannel()
741 await root.ports.bind('first', portRef1)
742 await root.send(creationPort, root.createMessage({
743 data: {
744 type: Root.typeId
745 },
746 ports: [portRef2]
747 }))
748
749 const message = root.createMessage()
750 await root.send(portRef1, message)
751 root.shutdown()
752 const sr = await hypervisor.createStateRoot()
753 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
754
755 t.end()
756 })
757
758 tape('should remove subgraphs', async t => {
759 const expectedSr = {
760 '/': 'zdpuAxKfu5nMTfpz6uHPqXdHZFQDZdRUer8zcQ6nvC4pTQsop'
761 }
762
763 const hypervisor = new Hypervisor(node.dag)
764 const creationPort = hypervisor.creationService.getPort()
765
766 class Root extends BaseContainer {
767 onMessage (m) {
768 const [, portRef2] = this.kernel.ports.createChannel()
769 return this.kernel.send(creationPort, this.kernel.createMessage({
770 data: {
771 type: Sub.typeId
772 },
773 ports: [portRef2]
774 }))
775 }
776 }
777
778 class Sub extends BaseContainer {
779 async onInitailize (message) {
780 await this.kernel.ports.bind('root', message.ports[0])
781 const [portRef1, portRef2] = this.kernel.ports.createChannel()
782 await this.kernel.ports.bind('child', portRef1)
783 await this.kernel.send(creationPort, this.kernel.createMessage({
784 data: {
785 type: Root.typeId
786 },
787 ports: [portRef2]
788 }))
789 }
790 static get typeId () {
791 return 299
792 }
793 }
794
795 try {
796 hypervisor.registerContainer(Root)
797 hypervisor.registerContainer(Sub)
798
799 let root = await hypervisor.send(creationPort, new Message({
800 data: {
801 type: Root.typeId
802 }
803 }))
804
805 root = await hypervisor.getInstance(root.id)
806
807 hypervisor.pin(root)
808
809 const [portRef1, portRef2] = root.ports.createChannel()
810 await root.ports.bind('first', portRef1)
811 await root.send(creationPort, root.createMessage({
812 data: {
813 type: Root.typeId
814 },
815 ports: [portRef2]
816 }))
817
818 await root.send(portRef1, root.createMessage())
819 root.shutdown()
820 const sr = await hypervisor.createStateRoot()
821
822 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
823 t.end()
824 } catch (e) {
825 console.log(e)
826 }
827 })
828
829 tape('should not remove connected nodes', async t => {
830 const expectedSr = {
831 '/': 'zdpuAr4A3i1t6B7BkLT9C7DoxwvFnNg74gEzyqhpFj7nqVBy6'
832 }
833
834 const hypervisor = new Hypervisor(node.dag)
835 const creationPort = hypervisor.creationService.getPort()
836
837 class Root extends BaseContainer {
838 async onMessage (m) {
839 if (m.ports.length) {
840 const port = this.kernel.ports.get('test1')
841 await this.kernel.send(port, m)
842 return this.kernel.ports.unbind('test1')
843 } else {
844 const [portRef1, portRef2] = this.kernel.ports.createChannel()
845 await this.kernel.send(creationPort, this.kernel.createMessage({
846 data: {
847 type: Sub.typeId
848 },
849 ports: [portRef2]
850 }))
851 await this.kernel.ports.bind('test1', portRef1)
852
853 const [portRef3, portRef4] = this.kernel.ports.createChannel()
854 await this.kernel.send(creationPort, this.kernel.createMessage({
855 data: {
856 type: Sub.typeId
857 },
858 ports: [portRef4]
859 }))
860 await this.kernel.ports.bind('test2', portRef3)
861 await this.kernel.send(portRef3, this.kernel.createMessage({
862 data: 'getChannel'
863 }))
864 }
865 }
866 }
867
868 class Sub extends BaseContainer {
869 async onMessage (message) {
870 if (message.data === 'getChannel') {
871 const ports = this.kernel.ports.createChannel()
872 await this.kernel.send(message.fromPort, this.kernel.createMessage({
873 data: 'bindPort',
874 ports: [ports[1]]
875 }))
876 return this.kernel.ports.bind('channel', ports[0])
877 } else if (message.data === 'bindPort') {
878 return this.kernel.ports.bind('channel', message.ports[0])
879 }
880 }
881 static get typeId () {
882 return 299
883 }
884 }
885
886 hypervisor.registerContainer(Root)
887 hypervisor.registerContainer(Sub)
888
889 let root = await hypervisor.send(creationPort, new Message({
890 data: {
891 type: Root.typeId
892 }
893 }))
894
895 root = await hypervisor.getInstance(root.id)
896 hypervisor.pin(root)
897
898 const [portRef1, portRef2] = root.ports.createChannel()
899 await root.ports.bind('first', portRef1)
900 await root.send(creationPort, root.createMessage({
901 data: {
902 type: Root.typeId
903 },
904 ports: [portRef2]
905 }))
906
907 await root.send(portRef1, root.createMessage())
908 root.shutdown()
909 const sr = await hypervisor.createStateRoot()
910
911 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
912 t.end()
913 })
914
915 tape('should remove multiple subgraphs', async t => {
916 const expectedSr = {
917 '/': 'zdpuAzYGmZeZsi5Zer7LXCTm1AsmqpUMJAXZnEeFW2UVDZj2P'
918 }
919
920 const hypervisor = new Hypervisor(node.dag)
921 const creationPort = hypervisor.creationService.getPort()
922
923 class Root extends BaseContainer {
924 onMessage (m) {
925 if (m.ports.length) {
926 const port = this.kernel.ports.get('test1')
927 return Promise.all([
928 this.kernel.send(port, m),
929 this.kernel.ports.unbind('test1'),
930 this.kernel.ports.unbind('test2')
931 ])
932 } else {
933 const [portRef1, portRef2] = this.kernel.ports.createChannel()
934 const [portRef3, portRef4] = this.kernel.ports.createChannel()
935 return Promise.all([
936 this.kernel.send(creationPort, this.kernel.createMessage({
937 data: {
938 type: Sub.typeId
939 },
940 ports: [portRef2]
941 })),
942 this.kernel.ports.bind('test1', portRef1),
943 this.kernel.send(creationPort, this.kernel.createMessage({
944 data: {
945 type: Sub.typeId
946 },
947 ports: [portRef4]
948 })),
949 this.kernel.ports.bind('test2', portRef3),
950 this.kernel.send(portRef3, this.kernel.createMessage({
951 data: 'getChannel'
952 }))
953 ])
954 }
955 }
956 }
957
958 class Sub extends BaseContainer {
959 async onMessage (message) {
960 if (message.data === 'getChannel') {
961 const ports = this.kernel.ports.createChannel()
962 await this.kernel.send(message.fromPort, this.kernel.createMessage({
963 data: 'bindPort',
964 ports: [ports[1]]
965 }))
966 return this.kernel.ports.bind('channel', ports[0])
967 } else if (message.data === 'bindPort') {
968 return this.kernel.ports.bind('channel', message.ports[0])
969 }
970 }
971 static get typeId () {
972 return 299
973 }
974 }
975
976 try {
977 hypervisor.registerContainer(Root)
978 hypervisor.registerContainer(Sub)
979
980 let root = await hypervisor.send(creationPort, new Message({
981 data: {
982 type: Root.typeId
983 }
984 }))
985
986 root = await hypervisor.getInstance(root.id)
987 hypervisor.pin(root)
988
989 const [portRef1, portRef2] = root.ports.createChannel()
990 await Promise.all([
991 root.ports.bind('first', portRef1),
992 root.send(creationPort, root.createMessage({
993 data: {
994 type: Root.typeId
995 },
996 ports: [portRef2]
997 })),
998 root.send(portRef1, root.createMessage())
999 ])
1000
1001 root.shutdown()
1002
1003 const sr = await hypervisor.createStateRoot()
1004 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
1005
1006 t.end()
1007 } catch (e) {
1008 console.log(e)
1009 }
1010 })
1011
1012 tape('response ports', async t => {
1013 t.plan(2)
1014 let runs = 0
1015 const returnValue = 'this is a test'
1016 const hypervisor = new Hypervisor(node.dag)
1017 const creationPort = hypervisor.creationService.getPort()
1018
1019 class testVMContainer extends BaseContainer {
1020 onMessage (m) {
1021 runs++
1022 if (runs === 1) {
1023 return returnValue
1024 } else {
1025 t.equals(m.data, returnValue, 'should have correct return value')
1026 }
1027 }
1028 }
1029
1030 hypervisor.registerContainer(testVMContainer)
1031
1032 let rootContainer = await hypervisor.send(creationPort, new Message({
1033 data: {
1034 type: testVMContainer.typeId
1035 }
1036 }))
1037
1038 rootContainer = await hypervisor.getInstance(rootContainer.id)
1039
1040 hypervisor.pin(rootContainer)
1041
1042 const [portRef1, portRef2] = rootContainer.ports.createChannel()
1043 const initMessage = rootContainer.createMessage({
1044 data: {
1045 type: testVMContainer.typeId
1046 },
1047 ports: [portRef2]
1048 })
1049
1050 rootContainer.send(creationPort, initMessage)
1051
1052 await rootContainer.ports.bind('first', portRef1)
1053 const message = rootContainer.createMessage()
1054 const rPort = rootContainer.getResponsePort(message)
1055 const rPort2 = rootContainer.getResponsePort(message)
1056
1057 t.equals(rPort2, rPort)
1058
1059 rootContainer.send(portRef1, message)
1060 await rootContainer.ports.bind('response', rPort)
1061 })
1062
1063 tape('start up', async t => {
1064 t.plan(1)
1065 class testVMContainer extends BaseContainer {
1066 onMessage () {}
1067 onStartup () {
1068 t.true(true, 'should start up')
1069 }
1070 }
1071
1072 const hypervisor = new Hypervisor(node.dag)
1073 const creationPort = hypervisor.creationService.getPort()
1074 hypervisor.registerContainer(testVMContainer)
1075 const instance = await hypervisor.send(creationPort, new Message({
1076 data: {
1077 type: testVMContainer.typeId
1078 }
1079 }))
1080 hypervisor.getInstance(instance.id)
1081 })
1082
1083 tape('large code size', async t => {
1084 t.plan(1)
1085 const content = Buffer.from(new ArrayBuffer(1e6))
1086 class testVMContainer extends BaseContainer {
1087 onMessage () {}
1088 }
1089
1090 const hypervisor = new Hypervisor(node.dag)
1091 const creationPort = hypervisor.creationService.getPort()
1092 hypervisor.registerContainer(testVMContainer)
1093 const oldInst = await hypervisor.send(creationPort, new Message({
1094 data: {
1095 type: testVMContainer.typeId,
1096 code: content
1097 }
1098 }))
1099 const instance = await hypervisor.getInstance(oldInst.id)
1100 t.equals(content.length, instance.code.length)
1101 })
1102
1103 tape('creation service messaging', async t => {
1104 t.plan(1)
1105 class TestVMContainer extends BaseContainer {
1106 async onCreation (m) {
1107 const creationPort = m.ports[0]
1108 const [port1, port2] = this.kernel.ports.createChannel()
1109 await this.kernel.ports.bind('child', port1)
1110
1111 const message = this.kernel.createMessage({
1112 data: {
1113 type: TestVMContainer2.typeId
1114 },
1115 ports: [port2]
1116 })
1117 return this.kernel.send(creationPort, message)
1118 }
1119 }
1120
1121 class TestVMContainer2 extends BaseContainer {
1122 static get typeId () {
1123 return 66
1124 }
1125 }
1126
1127 const hypervisor = new Hypervisor(node.dag)
1128 hypervisor.registerContainer(TestVMContainer)
1129 hypervisor.registerContainer(TestVMContainer2)
1130
1131 const port = hypervisor.creationService.getPort()
1132 const port2 = hypervisor.creationService.getPort()
1133
1134 const root = await hypervisor.send(port2, new Message({
1135 data: {
1136 type: TestVMContainer.typeId
1137 },
1138 ports: [port]
1139 }))
1140
1141 hypervisor.pin(root)
1142
1143 const stateRoot = await hypervisor.createStateRoot()
1144 // await hypervisor.graph.tree(hypervisor.state, Infinity, true)
1145 const expectedSR = {
1146 '/': 'zdpuAonuhk7ZhdghJh4saaUCskY5mXZ6M9BcV9iAhCanAQx9i'
1147 }
1148 t.deepEquals(stateRoot, expectedSR)
1149 })
1150})
1151

Built with git-ssb-web