git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: aeb0bcd3609c8af0b967edfd16aee39e7566aa0d

Files: aeb0bcd3609c8af0b967edfd16aee39e7566aa0d / tests / index.js

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

Built with git-ssb-web