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