git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 755514bf413e3af2218088969d281e9b6e56e8d7

Files: 755514bf413e3af2218088969d281e9b6e56e8d7 / tests / index.js

20836 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('a364c55f9993e0bc63f7155d5eb661ae9ad769d9', '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('9e8d5671e2c7d167e03784e5d9ec36e15747ad95', '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('840607eafe779858648d3311039f986e68f4752e', '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('840607eafe779858648d3311039f986e68f4752e', '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('response caps', async t => {
183 t.plan(3)
184 let message
185 const expectedState = {
186 '/': Buffer.from('9e8d5671e2c7d167e03784e5d9ec36e15747ad95', '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.responseCap = this.actor.mintCap()
197 this.actor.send(m.caps[0], message)
198 }
199
200 onMessage (m) {
201 t.true(m, 'should recive a response message')
202 }
203 }
204
205 class testVMContainerB extends BaseContainer {
206 onMessage (m) {
207 t.true(m === message, 'should recive a message')
208 }
209
210 static get typeId () {
211 return 8
212 }
213 }
214
215 const hypervisor = new Hypervisor(tree)
216 hypervisor.registerContainer(testVMContainerA)
217 hypervisor.registerContainer(testVMContainerB)
218
219 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
220 await hypervisor.createActor(testVMContainerA.typeId, new Message({
221 caps: [capB]
222 }))
223
224 const stateRoot = await hypervisor.createStateRoot()
225
226 t.deepEquals(stateRoot, expectedState, 'expected root!')
227})
228
229tape('response caps for errors', async t => {
230 t.plan(3)
231 let message
232 const expectedState = {
233 '/': Buffer.from('9e8d5671e2c7d167e03784e5d9ec36e15747ad95', 'hex')
234 }
235
236 const tree = new RadixTree({
237 db: db
238 })
239
240 class testVMContainerA extends BaseContainer {
241 onCreation (m) {
242 message = new Message()
243 message.responseCap = this.actor.mintCap()
244 this.actor.send(m.caps[0], message)
245 }
246
247 onMessage (m) {
248 t.true(m.data.exceptionError instanceof Error, 'should recive a response message')
249 }
250 }
251
252 class testVMContainerB extends BaseContainer {
253 onMessage (m) {
254 t.true(m === message, 'should recive a message')
255 throw new Error('test error')
256 }
257
258 static get typeId () {
259 return 8
260 }
261 }
262
263 const hypervisor = new Hypervisor(tree)
264 hypervisor.registerContainer(testVMContainerA)
265 hypervisor.registerContainer(testVMContainerB)
266
267 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
268 await hypervisor.createActor(testVMContainerA.typeId, new Message({
269 caps: [capB]
270 }))
271
272 const stateRoot = await hypervisor.createStateRoot()
273 t.deepEquals(stateRoot, expectedState, 'expected root!')
274})
275
276tape('actor creation', async t => {
277 t.plan(2)
278 let message
279 const expectedState = {
280 '/': Buffer.from('b19c67aea0ff97e96df6e2aacbd45b1bd260af30', 'hex')
281 }
282
283 const tree = new RadixTree({
284 db: db
285 })
286
287 class testVMContainerA extends BaseContainer {
288 onCreation (m) {
289 message = new Message()
290 const cap = this.actor.mintCap()
291 message.caps.push(cap)
292 return this.actor.createActor(testVMContainerB.typeId, message)
293 }
294
295 onMessage (m) {
296 t.equals(m.data, 'test', 'should recive a response message')
297 }
298 }
299
300 class testVMContainerB extends BaseContainer {
301 onCreation (m) {
302 const cap = m.caps[0]
303 this.actor.send(cap, new Message({data: 'test'}))
304 }
305
306 static get typeId () {
307 return 8
308 }
309 }
310
311 const hypervisor = new Hypervisor(tree)
312 hypervisor.registerContainer(testVMContainerA)
313 hypervisor.registerContainer(testVMContainerB)
314
315 await hypervisor.createActor(testVMContainerA.typeId, new Message())
316
317 const stateRoot = await hypervisor.createStateRoot()
318 t.deepEquals(stateRoot, expectedState, 'expected root!')
319})
320
321tape('simple message arbiter test', async t => {
322 t.plan(4)
323 const expectedState = {
324 '/': Buffer.from('9e8d5671e2c7d167e03784e5d9ec36e15747ad95', 'hex')
325 }
326
327 const tree = new RadixTree({
328 db: db
329 })
330
331 class testVMContainerA extends BaseContainer {
332 onCreation (m) {
333 const message1 = new Message({
334 data: 'first'
335 })
336 const message2 = new Message({
337 data: 'second'
338 })
339 const message3 = new Message({
340 data: 'third'
341 })
342 this.actor.send(m.caps[0], message1)
343 this.actor.incrementTicks(1)
344 this.actor.send(m.caps[0], message2)
345 this.actor.incrementTicks(1)
346 this.actor.send(m.caps[0], message3)
347 }
348 }
349
350 let recMsg = 0
351
352 class testVMContainerB extends BaseContainer {
353 onMessage (m) {
354 if (recMsg === 0) {
355 t.equal(m.data, 'first', 'should recive fist message')
356 } else if (recMsg === 1) {
357 t.equal(m.data, 'second', 'should recive second message')
358 } else {
359 t.equal(m.data, 'third', 'should recive third message')
360 }
361 recMsg++
362 }
363
364 static get typeId () {
365 return 8
366 }
367 }
368
369 const hypervisor = new Hypervisor(tree)
370 hypervisor.registerContainer(testVMContainerA)
371 hypervisor.registerContainer(testVMContainerB)
372
373 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
374 await hypervisor.createActor(testVMContainerA.typeId, new Message({
375 caps: [capB]
376 }))
377
378 const stateRoot = await hypervisor.createStateRoot()
379 t.deepEquals(stateRoot, expectedState, 'expected root!')
380})
381
382tape('arbiter test for id comparision', async t => {
383 t.plan(4)
384 let message
385 const expectedState = {
386 '/': Buffer.from('840607eafe779858648d3311039f986e68f4752e', 'hex')
387 }
388
389 const tree = new RadixTree({
390 db: db
391 })
392
393 class testVMContainerA extends BaseContainer {
394 onCreation (m) {
395 message = new Message({
396 data: m.data
397 })
398 this.actor.send(m.caps[0], message)
399 }
400 }
401
402 let recMsg = 0
403
404 class testVMContainerB extends BaseContainer {
405 onMessage (m) {
406 if (recMsg === 0) {
407 t.equal(m.data, 'first', 'should recive fist message')
408 } else if (recMsg === 1) {
409 t.equal(m.data, 'second', 'should recive second message')
410 } else {
411 t.equal(m.data, 'third', 'should recive third message')
412 }
413 recMsg++
414 }
415
416 static get typeId () {
417 return 8
418 }
419 }
420
421 const hypervisor = new Hypervisor(tree)
422 hypervisor.registerContainer(testVMContainerA)
423 hypervisor.registerContainer(testVMContainerB)
424
425 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
426 await hypervisor.send(capB, new Message({
427 data: 'first'
428 }))
429
430 await hypervisor.createActor(testVMContainerA.typeId, new Message({
431 caps: [capB],
432 data: 'second'
433 }))
434
435 await hypervisor.createActor(testVMContainerA.typeId, new Message({
436 caps: [capB],
437 data: 'third'
438 }))
439
440 const stateRoot = await hypervisor.createStateRoot()
441 t.deepEquals(stateRoot, expectedState, 'expected root!')
442})
443
444tape('basic tagged caps', async t => {
445 t.plan(4)
446 const expectedState = {
447 '/': Buffer.from('d4291da4536544bf90aa473a1148cb29f913d078', 'hex')
448 }
449
450 const tree = new RadixTree({
451 db: db
452 })
453
454 class testVMContainerA extends BaseContainer {
455 async onMessage (m) {
456 t.true(m, 'should recive first message')
457 const rCap = this.actor.mintCap(1)
458 const message = new Message()
459 message.responseCap = rCap
460 this.actor.send(m.caps[0], message)
461 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 44)
462 t.true(rMessage, 'should recive a response message')
463 }
464 }
465
466 class testVMContainerB extends BaseContainer {
467 onMessage (m) {
468 t.true(m, 'should recive a message')
469 }
470
471 static get typeId () {
472 return 8
473 }
474 }
475
476 const hypervisor = new Hypervisor(tree)
477 hypervisor.registerContainer(testVMContainerA)
478 hypervisor.registerContainer(testVMContainerB)
479
480 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
481 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
482
483 await hypervisor.send(capA, new Message({caps: [capB]}))
484
485 const stateRoot = await hypervisor.createStateRoot()
486 t.deepEquals(stateRoot, expectedState, 'expected root!')
487})
488
489tape('trying to listen for caps more then once', async t => {
490 t.plan(4)
491 const expectedState = {
492 '/': Buffer.from('d4291da4536544bf90aa473a1148cb29f913d078', 'hex')
493 }
494
495 const tree = new RadixTree({
496 db: db
497 })
498
499 class testVMContainerA extends BaseContainer {
500 async onMessage (m) {
501 t.true(m, 'should recive first message')
502 const rCap = this.actor.mintCap(1)
503 const message = new Message({data: 'first'})
504 message.responseCap = rCap
505 this.actor.send(m.caps[0], message)
506 const promise = this.actor.inbox.nextTaggedMessage([1], 44)
507 try {
508 await this.actor.inbox.nextTaggedMessage([1], 44)
509 } catch (e) {
510 t.true(e, 'should error if waiting twice')
511 }
512 return promise
513 }
514 }
515
516 class testVMContainerB extends BaseContainer {
517 onMessage (m) {
518 t.true(m, 'should recive a message')
519 }
520
521 static get typeId () {
522 return 8
523 }
524 }
525
526 const hypervisor = new Hypervisor(tree)
527 hypervisor.registerContainer(testVMContainerA)
528 hypervisor.registerContainer(testVMContainerB)
529
530 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
531 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
532
533 await hypervisor.send(capA, new Message({caps: [capB]}))
534
535 const stateRoot = await hypervisor.createStateRoot()
536 t.deepEquals(stateRoot, expectedState, 'expected root!')
537})
538
539tape('multple messages to restore on waiting for tags', async t => {
540 t.plan(6)
541 const expectedState = {
542 '/': Buffer.from('b5c0822ccb21bbaa2ad8069c4dcd18add7d6e2d1', 'hex')
543 }
544
545 const tree = new RadixTree({
546 db: db
547 })
548
549 class testVMContainerA extends BaseContainer {
550 async onMessage (m) {
551 t.true(m, 'should recive first message')
552 if (m.caps.length) {
553 const cap1 = this.actor.mintCap(1)
554 const cap2 = this.actor.mintCap(2)
555 const message1 = new Message({
556 data: 'first'
557 })
558 const message2 = new Message({
559 data: 'second'
560 })
561 message1.caps.push(cap1)
562 message2.caps.push(cap2)
563 this.actor.send(m.caps[0], message1)
564 this.actor.send(m.caps[1], message2)
565 const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44)
566 t.true(rMessage, 'should recive a response message')
567 }
568 }
569 }
570
571 class testVMContainerB extends BaseContainer {
572 onMessage (m) {
573 t.true(m, 'should recive a message')
574 const cap = m.caps[0]
575 this.actor.incrementTicks(1)
576 this.actor.send(cap, new Message({data: m.data}))
577 }
578
579 static get typeId () {
580 return 8
581 }
582 }
583
584 const hypervisor = new Hypervisor(tree)
585 hypervisor.registerContainer(testVMContainerA)
586 hypervisor.registerContainer(testVMContainerB)
587
588 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
589 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
590 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
591
592 await hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
593
594 const stateRoot = await hypervisor.createStateRoot()
595
596 t.deepEquals(stateRoot, expectedState, 'expected root!')
597})
598
599tape('multple messages to backup on waiting for tags', async t => {
600 t.plan(6)
601 const expectedState = {
602 '/': Buffer.from('b5c0822ccb21bbaa2ad8069c4dcd18add7d6e2d1', 'hex')
603 }
604
605 const tree = new RadixTree({
606 db: db
607 })
608
609 class testVMContainerA extends BaseContainer {
610 async onMessage (m) {
611 t.true(m, 'should recive first message')
612 if (m.caps.length) {
613 const cap1 = this.actor.mintCap(1)
614 const cap2 = this.actor.mintCap(2)
615 const message1 = new Message({
616 data: 'first'
617 })
618 const message2 = new Message({
619 data: 'second'
620 })
621 message1.caps.push(cap1)
622 message2.caps.push(cap2)
623 this.actor.send(m.caps[0], message1)
624 this.actor.send(m.caps[1], message2)
625 const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44)
626 t.true(rMessage, 'should recive a response message')
627 }
628 }
629 }
630
631 class testVMContainerB extends BaseContainer {
632 async onMessage (m) {
633 t.true(m, 'should recive a message')
634 const cap = m.caps[0]
635 this.actor.incrementTicks(1)
636 this.actor.send(cap, new Message({data: m.data}))
637 }
638
639 static get typeId () {
640 return 8
641 }
642 }
643
644 const hypervisor = new Hypervisor(tree)
645 hypervisor.registerContainer(testVMContainerA)
646 hypervisor.registerContainer(testVMContainerB)
647
648 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
649 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
650 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
651
652 await hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
653
654 const stateRoot = await hypervisor.createStateRoot()
655 t.deepEquals(stateRoot, expectedState, 'expected root!')
656})
657
658tape('multple messages, but single tag', async t => {
659 t.plan(6)
660 const expectedState = {
661 '/': Buffer.from('b5c0822ccb21bbaa2ad8069c4dcd18add7d6e2d1', 'hex')
662 }
663
664 const tree = new RadixTree({
665 db: db
666 })
667
668 class testVMContainerA extends BaseContainer {
669 async onMessage (m) {
670 t.true(m, 'should recive first message')
671 if (m.caps.length) {
672 const cap1 = this.actor.mintCap(1)
673 const cap2 = this.actor.mintCap(2)
674 const message1 = new Message({
675 data: 'first'
676 })
677 const message2 = new Message({
678 data: 'second'
679 })
680 message1.caps.push(cap1)
681 message2.caps.push(cap2)
682 await this.actor.send(m.caps[0], message1)
683 await this.actor.send(m.caps[1], message2)
684 const rMessage = await this.actor.inbox.nextTaggedMessage([2], 44)
685 t.true(rMessage, 'should recive a response message')
686 }
687 }
688 }
689
690 class testVMContainerB extends BaseContainer {
691 async onMessage (m) {
692 t.true(m, 'should recive a message')
693 const cap = m.caps[0]
694 this.actor.incrementTicks(1)
695 this.actor.send(cap, new Message({data: m.data}))
696 }
697
698 static get typeId () {
699 return 8
700 }
701 }
702
703 const hypervisor = new Hypervisor(tree)
704 hypervisor.registerContainer(testVMContainerA)
705 hypervisor.registerContainer(testVMContainerB)
706
707 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
708 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
709 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
710
711 await hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
712
713 const stateRoot = await hypervisor.createStateRoot()
714 t.deepEquals(stateRoot, expectedState, 'expected root!')
715})
716
717tape('deadlock test', async t => {
718 t.plan(7)
719 const expectedState = {
720 '/': Buffer.from('f290945ad63dd06b9ada924fa5149df4a0a32f53', 'hex')
721 }
722
723 const tree = new RadixTree({
724 db: db
725 })
726
727 class testVMContainerA extends BaseContainer {
728 async onMessage (m) {
729 t.true(m, 'should recive first message 1')
730 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 50)
731 t.equals(rMessage, undefined, 'should recive a response message 1')
732 }
733 }
734
735 class testVMContainerB extends BaseContainer {
736 async onMessage (m) {
737 t.true(m, 'should recive first message 2')
738 this.actor.incrementTicks(47)
739 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1)
740 t.equals(rMessage, undefined, 'should recive a response message 2')
741 }
742
743 static get typeId () {
744 return 8
745 }
746 }
747
748 class testVMContainerC extends BaseContainer {
749 async onMessage (m) {
750 t.true(m, 'should recive first message 3')
751 this.actor.incrementTicks(45)
752 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1)
753 t.equals(rMessage, undefined, 'should recive a response message 3')
754 }
755
756 static get typeId () {
757 return 7
758 }
759 }
760
761 const hypervisor = new Hypervisor(tree)
762 hypervisor.registerContainer(testVMContainerA)
763 hypervisor.registerContainer(testVMContainerB)
764 hypervisor.registerContainer(testVMContainerC)
765
766 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
767 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
768 let capC = await hypervisor.createActor(testVMContainerC.typeId, new Message())
769
770 await Promise.all([
771 hypervisor.send(capA, new Message()),
772 hypervisor.send(capB, new Message()),
773 hypervisor.send(capC, new Message())
774 ])
775 const stateRoot = await hypervisor.createStateRoot()
776 t.deepEquals(stateRoot, expectedState, 'expected root!')
777})
778

Built with git-ssb-web