git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 14d278d77a6b00d8d1f7c2c3058e80801569e444

Files: 14d278d77a6b00d8d1f7c2c3058e80801569e444 / tests / index.js

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

Built with git-ssb-web