git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 818c7e2b325f1dac05933b54857443ddadc56c93

Files: 818c7e2b325f1dac05933b54857443ddadc56c93 / tests / index.js

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

Built with git-ssb-web