git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: b17f430cb428dc0322dc3915948f9c7802107eda

Files: b17f430cb428dc0322dc3915948f9c7802107eda / tests / index.js

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

Built with git-ssb-web