git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 2fb975398cfb471a241d9576050158a86e8eff04

Files: 2fb975398cfb471a241d9576050158a86e8eff04 / tests / index.js

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

Built with git-ssb-web