git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: c07c0d327b50805cbf2d5450f58de01059a95d1a

Files: c07c0d327b50805cbf2d5450f58de01059a95d1a / tests / index.js

21304 bytesRaw
1const tape = require('tape')
2const AbstractContainer = require('primea-abstract-container')
3const Message = require('primea-message')
4const Hypervisor = require('../')
5const CapsStore = require('../capsStore.js')
6
7const level = require('level-browserify')
8const RadixTree = require('dfinity-radix-tree')
9const db = level('./testdb')
10
11class BaseContainer extends AbstractContainer {
12 onCreation () {}
13 static get typeId () {
14 return 9
15 }
16}
17
18tape('basic', async t => {
19 t.plan(2)
20 let message
21 const expectedState = {
22 '/': Buffer.from('70a9676b7995b108057bd29955e3874401aa5ba7', 'hex')
23 }
24
25 const tree = new RadixTree({
26 db: db
27 })
28
29 class testVMContainer extends BaseContainer {
30 onMessage (m, tag) {
31 t.true(m === message, 'should recive a message')
32 }
33 }
34
35 const hypervisor = new Hypervisor(tree)
36 hypervisor.registerContainer(testVMContainer)
37
38 let rootCap = await hypervisor.createActor(testVMContainer.typeId, new Message())
39
40 message = new Message()
41 hypervisor.send(rootCap, message)
42
43 const stateRoot = await hypervisor.createStateRoot(Infinity)
44 t.deepEquals(stateRoot, expectedState, 'expected root!')
45})
46
47tape('caps manager', async t => {
48 const capsManager = new CapsStore({})
49 const cap = {}
50 capsManager.store('test', cap)
51 const c = capsManager.load('test')
52 t.equals(cap, c)
53 capsManager.delete('test')
54 const empty = capsManager.load('test')
55 t.equals(empty, undefined)
56 t.end()
57})
58
59tape('two communicating actors', async t => {
60 t.plan(2)
61 let message
62 const expectedState = {
63 '/': Buffer.from('fc935489953ed357f06171dd23439d83190b3a1b', 'hex')
64 }
65
66 const tree = new RadixTree({
67 db: db
68 })
69
70 class testVMContainerA extends BaseContainer {
71 onCreation (m) {
72 message = new Message()
73 this.actor.send(m.caps[0], message)
74 }
75 }
76
77 class testVMContainerB extends BaseContainer {
78 onMessage (m) {
79 t.true(m === message, 'should recive a message')
80 }
81
82 static get typeId () {
83 return 8
84 }
85 }
86
87 const hypervisor = new Hypervisor(tree)
88 hypervisor.registerContainer(testVMContainerA)
89 hypervisor.registerContainer(testVMContainerB)
90
91 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
92 await hypervisor.createActor(testVMContainerA.typeId, new Message({
93 caps: [capB]
94 }))
95
96 const stateRoot = await hypervisor.createStateRoot(Infinity)
97
98 t.deepEquals(stateRoot, expectedState, 'expected root!')
99})
100
101tape('three communicating actors', async t => {
102 t.plan(3)
103 let message
104 const expectedState = {
105 '/': Buffer.from('24855a8efa9af536f0f9b319c05b10d6b7cae6c8', 'hex')
106 }
107
108 const tree = new RadixTree({
109 db: db
110 })
111
112 class testVMContainerA extends BaseContainer {
113 onCreation (m) {
114 message = new Message()
115 this.actor.send(m.caps[0], message)
116 }
117 }
118
119 class testVMContainerB extends BaseContainer {
120 onMessage (m) {
121 t.true(m === message, 'should recive a message')
122 }
123
124 static get typeId () {
125 return 8
126 }
127 }
128
129 const hypervisor = new Hypervisor(tree)
130 hypervisor.registerContainer(testVMContainerA)
131 hypervisor.registerContainer(testVMContainerB)
132
133 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
134 await hypervisor.createActor(testVMContainerA.typeId, new Message({
135 caps: [capB]
136 }))
137
138 await hypervisor.createActor(testVMContainerA.typeId, new Message({
139 caps: [capB]
140 }))
141
142 const stateRoot = await hypervisor.createStateRoot(Infinity)
143
144 t.deepEquals(stateRoot, expectedState, 'expected root!')
145})
146
147tape('three communicating actors, with tick counting', async t => {
148 t.plan(3)
149 let message
150 const expectedState = {
151 '/': Buffer.from('24855a8efa9af536f0f9b319c05b10d6b7cae6c8', 'hex')
152 }
153
154 const tree = new RadixTree({
155 db: db
156 })
157
158 let ticks = 1
159
160 class testVMContainerA extends BaseContainer {
161 async onCreation (m) {
162 this.actor.incrementTicks(ticks)
163 ticks++
164 message = new Message()
165 this.actor.send(m.caps[0], message)
166 }
167 }
168
169 class testVMContainerB extends BaseContainer {
170 onMessage (m) {
171 t.true(m, 'should recive a message')
172 }
173
174 static get typeId () {
175 return 8
176 }
177 }
178
179 const hypervisor = new Hypervisor(tree)
180 hypervisor.registerContainer(testVMContainerA)
181 hypervisor.registerContainer(testVMContainerB)
182
183 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
184 await hypervisor.createActor(testVMContainerA.typeId, new Message({
185 caps: [capB]
186 }))
187
188 await hypervisor.createActor(testVMContainerA.typeId, new Message({
189 caps: [capB]
190 }))
191
192 const stateRoot = await hypervisor.createStateRoot(Infinity)
193
194 t.deepEquals(stateRoot, expectedState, 'expected root!')
195})
196
197tape('response caps', async t => {
198 t.plan(3)
199 let message
200 const expectedState = {
201 '/': Buffer.from('fc935489953ed357f06171dd23439d83190b3a1b', 'hex')
202 }
203
204 const tree = new RadixTree({
205 db: db
206 })
207
208 class testVMContainerA extends BaseContainer {
209 onCreation (m) {
210 message = new Message()
211 message.responseCap = this.actor.mintCap()
212 this.actor.send(m.caps[0], message)
213 }
214
215 onMessage (m) {
216 t.true(m, 'should recive a response message')
217 }
218 }
219
220 class testVMContainerB extends BaseContainer {
221 onMessage (m) {
222 t.true(m === message, 'should recive a message')
223 }
224
225 static get typeId () {
226 return 8
227 }
228 }
229
230 const hypervisor = new Hypervisor(tree)
231 hypervisor.registerContainer(testVMContainerA)
232 hypervisor.registerContainer(testVMContainerB)
233
234 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
235 await hypervisor.createActor(testVMContainerA.typeId, new Message({
236 caps: [capB]
237 }))
238
239 const stateRoot = await hypervisor.createStateRoot(Infinity)
240
241 t.deepEquals(stateRoot, expectedState, 'expected root!')
242})
243
244tape('response caps for errors', async t => {
245 t.plan(3)
246 let message
247 const expectedState = {
248 '/': Buffer.from('fc935489953ed357f06171dd23439d83190b3a1b', 'hex')
249 }
250
251 const tree = new RadixTree({
252 db: db
253 })
254
255 class testVMContainerA extends BaseContainer {
256 onCreation (m) {
257 message = new Message()
258 message.responseCap = this.actor.mintCap()
259 this.actor.send(m.caps[0], message)
260 }
261
262 onMessage (m) {
263 t.true(m.data.exceptionError instanceof Error, 'should recive a response message')
264 }
265 }
266
267 class testVMContainerB extends BaseContainer {
268 onMessage (m) {
269 t.true(m === message, 'should recive a message')
270 throw new Error('test error')
271 }
272
273 static get typeId () {
274 return 8
275 }
276 }
277
278 const hypervisor = new Hypervisor(tree)
279 hypervisor.registerContainer(testVMContainerA)
280 hypervisor.registerContainer(testVMContainerB)
281
282 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
283 await hypervisor.createActor(testVMContainerA.typeId, new Message({
284 caps: [capB]
285 }))
286
287 const stateRoot = await hypervisor.createStateRoot(Infinity)
288
289 t.deepEquals(stateRoot, expectedState, 'expected root!')
290})
291
292tape('actor creation', async t => {
293 t.plan(2)
294 let message
295 const expectedState = {
296 '/': Buffer.from('8e809b10d473ef4592dc5c1683e89bc7001e5e3e', 'hex')
297 }
298
299 const tree = new RadixTree({
300 db: db
301 })
302
303 class testVMContainerA extends BaseContainer {
304 onCreation (m) {
305 message = new Message()
306 const cap = this.actor.mintCap()
307 message.caps.push(cap)
308 return this.actor.createActor(testVMContainerB.typeId, message)
309 }
310
311 onMessage (m) {
312 t.equals(m.data, 'test', 'should recive a response message')
313 }
314 }
315
316 class testVMContainerB extends BaseContainer {
317 onCreation (m) {
318 const cap = m.caps[0]
319 this.actor.send(cap, new Message({data: 'test'}))
320 }
321
322 static get typeId () {
323 return 8
324 }
325 }
326
327 const hypervisor = new Hypervisor(tree)
328 hypervisor.registerContainer(testVMContainerA)
329 hypervisor.registerContainer(testVMContainerB)
330
331 await hypervisor.createActor(testVMContainerA.typeId, new Message())
332
333 const stateRoot = await hypervisor.createStateRoot(Infinity)
334
335 t.deepEquals(stateRoot, expectedState, 'expected root!')
336})
337
338tape('simple message arbiter test', async t => {
339 t.plan(4)
340 const expectedState = {
341 '/': Buffer.from('fc935489953ed357f06171dd23439d83190b3a1b', 'hex')
342 }
343
344 const tree = new RadixTree({
345 db: db
346 })
347
348 class testVMContainerA extends BaseContainer {
349 onCreation (m) {
350 const message1 = new Message({
351 data: 'first'
352 })
353 const message2 = new Message({
354 data: 'second'
355 })
356 const message3 = new Message({
357 data: 'third'
358 })
359 this.actor.send(m.caps[0], message1)
360 this.actor.incrementTicks(1)
361 this.actor.send(m.caps[0], message2)
362 this.actor.incrementTicks(1)
363 this.actor.send(m.caps[0], message3)
364 }
365 }
366
367 let recMsg = 0
368
369 class testVMContainerB extends BaseContainer {
370 onMessage (m) {
371 if (recMsg === 0) {
372 t.equal(m.data, 'first', 'should recive fist message')
373 } else if (recMsg === 1) {
374 t.equal(m.data, 'second', 'should recive second message')
375 } else {
376 t.equal(m.data, 'third', 'should recive third message')
377 }
378 recMsg++
379 }
380
381 static get typeId () {
382 return 8
383 }
384 }
385
386 const hypervisor = new Hypervisor(tree)
387 hypervisor.registerContainer(testVMContainerA)
388 hypervisor.registerContainer(testVMContainerB)
389
390 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
391 await hypervisor.createActor(testVMContainerA.typeId, new Message({
392 caps: [capB]
393 }))
394
395 const stateRoot = await hypervisor.createStateRoot(Infinity)
396
397 t.deepEquals(stateRoot, expectedState, 'expected root!')
398})
399
400tape('arbiter test for id comparision', async t => {
401 t.plan(4)
402 let message
403 const expectedState = {
404 '/': Buffer.from('0866fe6a6adaf28c51ce99ddfddd49c492e9ce48', 'hex')
405 }
406
407 const tree = new RadixTree({
408 db: db
409 })
410
411 class testVMContainerA extends BaseContainer {
412 onCreation (m) {
413 message = new Message({
414 data: m.data
415 })
416 this.actor.send(m.caps[0], message)
417 }
418 }
419
420 let recMsg = 0
421
422 class testVMContainerB extends BaseContainer {
423 onMessage (m) {
424 if (recMsg === 0) {
425 t.equal(m.data, 'first', 'should recive fist message')
426 } else if (recMsg === 1) {
427 t.equal(m.data, 'second', 'should recive second message')
428 } else {
429 t.equal(m.data, 'third', 'should recive third message')
430 }
431 recMsg++
432 }
433
434 static get typeId () {
435 return 8
436 }
437 }
438
439 const hypervisor = new Hypervisor(tree)
440 hypervisor.registerContainer(testVMContainerA)
441 hypervisor.registerContainer(testVMContainerB)
442
443 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
444 await hypervisor.send(capB, new Message({
445 data: 'first'
446 }))
447
448 await hypervisor.createActor(testVMContainerA.typeId, new Message({
449 caps: [capB],
450 data: 'second'
451 }))
452
453 await hypervisor.createActor(testVMContainerA.typeId, new Message({
454 caps: [capB],
455 data: 'third'
456 }))
457
458 const stateRoot = await hypervisor.createStateRoot(Infinity)
459
460 t.deepEquals(stateRoot, expectedState, 'expected root!')
461})
462
463tape('basic tagged caps', async t => {
464 t.plan(4)
465 const expectedState = {
466 '/': Buffer.from('ef403643f292108fe9edc1700d80a7bf2402e7a0', 'hex')
467 }
468
469 const tree = new RadixTree({
470 db: db
471 })
472
473 class testVMContainerA extends BaseContainer {
474 async onMessage (m) {
475 t.true(m, 'should recive first message')
476 const rCap = this.actor.mintCap(1)
477 const message = new Message()
478 message.responseCap = rCap
479 this.actor.send(m.caps[0], message)
480 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 44)
481 t.true(rMessage, 'should recive a response message')
482 }
483 }
484
485 class testVMContainerB extends BaseContainer {
486 onMessage (m) {
487 t.true(m, 'should recive a message')
488 }
489
490 static get typeId () {
491 return 8
492 }
493 }
494
495 const hypervisor = new Hypervisor(tree)
496 hypervisor.registerContainer(testVMContainerA)
497 hypervisor.registerContainer(testVMContainerB)
498
499 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
500 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
501
502 await hypervisor.send(capA, new Message({caps: [capB]}))
503
504 const stateRoot = await hypervisor.createStateRoot(Infinity)
505
506 t.deepEquals(stateRoot, expectedState, 'expected root!')
507})
508
509tape('trying to listen for caps more then once', async t => {
510 t.plan(4)
511 const expectedState = {
512 '/': Buffer.from('ef403643f292108fe9edc1700d80a7bf2402e7a0', 'hex')
513 }
514
515 const tree = new RadixTree({
516 db: db
517 })
518
519 class testVMContainerA extends BaseContainer {
520 async onMessage (m) {
521 t.true(m, 'should recive first message')
522 const rCap = this.actor.mintCap(1)
523 const message = new Message({data: 'first'})
524 message.responseCap = rCap
525 this.actor.send(m.caps[0], message)
526 const promise = this.actor.inbox.nextTaggedMessage([1], 44)
527 try {
528 await this.actor.inbox.nextTaggedMessage([1], 44)
529 } catch (e) {
530 t.true(e, 'should error if waiting twice')
531 }
532 return promise
533 }
534 }
535
536 class testVMContainerB extends BaseContainer {
537 onMessage (m) {
538 t.true(m, 'should recive a message')
539 }
540
541 static get typeId () {
542 return 8
543 }
544 }
545
546 const hypervisor = new Hypervisor(tree)
547 hypervisor.registerContainer(testVMContainerA)
548 hypervisor.registerContainer(testVMContainerB)
549
550 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
551 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
552
553 await hypervisor.send(capA, new Message({caps: [capB]}))
554
555 const stateRoot = await hypervisor.createStateRoot(Infinity)
556
557 t.deepEquals(stateRoot, expectedState, 'expected root!')
558})
559
560tape('multple messages to restore on waiting for tags', async t => {
561 t.plan(6)
562 const expectedState = {
563 '/': Buffer.from('c2bbd78ee38ecf417f857451bdb06cdba1345b22', 'hex')
564 }
565
566 const tree = new RadixTree({
567 db: db
568 })
569
570 class testVMContainerA extends BaseContainer {
571 async onMessage (m) {
572 t.true(m, 'should recive first message')
573 if (m.caps.length) {
574 const cap1 = this.actor.mintCap(1)
575 const cap2 = this.actor.mintCap(2)
576 const message1 = new Message({
577 data: 'first'
578 })
579 const message2 = new Message({
580 data: 'second'
581 })
582 message1.caps.push(cap1)
583 message2.caps.push(cap2)
584 this.actor.send(m.caps[0], message1)
585 this.actor.send(m.caps[1], message2)
586 const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44)
587 t.true(rMessage, 'should recive a response message')
588 }
589 }
590 }
591
592 class testVMContainerB extends BaseContainer {
593 onMessage (m) {
594 t.true(m, 'should recive a message')
595 const cap = m.caps[0]
596 this.actor.incrementTicks(1)
597 this.actor.send(cap, new Message({data: m.data}))
598 }
599
600 static get typeId () {
601 return 8
602 }
603 }
604
605 const hypervisor = new Hypervisor(tree)
606 hypervisor.registerContainer(testVMContainerA)
607 hypervisor.registerContainer(testVMContainerB)
608
609 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
610 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
611 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
612
613 await hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
614
615 const stateRoot = await hypervisor.createStateRoot(Infinity)
616
617 t.deepEquals(stateRoot, expectedState, 'expected root!')
618})
619
620tape('multple messages to backup on waiting for tags', async t => {
621 t.plan(6)
622 const expectedState = {
623 '/': Buffer.from('c2bbd78ee38ecf417f857451bdb06cdba1345b22', 'hex')
624 }
625
626 const tree = new RadixTree({
627 db: db
628 })
629
630 class testVMContainerA extends BaseContainer {
631 async onMessage (m) {
632 t.true(m, 'should recive first message')
633 if (m.caps.length) {
634 const cap1 = this.actor.mintCap(1)
635 const cap2 = this.actor.mintCap(2)
636 const message1 = new Message({
637 data: 'first'
638 })
639 const message2 = new Message({
640 data: 'second'
641 })
642 message1.caps.push(cap1)
643 message2.caps.push(cap2)
644 this.actor.send(m.caps[0], message1)
645 this.actor.send(m.caps[1], message2)
646 const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44)
647 t.true(rMessage, 'should recive a response message')
648 }
649 }
650 }
651
652 class testVMContainerB extends BaseContainer {
653 async onMessage (m) {
654 t.true(m, 'should recive a message')
655 const cap = m.caps[0]
656 this.actor.incrementTicks(1)
657 this.actor.send(cap, new Message({data: m.data}))
658 }
659
660 static get typeId () {
661 return 8
662 }
663 }
664
665 const hypervisor = new Hypervisor(tree)
666 hypervisor.registerContainer(testVMContainerA)
667 hypervisor.registerContainer(testVMContainerB)
668
669 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
670 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
671 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
672
673 await hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
674
675 const stateRoot = await hypervisor.createStateRoot(Infinity)
676
677 t.deepEquals(stateRoot, expectedState, 'expected root!')
678})
679
680tape('multple messages, but single tag', async t => {
681 t.plan(6)
682 const expectedState = {
683 '/': Buffer.from('c2bbd78ee38ecf417f857451bdb06cdba1345b22', 'hex')
684 }
685
686 const tree = new RadixTree({
687 db: db
688 })
689
690 class testVMContainerA extends BaseContainer {
691 async onMessage (m) {
692 t.true(m, 'should recive first message')
693 if (m.caps.length) {
694 const cap1 = this.actor.mintCap(1)
695 const cap2 = this.actor.mintCap(2)
696 const message1 = new Message({
697 data: 'first'
698 })
699 const message2 = new Message({
700 data: 'second'
701 })
702 message1.caps.push(cap1)
703 message2.caps.push(cap2)
704 await this.actor.send(m.caps[0], message1)
705 await this.actor.send(m.caps[1], message2)
706 const rMessage = await this.actor.inbox.nextTaggedMessage([2], 44)
707 t.true(rMessage, 'should recive a response message')
708 }
709 }
710 }
711
712 class testVMContainerB extends BaseContainer {
713 async onMessage (m) {
714 t.true(m, 'should recive a message')
715 const cap = m.caps[0]
716 this.actor.incrementTicks(1)
717 this.actor.send(cap, new Message({data: m.data}))
718 }
719
720 static get typeId () {
721 return 8
722 }
723 }
724
725 const hypervisor = new Hypervisor(tree)
726 hypervisor.registerContainer(testVMContainerA)
727 hypervisor.registerContainer(testVMContainerB)
728
729 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
730 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
731 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
732
733 await hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
734
735 const stateRoot = await hypervisor.createStateRoot(Infinity)
736
737 t.deepEquals(stateRoot, expectedState, 'expected root!')
738})
739
740tape('deadlock test', async t => {
741 t.plan(7)
742 const expectedState = {
743 '/': Buffer.from('2e8658dc2f616599b4fa622318b86ad6ed809db0', 'hex')
744 }
745
746 const tree = new RadixTree({
747 db: db
748 })
749
750 class testVMContainerA extends BaseContainer {
751 async onMessage (m) {
752 t.true(m, 'should recive first message 1')
753 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 50)
754 t.equals(rMessage, undefined, 'should recive a response message 1')
755 }
756 }
757
758 class testVMContainerB extends BaseContainer {
759 async onMessage (m) {
760 t.true(m, 'should recive first message 2')
761 this.actor.incrementTicks(47)
762 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1)
763 t.equals(rMessage, undefined, 'should recive a response message 2')
764 }
765
766 static get typeId () {
767 return 8
768 }
769 }
770
771 class testVMContainerC extends BaseContainer {
772 async onMessage (m) {
773 t.true(m, 'should recive first message 3')
774 this.actor.incrementTicks(45)
775 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1)
776 t.equals(rMessage, undefined, 'should recive a response message 3')
777 }
778
779 static get typeId () {
780 return 7
781 }
782 }
783
784 const hypervisor = new Hypervisor(tree)
785 hypervisor.registerContainer(testVMContainerA)
786 hypervisor.registerContainer(testVMContainerB)
787 hypervisor.registerContainer(testVMContainerC)
788
789 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
790 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
791 let capC = await hypervisor.createActor(testVMContainerC.typeId, new Message())
792
793 await Promise.all([
794 hypervisor.send(capA, new Message()),
795 hypervisor.send(capB, new Message()),
796 hypervisor.send(capC, new Message())
797 ])
798 const stateRoot = await hypervisor.createStateRoot(Infinity)
799 t.deepEquals(stateRoot, expectedState, 'expected root!')
800})
801

Built with git-ssb-web