git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: c77c7618fb3abd31a3d1b797af55b9f21a318173

Files: c77c7618fb3abd31a3d1b797af55b9f21a318173 / tests / index.js

19527 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('trying to listen for caps more then once', 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 t.true(m, 'should recive first message')
453 const message = new Message({data: 'first'})
454 this.actor.send(m.caps[0], message)
455 const promise = this.actor.inbox.nextTaggedMessage([1], 44)
456 try {
457 await this.actor.inbox.nextTaggedMessage([1], 44)
458 } catch (e) {
459 t.true(e, 'should error if waiting twice')
460 }
461 return promise
462 }
463 }
464
465 class testVMContainerB extends BaseContainer {
466 onMessage (m) {
467 t.true(m, 'should recive a 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 await hypervisor.send(capA, new Message({caps: [capB]}))
483
484 const stateRoot = await hypervisor.createStateRoot()
485 t.deepEquals(stateRoot, expectedState, 'expected root!')
486})
487
488tape('multple messages to restore on waiting for tags', async t => {
489 t.plan(6)
490 const expectedState = {
491 '/': Buffer.from('b2025e9430f0ce3a53767a36124fa622f782a38f', '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 if (m.caps.length) {
502 const cap1 = this.actor.mintCap(1)
503 const cap2 = this.actor.mintCap(2)
504 const message1 = new Message({
505 data: 'first'
506 })
507 const message2 = new Message({
508 data: 'second'
509 })
510 message1.caps.push(cap1)
511 message2.caps.push(cap2)
512 this.actor.send(m.caps[0], message1)
513 this.actor.send(m.caps[1], message2)
514 const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44)
515 t.true(rMessage, 'should recive a response message')
516 }
517 }
518 }
519
520 class testVMContainerB extends BaseContainer {
521 onMessage (m) {
522 t.true(m, 'should recive a message')
523 const cap = m.caps[0]
524 this.actor.incrementTicks(1)
525 this.actor.send(cap, new Message({data: m.data}))
526 }
527
528 static get typeId () {
529 return 8
530 }
531 }
532
533 const hypervisor = new Hypervisor(tree)
534 hypervisor.registerContainer(testVMContainerA)
535 hypervisor.registerContainer(testVMContainerB)
536
537 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
538 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
539 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
540
541 hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
542
543 const stateRoot = await hypervisor.createStateRoot()
544
545 t.deepEquals(stateRoot, expectedState, 'expected root!')
546})
547
548tape('multple messages to backup on waiting for tags', async t => {
549 t.plan(6)
550 const expectedState = {
551 '/': Buffer.from('b2025e9430f0ce3a53767a36124fa622f782a38f', 'hex')
552 }
553
554 const tree = new RadixTree({
555 db: db
556 })
557
558 class testVMContainerA extends BaseContainer {
559 async onMessage (m) {
560 t.true(m, 'should recive first message')
561 if (m.caps.length) {
562 const cap1 = this.actor.mintCap(1)
563 const cap2 = this.actor.mintCap(2)
564 const message1 = new Message({
565 data: 'first'
566 })
567 const message2 = new Message({
568 data: 'second'
569 })
570 message1.caps.push(cap1)
571 message2.caps.push(cap2)
572 this.actor.send(m.caps[0], message1)
573 this.actor.send(m.caps[1], message2)
574 const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44)
575 t.true(rMessage, 'should recive a response message')
576 }
577 }
578 }
579
580 class testVMContainerB extends BaseContainer {
581 async onMessage (m) {
582 t.true(m, 'should recive a message')
583 const cap = m.caps[0]
584 this.actor.incrementTicks(1)
585 this.actor.send(cap, new Message({data: m.data}))
586 }
587
588 static get typeId () {
589 return 8
590 }
591 }
592
593 const hypervisor = new Hypervisor(tree)
594 hypervisor.registerContainer(testVMContainerA)
595 hypervisor.registerContainer(testVMContainerB)
596
597 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
598 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
599 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
600
601 hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
602
603 const stateRoot = await hypervisor.createStateRoot()
604 t.deepEquals(stateRoot, expectedState, 'expected root!')
605})
606
607tape('multple messages, but single tag', async t => {
608 t.plan(6)
609 const expectedState = {
610 '/': Buffer.from('b2025e9430f0ce3a53767a36124fa622f782a38f', 'hex')
611 }
612
613 const tree = new RadixTree({
614 db: db
615 })
616
617 class testVMContainerA extends BaseContainer {
618 async onMessage (m) {
619 t.true(m, 'should recive first message')
620 if (m.caps.length) {
621 const cap1 = this.actor.mintCap(1)
622 const cap2 = this.actor.mintCap(2)
623 const message1 = new Message({
624 data: 'first'
625 })
626 const message2 = new Message({
627 data: 'second'
628 })
629 message1.caps.push(cap1)
630 message2.caps.push(cap2)
631 await this.actor.send(m.caps[0], message1)
632 await this.actor.send(m.caps[1], message2)
633 const rMessage = await this.actor.inbox.nextTaggedMessage([2], 44)
634 t.true(rMessage, 'should recive a response message')
635 }
636 }
637 }
638
639 class testVMContainerB extends BaseContainer {
640 async onMessage (m) {
641 t.true(m, 'should recive a message')
642 const cap = m.caps[0]
643 this.actor.incrementTicks(1)
644 this.actor.send(cap, new Message({data: m.data}))
645 }
646
647 static get typeId () {
648 return 8
649 }
650 }
651
652 const hypervisor = new Hypervisor(tree)
653 hypervisor.registerContainer(testVMContainerA)
654 hypervisor.registerContainer(testVMContainerB)
655
656 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
657 let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
658 let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message())
659
660 hypervisor.send(capA, new Message({caps: [capB1, capB2]}))
661
662 const stateRoot = await hypervisor.createStateRoot()
663 t.deepEquals(stateRoot, expectedState, 'expected root!')
664})
665
666tape('deadlock test', async t => {
667 t.plan(7)
668 const expectedState = {
669 '/': Buffer.from('54f55756d0255d849e6878cc706f4c1565396e5c', 'hex')
670 }
671
672 const tree = new RadixTree({
673 db: db
674 })
675
676 class testVMContainerA extends BaseContainer {
677 async onMessage (m) {
678 t.true(m, 'should recive first message 1')
679 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 50)
680 t.equals(rMessage, undefined, 'should recive a response message 1')
681 }
682 }
683
684 class testVMContainerB extends BaseContainer {
685 async onMessage (m) {
686 t.true(m, 'should recive first message 2')
687 this.actor.incrementTicks(47)
688 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1)
689 t.equals(rMessage, undefined, 'should recive a response message 2')
690 }
691
692 static get typeId () {
693 return 8
694 }
695 }
696
697 class testVMContainerC extends BaseContainer {
698 async onMessage (m) {
699 t.true(m, 'should recive first message 3')
700 this.actor.incrementTicks(45)
701 const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1)
702 t.equals(rMessage, undefined, 'should recive a response message 3')
703 }
704
705 static get typeId () {
706 return 7
707 }
708 }
709
710 const hypervisor = new Hypervisor(tree)
711 hypervisor.registerContainer(testVMContainerA)
712 hypervisor.registerContainer(testVMContainerB)
713 hypervisor.registerContainer(testVMContainerC)
714
715 let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message())
716 let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message())
717 let capC = await hypervisor.createActor(testVMContainerC.typeId, new Message())
718
719 hypervisor.send(capA, new Message())
720 hypervisor.send(capB, new Message())
721 hypervisor.send(capC, new Message())
722
723 const stateRoot = await hypervisor.createStateRoot()
724 t.deepEquals(stateRoot, expectedState, 'expected root!')
725})
726

Built with git-ssb-web