git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 4edd1fee9342f57e8ccc90c989eccfbf4aa9a15f

Files: 4edd1fee9342f57e8ccc90c989eccfbf4aa9a15f / tests / index.js

36211 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 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 await 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 async onMessage (m) {
175 const [portRef1, portRef2] = this.kernel.ports.createChannel()
176 await 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 await 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 await Promise.all([
247 this.kernel.createInstance(Root.typeId, message1),
248 this.kernel.createInstance(Root.typeId, message2),
249 this.kernel.createInstance(Root.typeId, message3)
250 ])
251
252 throw new Error('it is a trap!!!')
253 }
254 }
255
256 const hypervisor = new Hypervisor(node.dag)
257
258 hypervisor.registerContainer(Root)
259 const root = await hypervisor.createInstance(Root.typeId)
260 await root.message(root.createMessage())
261 const stateRoot = await hypervisor.createStateRoot()
262
263 t.deepEquals(stateRoot, {
264 '/': 'zdpuAoifKuJkWz9Fjvt79NmGq3tcefhfCyq8iM8YhcFdV9bmZ'
265 }, 'should revert the state')
266 })
267
268 tape('message should arrive in the correct oder if sent in order', async t => {
269 t.plan(2)
270 let runs = 0
271
272 class Root extends BaseContainer {
273 async onMessage (m) {
274 if (!runs) {
275 runs++
276
277 const [portRef1, portRef2] = this.kernel.ports.createChannel()
278 const [portRef3, portRef4] = this.kernel.ports.createChannel()
279
280 const message1 = this.kernel.createMessage({
281 ports: [portRef2]
282 })
283 const message2 = this.kernel.createMessage({
284 ports: [portRef4]
285 })
286
287 await this.kernel.createInstance(First.typeId, message1)
288 await this.kernel.createInstance(Second.typeId, message2)
289
290 this.kernel.send(portRef1, this.kernel.createMessage())
291 this.kernel.send(portRef3, this.kernel.createMessage())
292 return Promise.all(
293 this.kernel.ports.bind('two', portRef3),
294 this.kernel.ports.bind('one', portRef1)
295 )
296 } else if (runs === 1) {
297 runs++
298 t.equals(m.data, 'first', 'should recive the first message')
299 } else if (runs === 2) {
300 t.equals(m.data, 'second', 'should recived the second message')
301 }
302 }
303 }
304
305 class First extends BaseContainer {
306 onMessage (m) {
307 this.kernel.incrementTicks(2)
308 this.kernel.send(m.fromPort, this.kernel.createMessage({
309 data: 'first'
310 }))
311 }
312
313 static get typeId () {
314 return 99
315 }
316 }
317
318 class Second extends BaseContainer {
319 onMessage (m) {
320 this.kernel.incrementTicks(3)
321 this.kernel.send(m.fromPort, this.kernel.createMessage({
322 data: 'second'
323 }))
324 }
325
326 static get typeId () {
327 return 299
328 }
329 }
330
331 const hypervisor = new Hypervisor(node.dag)
332
333 hypervisor.registerContainer(Root)
334 hypervisor.registerContainer(First)
335 hypervisor.registerContainer(Second)
336
337 const root = await hypervisor.createInstance(Root.typeId)
338
339 const [portRef1, portRef2] = root.ports.createChannel()
340 await root.createInstance(Root.typeId, root.createMessage({
341 ports: [portRef2]
342 }))
343
344 await root.ports.bind('first', portRef1)
345 const message = root.createMessage()
346 root.send(portRef1, message)
347 })
348
349 tape('message should arrive in the correct oder if sent in order', async t => {
350 t.plan(2)
351 let runs = 0
352
353 class Root extends BaseContainer {
354 async onMessage (m) {
355 if (!runs) {
356 runs++
357
358 const [portRef1, portRef2] = this.kernel.ports.createChannel()
359 const [portRef3, portRef4] = this.kernel.ports.createChannel()
360
361 const message1 = this.kernel.createMessage({
362 ports: [portRef2]
363 })
364 const message2 = this.kernel.createMessage({
365 ports: [portRef4]
366 })
367
368 await this.kernel.createInstance(First.typeId, message1)
369 await this.kernel.createInstance(Second.typeId, message2)
370
371 this.kernel.send(portRef1, this.kernel.createMessage())
372 this.kernel.send(portRef3, this.kernel.createMessage())
373
374 return Promise.all([
375 this.kernel.ports.bind('one', portRef1),
376 this.kernel.ports.bind('two', portRef3)
377 ])
378 } else if (runs === 1) {
379 runs++
380 t.equals(m.data, 'second', 'should recived the second message')
381 } else if (runs === 2) {
382 t.equals(m.data, 'first', 'should recive the first message')
383 }
384 }
385
386 static get typeId () {
387 return 99
388 }
389 }
390
391 class First extends BaseContainer {
392 onMessage (m) {
393 this.kernel.incrementTicks(2)
394 this.kernel.send(m.fromPort, this.kernel.createMessage({
395 data: 'first'
396 }))
397 }
398
399 static get typeId () {
400 return 299
401 }
402 }
403
404 class Second extends BaseContainer {
405 onMessage (m) {
406 this.kernel.incrementTicks(1)
407 this.kernel.send(m.fromPort, this.kernel.createMessage({
408 data: 'second'
409 }))
410 }
411 }
412
413 const hypervisor = new Hypervisor(node.dag)
414
415 hypervisor.registerContainer(Root)
416 hypervisor.registerContainer(First)
417 hypervisor.registerContainer(Second)
418
419 const root = await hypervisor.createInstance(Root.typeId)
420
421 const [portRef1, portRef2] = root.ports.createChannel()
422 await root.createInstance(Root.typeId, root.createMessage({
423 ports: [portRef2]
424 }))
425
426 await root.ports.bind('first', portRef1)
427 const message = root.createMessage()
428 root.send(portRef1, message)
429 })
430
431 tape('message should arrive in the correct oder if sent in order', async t => {
432 t.plan(2)
433 let runs = 0
434
435 class Root extends BaseContainer {
436 onMessage (m) {
437 if (!runs) {
438 runs++
439 const [portRef1, portRef2] = this.kernel.ports.createChannel()
440 const [portRef3, portRef4] = this.kernel.ports.createChannel()
441
442 const message1 = this.kernel.createMessage({
443 ports: [portRef2]
444 })
445 const message2 = this.kernel.createMessage({
446 ports: [portRef4]
447 })
448
449 this.kernel.send(portRef1, this.kernel.createMessage())
450 this.kernel.send(portRef3, this.kernel.createMessage())
451
452 this.kernel.incrementTicks(6)
453
454 return Promise.all([
455 this.kernel.createInstance(First.typeId, message1),
456 this.kernel.createInstance(Second.typeId, message2),
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 await 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 async 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 await this.kernel.createInstance(First.typeId, message1)
529 await 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 try {
587 const hypervisor = new Hypervisor(node.dag)
588
589 hypervisor.registerContainer(Root)
590 hypervisor.registerContainer(First)
591 hypervisor.registerContainer(Second)
592 hypervisor.registerContainer(Waiter)
593
594 const root = await hypervisor.createInstance(Root.typeId)
595 const [portRef1, portRef2] = root.ports.createChannel()
596
597 const message = root.createMessage()
598 root.send(portRef1, message)
599 await root.ports.bind('first', portRef1)
600 await root.createInstance(Root.typeId, root.createMessage({
601 ports: [portRef2]
602 }))
603
604 const [portRef3, portRef4] = root.ports.createChannel()
605 await root.ports.bind('sencond', portRef3)
606 await root.createInstance(Waiter.typeId, root.createMessage({
607 ports: [portRef4]
608 }))
609
610 root.incrementTicks(100)
611 root.send(portRef1, root.createMessage({data: 'testss'}))
612 // hypervisor.scheduler.done(root.id)
613 } catch (e) {
614 console.log(e)
615 }
616 })
617
618 tape('message should arrive in the correct order, even in a tie of ticks', async t => {
619 t.plan(2)
620
621 let runs = 0
622
623 class Root extends BaseContainer {
624 async onMessage (m) {
625 if (!runs) {
626 runs++
627 const [portRef1, portRef2] = this.kernel.ports.createChannel()
628 const [portRef3, portRef4] = this.kernel.ports.createChannel()
629
630 const message1 = this.kernel.createMessage({
631 ports: [portRef2]
632 })
633 const message2 = this.kernel.createMessage({
634 ports: [portRef4]
635 })
636
637 await this.kernel.createInstance(First.typeId, message1)
638 await this.kernel.createInstance(Second.typeId, message2)
639
640 this.kernel.send(portRef1, this.kernel.createMessage())
641 this.kernel.send(portRef3, this.kernel.createMessage())
642
643 this.kernel.incrementTicks(6)
644 return Promise.all([
645 this.kernel.ports.bind('two', portRef3),
646 this.kernel.ports.bind('one', portRef1)
647 ])
648 } else if (runs === 1) {
649 runs++
650 t.equals(m.data, 'second', 'should recived the second message')
651 } else if (runs === 2) {
652 t.equals(m.data, 'first', 'should recive the first message')
653 }
654 }
655 static get typeId () {
656 return 299
657 }
658 }
659
660 class First extends BaseContainer {
661 onMessage (m) {
662 this.kernel.incrementTicks(2)
663 this.kernel.send(m.fromPort, this.kernel.createMessage({
664 data: 'first'
665 }))
666 }
667 static get typeId () {
668 return 29
669 }
670 }
671
672 class Second extends BaseContainer {
673 onMessage (m) {
674 this.kernel.incrementTicks(2)
675 this.kernel.send(m.fromPort, this.kernel.createMessage({
676 data: 'second'
677 }))
678 }
679 static get typeId () {
680 return 2
681 }
682 }
683
684 const hypervisor = new Hypervisor(node.dag)
685
686 hypervisor.registerContainer(Root)
687 hypervisor.registerContainer(First)
688 hypervisor.registerContainer(Second)
689
690 const root = await hypervisor.createInstance(Root.typeId)
691 const [portRef1, portRef2] = root.ports.createChannel()
692 const message = root.createMessage()
693
694 root.send(portRef1, message)
695 await root.ports.bind('first', portRef1)
696 await root.createInstance(Root.typeId, root.createMessage({
697 ports: [portRef2]
698 }))
699 })
700
701 tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => {
702 t.plan(2)
703
704 let runs = 0
705
706 class Root extends BaseContainer {
707 async onMessage (m) {
708 if (!runs) {
709 runs++
710 const [portRef1, portRef2] = this.kernel.ports.createChannel()
711 const [portRef3, portRef4] = this.kernel.ports.createChannel()
712
713 await this.kernel.ports.bind('one', portRef1)
714 await this.kernel.ports.bind('two', portRef3)
715
716 const message1 = this.kernel.createMessage({
717 ports: [portRef2]
718 })
719 const message2 = this.kernel.createMessage({
720 ports: [portRef4]
721 })
722
723 await this.kernel.createInstance(First.typeId, message1)
724 await this.kernel.createInstance(Second.typeId, message2)
725
726 this.kernel.send(portRef1, this.kernel.createMessage())
727 this.kernel.send(portRef3, this.kernel.createMessage())
728
729 this.kernel.incrementTicks(6)
730 } else if (runs === 1) {
731 runs++
732 t.equals(m.data, 'first', 'should recive the first message')
733 } else if (runs === 2) {
734 t.equals(m.data, 'second', 'should recived the second message')
735 }
736 }
737 static get typeId () {
738 return 299
739 }
740 }
741
742 class First extends BaseContainer {
743 onMessage (m) {
744 this.kernel.incrementTicks(2)
745 this.kernel.send(m.fromPort, this.kernel.createMessage({
746 data: 'first'
747 }))
748 }
749 static get typeId () {
750 return 29
751 }
752 }
753
754 class Second extends BaseContainer {
755 onMessage (m) {
756 this.kernel.incrementTicks(2)
757 this.kernel.send(m.fromPort, this.kernel.createMessage({
758 data: 'second'
759 }))
760 }
761 }
762
763 const hypervisor = new Hypervisor(node.dag)
764
765 hypervisor.registerContainer(Root)
766 hypervisor.registerContainer(First)
767 hypervisor.registerContainer(Second)
768
769 const root = await hypervisor.createInstance(Root.typeId)
770 const [portRef1, portRef2] = root.ports.createChannel()
771 const message = root.createMessage()
772
773 root.send(portRef1, message)
774 await root.ports.bind('first', portRef1)
775 await root.createInstance(Root.typeId, root.createMessage({
776 ports: [portRef2]
777 }))
778 })
779
780 tape('send to the same container at the same time', async t => {
781 t.plan(2)
782
783 let runs = 0
784 let instance
785
786 class Root extends BaseContainer {
787 async onMessage (m) {
788 let one = this.kernel.ports.get('one')
789 if (!one) {
790 const [portRef1, portRef2] = this.kernel.ports.createChannel()
791 const message1 = this.kernel.createMessage({
792 ports: [portRef2]
793 })
794 await this.kernel.createInstance(First.typeId, message1)
795 return this.kernel.ports.bind('one', portRef1)
796 } else {
797 this.kernel.send(one, this.kernel.createMessage())
798 this.kernel.send(one, this.kernel.createMessage())
799 }
800 }
801 static get typeId () {
802 return 299
803 }
804 }
805
806 class First extends BaseContainer {
807 onMessage (m) {
808 ++runs
809 if (runs === 2) {
810 t.equals(instance, this, 'should have same instances')
811 } else {
812 instance = this
813 }
814 }
815 }
816
817 try {
818 const hypervisor = new Hypervisor(node.dag)
819
820 hypervisor.registerContainer(Root)
821 hypervisor.registerContainer(First)
822
823 const root = await hypervisor.createInstance(Root.typeId)
824 const [portRef1, portRef2] = root.ports.createChannel()
825 await root.ports.bind('first', portRef1)
826 await root.createInstance(Root.typeId, root.createMessage({
827 ports: [portRef2]
828 }))
829
830 const message = root.createMessage()
831 root.send(portRef1, message)
832 await hypervisor.createStateRoot()
833 root.send(portRef1, root.createMessage())
834 await hypervisor.createStateRoot()
835 t.equals(runs, 2)
836 } catch (e) {
837 console.log(e)
838 }
839 })
840
841 tape('checking ports', async t => {
842 t.plan(4)
843 const hypervisor = new Hypervisor(node.dag)
844 hypervisor.registerContainer(BaseContainer)
845
846 const root = await hypervisor.createInstance(BaseContainer.typeId)
847
848 const [portRef1, portRef2] = root.ports.createChannel()
849 root.createInstance(BaseContainer.typeId, root.createMessage({
850 ports: [portRef2]
851 }))
852 await root.ports.bind('test', portRef1)
853
854 try {
855 root.createMessage({
856 ports: [portRef1]
857 })
858 } catch (e) {
859 t.pass('should thow if sending a port that is bound')
860 }
861
862 try {
863 await root.ports.bind('test', portRef1)
864 } catch (e) {
865 t.pass('should thow if binding an already bound port')
866 }
867
868 try {
869 const [portRef3] = root.ports.createChannel()
870 await root.ports.bind('test', portRef3)
871 } catch (e) {
872 t.pass('should thow if binding an already bound name')
873 }
874
875 await root.ports.unbind('test')
876 const message = root.createMessage({
877 ports: [portRef1]
878 })
879 t.equals(message.ports[0], portRef1, 'should create a message if the port is unbound')
880 })
881
882 tape('port deletion', async t => {
883 const expectedSr = {
884 '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md'
885 }
886 class Root extends BaseContainer {
887 async onMessage (m) {
888 const [portRef1, portRef2] = this.kernel.ports.createChannel()
889 const message1 = this.kernel.createMessage({
890 ports: [portRef2]
891 })
892
893 await this.kernel.createInstance(First.typeId, message1)
894 this.kernel.send(portRef1, this.kernel.createMessage())
895 this.kernel.incrementTicks(6)
896 return this.kernel.ports.bind('one', portRef1)
897 }
898 }
899
900 class First extends BaseContainer {
901 onMessage (m) {
902 this.kernel.incrementTicks(2)
903 this.kernel.ports.delete('root')
904 }
905 static get typeId () {
906 return 299
907 }
908 }
909
910 const hypervisor = new Hypervisor(node.dag)
911
912 hypervisor.registerContainer(Root)
913 hypervisor.registerContainer(First)
914
915 const root = await hypervisor.createInstance(Root.typeId)
916 const [portRef1, portRef2] = root.ports.createChannel()
917 await root.ports.bind('first', portRef1)
918 await root.createInstance(Root.typeId, root.createMessage({
919 ports: [portRef2]
920 }))
921
922 const message = root.createMessage()
923 root.send(portRef1, message)
924
925 const sr = await hypervisor.createStateRoot()
926 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
927 await hypervisor.graph.tree(sr, Infinity, true)
928
929 t.end()
930 })
931
932 tape('clear unbounded ports', async t => {
933 const expectedSr = {
934 '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md'
935 }
936 class Root extends BaseContainer {
937 onMessage (m) {
938 return this.kernel.createInstance(Root.typeId)
939 }
940 }
941
942 const hypervisor = new Hypervisor(node.dag)
943 hypervisor.registerContainer(Root)
944
945 const root = await hypervisor.createInstance(Root.typeId)
946 const [portRef1, portRef2] = root.ports.createChannel()
947 await root.ports.bind('first', portRef1)
948 await root.createInstance(Root.typeId, root.createMessage({
949 ports: [portRef2]
950 }))
951
952 const message = root.createMessage()
953 root.send(portRef1, message)
954 const sr = await hypervisor.createStateRoot()
955 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
956
957 t.end()
958 })
959
960 tape('should remove subgraphs', async t => {
961 const expectedSr = {
962 '/': 'zdpuAopMy53q2uvL2a4fhVEAvwXjSDW28fh8zhQUj598tb5md'
963 }
964 class Root extends BaseContainer {
965 onMessage (m) {
966 const [, portRef2] = this.kernel.ports.createChannel()
967 return this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({
968 ports: [portRef2]
969 }))
970 }
971 }
972
973 class Sub extends BaseContainer {
974 async onInitailize (message) {
975 await this.kernel.ports.bind('root', message.ports[0])
976 const [portRef1, portRef2] = this.kernel.ports.createChannel()
977 await this.kernel.ports.bind('child', portRef1)
978 await this.kernel.createInstance(Root.typeId, this.kernel.createMessage({
979 ports: [portRef2]
980 }))
981 }
982 static get typeId () {
983 return 299
984 }
985 }
986
987 try {
988 const hypervisor = new Hypervisor(node.dag)
989
990 hypervisor.registerContainer(Root)
991 hypervisor.registerContainer(Sub)
992
993 const root = await hypervisor.createInstance(Root.typeId)
994 const [portRef1, portRef2] = root.ports.createChannel()
995 await root.ports.bind('first', portRef1)
996 await root.createInstance(Root.typeId, root.createMessage({
997 ports: [portRef2]
998 }))
999
1000 root.send(portRef1, root.createMessage())
1001 const sr = await hypervisor.createStateRoot()
1002
1003 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
1004 t.end()
1005 } catch (e) {
1006 console.log(e)
1007 }
1008 })
1009
1010 tape('should not remove connected nodes', async t => {
1011 const expectedSr = {
1012 '/': 'zdpuApKrsvsWknDML2Mme9FyZfRnVZ1hTCoKzkooYAWT3dUDV'
1013 }
1014 class Root extends BaseContainer {
1015 async onMessage (m) {
1016 if (m.ports.length) {
1017 const port = this.kernel.ports.get('test1')
1018 this.kernel.send(port, m)
1019 return this.kernel.ports.unbind('test1')
1020 } else {
1021 const [portRef1, portRef2] = this.kernel.ports.createChannel()
1022 await this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({
1023 ports: [portRef2]
1024 }))
1025 await this.kernel.ports.bind('test1', portRef1)
1026
1027 const [portRef3, portRef4] = this.kernel.ports.createChannel()
1028 await this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({
1029 ports: [portRef4]
1030 }))
1031 await this.kernel.ports.bind('test2', portRef3)
1032 this.kernel.send(portRef3, this.kernel.createMessage({
1033 data: 'getChannel'
1034 }))
1035 }
1036 }
1037 }
1038
1039 class Sub extends BaseContainer {
1040 onMessage (message) {
1041 if (message.data === 'getChannel') {
1042 const ports = this.kernel.ports.createChannel()
1043 this.kernel.send(message.fromPort, this.kernel.createMessage({
1044 data: 'bindPort',
1045 ports: [ports[1]]
1046 }))
1047 return this.kernel.ports.bind('channel', ports[0])
1048 } else if (message.data === 'bindPort') {
1049 return this.kernel.ports.bind('channel', message.ports[0])
1050 }
1051 }
1052 static get typeId () {
1053 return 299
1054 }
1055 }
1056
1057 const hypervisor = new Hypervisor(node.dag)
1058
1059 hypervisor.registerContainer(Root)
1060 hypervisor.registerContainer(Sub)
1061
1062 const root = await hypervisor.createInstance(Root.typeId)
1063 const [portRef1, portRef2] = root.ports.createChannel()
1064 await root.ports.bind('first', portRef1)
1065 await root.createInstance(Root.typeId, root.createMessage({
1066 ports: [portRef2]
1067 }))
1068
1069 root.send(portRef1, root.createMessage())
1070 const sr = await hypervisor.createStateRoot()
1071 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
1072 // await hypervisor.graph.tree(sr, Infinity)
1073
1074 t.end()
1075 })
1076
1077 tape('should remove multiple subgraphs', async t => {
1078 const expectedSr = {
1079 '/': 'zdpuArkZ5yNowNnU4qJ8vayAUncgibQP9goDP1CwFxdmPJF9D'
1080 }
1081 class Root extends BaseContainer {
1082 async onMessage (m) {
1083 if (m.ports.length) {
1084 const port = this.kernel.ports.get('test1')
1085 await this.kernel.ports.unbind('test1')
1086 await this.kernel.ports.unbind('test2')
1087 await this.kernel.send(port, m)
1088 } else {
1089 const [portRef1, portRef2] = this.kernel.ports.createChannel()
1090 await this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({
1091 ports: [portRef2]
1092 }))
1093 await this.kernel.ports.bind('test1', portRef1)
1094
1095 const [portRef3, portRef4] = this.kernel.ports.createChannel()
1096 await this.kernel.createInstance(Sub.typeId, this.kernel.createMessage({
1097 ports: [portRef4]
1098 }))
1099 await this.kernel.ports.bind('test2', portRef3)
1100 await this.kernel.send(portRef3, this.kernel.createMessage({
1101 data: 'getChannel'
1102 }))
1103 }
1104 }
1105 }
1106
1107 class Sub extends BaseContainer {
1108 async onMessage (message) {
1109 if (message.data === 'getChannel') {
1110 const ports = this.kernel.ports.createChannel()
1111 await this.kernel.send(message.fromPort, this.kernel.createMessage({
1112 data: 'bindPort',
1113 ports: [ports[1]]
1114 }))
1115 return this.kernel.ports.bind('channel', ports[0])
1116 } else if (message.data === 'bindPort') {
1117 return this.kernel.ports.bind('channel', message.ports[0])
1118 }
1119 }
1120 static get typeId () {
1121 return 299
1122 }
1123 }
1124
1125 try {
1126 const hypervisor = new Hypervisor(node.dag)
1127
1128 hypervisor.registerContainer(Root)
1129 hypervisor.registerContainer(Sub)
1130
1131 const root = await hypervisor.createInstance(Root.typeId)
1132
1133 const [portRef1, portRef2] = root.ports.createChannel()
1134 await root.ports.bind('first', portRef1)
1135 await root.createInstance(Root.typeId, root.createMessage({
1136 ports: [portRef2]
1137 }))
1138
1139 root.send(portRef1, root.createMessage())
1140
1141 const sr = await hypervisor.createStateRoot()
1142 t.deepEquals(sr, expectedSr, 'should produce the corret state root')
1143
1144 // await hypervisor.graph.tree(sr, Infinity, true)
1145 // console.log(JSON.stringify(sr, null, 2))
1146
1147 t.end()
1148 } catch (e) {
1149 console.log(e)
1150 }
1151 })
1152
1153 tape('response ports', async t => {
1154 t.plan(2)
1155 let runs = 0
1156 const returnValue = 'this is a test'
1157
1158 class testVMContainer extends BaseContainer {
1159 onMessage (m) {
1160 runs++
1161 if (runs === 1) {
1162 return returnValue
1163 } else {
1164 t.equals(m.data, returnValue, 'should have correct return value')
1165 }
1166 }
1167 }
1168
1169 const hypervisor = new Hypervisor(node.dag)
1170
1171 hypervisor.registerContainer(testVMContainer)
1172
1173 const rootContainer = await hypervisor.createInstance(testVMContainer.typeId)
1174
1175 const [portRef1, portRef2] = rootContainer.ports.createChannel()
1176 const initMessage = rootContainer.createMessage({
1177 ports: [portRef2]
1178 })
1179
1180 rootContainer.createInstance(testVMContainer.typeId, initMessage)
1181
1182 await rootContainer.ports.bind('first', portRef1)
1183 const message = rootContainer.createMessage()
1184 const rPort = rootContainer.getResponsePort(message)
1185 const rPort2 = rootContainer.getResponsePort(message)
1186
1187 t.equals(rPort2, rPort)
1188
1189 rootContainer.send(portRef1, message)
1190 await rootContainer.ports.bind('response', rPort)
1191 })
1192
1193 tape('start up', async t => {
1194 t.plan(1)
1195 class testVMContainer extends BaseContainer {
1196 onMessage () {}
1197 onStartup () {
1198 t.true(true, 'should start up')
1199 }
1200 }
1201
1202 const hypervisor = new Hypervisor(node.dag)
1203 hypervisor.registerContainer(testVMContainer)
1204 await hypervisor.createInstance(testVMContainer.typeId)
1205 hypervisor.getInstance(hypervisor.ROOT_ID)
1206 })
1207
1208 tape('large code size', async t => {
1209 t.plan(1)
1210 const content = Buffer.from(new ArrayBuffer(1000000))
1211 class testVMContainer extends BaseContainer {
1212 onMessage () {}
1213 }
1214
1215 const hypervisor = new Hypervisor(node.dag)
1216 hypervisor.registerContainer(testVMContainer)
1217 await hypervisor.createInstance(testVMContainer.typeId, new Message({data: content}))
1218 const instance = await hypervisor.getInstance(hypervisor.ROOT_ID)
1219 t.equals(content.length, instance.code.length)
1220 })
1221})
1222

Built with git-ssb-web