Files: bde72a3aa9363b13bf59b50cff532ff35ef665f4 / tests / index.js
31733 bytesRaw
1 | const tape = require('tape') |
2 | const IPFS = require('ipfs') |
3 | const AbstractContainer = require('primea-abstract-container') |
4 | const Hypervisor = require('../') |
5 | |
6 | // start ipfs |
7 | const node = new IPFS({ |
8 | start: false |
9 | }) |
10 | |
11 | class BaseContainer extends AbstractContainer { |
12 | initialize (message) { |
13 | this.kernel.state.code = message.data.byteLength ? message.data : undefined |
14 | const port = message.ports[0] |
15 | if (port) { |
16 | this.kernel.ports.bind('root', port) |
17 | } |
18 | } |
19 | } |
20 | |
21 | node.on('ready', () => { |
22 | tape('basic', async t => { |
23 | t.plan(3) |
24 | let message |
25 | const expectedState = { |
26 | '/': 'zdpuB1wc9Pb6jUzfNt4nAxAEUxB7kNhg4vbq7YLcEyBUb6iAB' |
27 | } |
28 | |
29 | class testVMContainer extends BaseContainer { |
30 | run (m) { |
31 | t.true(m === message, 'should recive a message') |
32 | } |
33 | } |
34 | |
35 | const hypervisor = new Hypervisor(node.dag) |
36 | hypervisor.registerContainer('test', testVMContainer) |
37 | |
38 | const rootContainer = await hypervisor.createInstance('test') |
39 | |
40 | const [portRef1, portRef2] = rootContainer.ports.createChannel() |
41 | const initMessage = rootContainer.createMessage({ |
42 | data: Buffer.from('test code'), |
43 | ports: [portRef2] |
44 | }) |
45 | |
46 | rootContainer.createInstance('test', initMessage) |
47 | |
48 | rootContainer.ports.bind('first', portRef1) |
49 | message = rootContainer.createMessage() |
50 | rootContainer.send(portRef1, message) |
51 | |
52 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
53 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
54 | t.equals(hypervisor.scheduler.oldest(), 0) |
55 | }) |
56 | |
57 | tape('basic - do not store containers with no ports bound', async t => { |
58 | t.plan(1) |
59 | const expectedState = { |
60 | '/': 'zdpuAozDi6tKPbqmHJxo7aNES2xVt1MkaCLyxcioEKzz3M2WH' |
61 | } |
62 | |
63 | class testVMContainer extends BaseContainer { |
64 | initialize () {} |
65 | } |
66 | |
67 | const hypervisor = new Hypervisor(node.dag) |
68 | hypervisor.registerContainer('test', testVMContainer) |
69 | |
70 | const root = await hypervisor.createInstance('test') |
71 | const [portRef1, portRef2] = root.ports.createChannel() |
72 | |
73 | root.ports.bind('one', portRef1) |
74 | root.createInstance('test', root.createMessage({ |
75 | ports: [portRef2] |
76 | })) |
77 | |
78 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
79 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
80 | }) |
81 | |
82 | tape('one child contract with saturated ports', async t => { |
83 | t.plan(2) |
84 | let message |
85 | const expectedState = { |
86 | '/': 'zdpuAtVcH6MUnvt2RXnLsDXyLB3CBSQ7aydfh2ogSKGCejJCQ' |
87 | } |
88 | |
89 | class testVMContainer2 extends BaseContainer { |
90 | run (m) { |
91 | t.true(m === message, 'should recive a message') |
92 | } |
93 | } |
94 | |
95 | class testVMContainer extends BaseContainer { |
96 | run (m) { |
97 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
98 | this.kernel.createInstance('test2', this.kernel.createMessage({ |
99 | ports: [portRef2] |
100 | })) |
101 | this.kernel.ports.bind('child', portRef1) |
102 | this.kernel.incrementTicks(2) |
103 | this.kernel.send(portRef1, m) |
104 | } |
105 | } |
106 | |
107 | const hypervisor = new Hypervisor(node.dag) |
108 | hypervisor.registerContainer('test', testVMContainer) |
109 | hypervisor.registerContainer('test2', testVMContainer2) |
110 | |
111 | const root = await hypervisor.createInstance('test') |
112 | const [portRef1, portRef2] = root.ports.createChannel() |
113 | root.createInstance('test', root.createMessage({ |
114 | ports: [portRef2] |
115 | })) |
116 | |
117 | root.ports.bind('first', portRef1) |
118 | message = root.createMessage({ |
119 | data: 'test' |
120 | }) |
121 | |
122 | root.send(portRef1, message) |
123 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
124 | t.deepEquals(stateRoot, expectedState, 'expected state') |
125 | }) |
126 | |
127 | tape('one child contract', async t => { |
128 | t.plan(4) |
129 | let message |
130 | const expectedState = { |
131 | '/': 'zdpuAtVcH6MUnvt2RXnLsDXyLB3CBSQ7aydfh2ogSKGCejJCQ' |
132 | } |
133 | let hasResolved = false |
134 | |
135 | class testVMContainer2 extends BaseContainer { |
136 | run (m) { |
137 | t.true(m === message, 'should recive a message') |
138 | return new Promise((resolve, reject) => { |
139 | setTimeout(() => { |
140 | this.kernel.incrementTicks(1) |
141 | hasResolved = true |
142 | resolve() |
143 | }, 200) |
144 | }) |
145 | } |
146 | } |
147 | |
148 | class testVMContainer extends BaseContainer { |
149 | run (m) { |
150 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
151 | this.kernel.createInstance('test2', this.kernel.createMessage({ |
152 | ports: [portRef2] |
153 | })) |
154 | this.kernel.ports.bind('child', portRef1) |
155 | this.kernel.send(portRef1, m) |
156 | this.kernel.incrementTicks(1) |
157 | } |
158 | } |
159 | |
160 | const hypervisor = new Hypervisor(node.dag) |
161 | hypervisor.registerContainer('test', testVMContainer) |
162 | hypervisor.registerContainer('test2', testVMContainer2) |
163 | |
164 | let root = await hypervisor.createInstance('test') |
165 | const rootId = root.id |
166 | const [portRef1, portRef2] = root.ports.createChannel() |
167 | root.createInstance('test', root.createMessage({ |
168 | ports: [portRef2] |
169 | })) |
170 | |
171 | root.ports.bind('first', portRef1) |
172 | message = root.createMessage() |
173 | |
174 | root.send(portRef1, message) |
175 | const stateRoot = await hypervisor.createStateRoot(Infinity) |
176 | t.true(hasResolved, 'should resolve before generating the state root') |
177 | t.deepEquals(stateRoot, expectedState, 'expected state') |
178 | |
179 | // test reviving the state |
180 | class testVMContainer3 extends BaseContainer { |
181 | run (m) { |
182 | const port = this.kernel.ports.get('child') |
183 | this.kernel.send(port, m) |
184 | this.kernel.incrementTicks(1) |
185 | } |
186 | } |
187 | |
188 | hypervisor.registerContainer('test', testVMContainer3) |
189 | root = await hypervisor.getInstance(rootId) |
190 | const port = root.ports.get('first') |
191 | root.send(port, message) |
192 | }) |
193 | |
194 | tape('traps', async t => { |
195 | t.plan(1) |
196 | class Root extends BaseContainer { |
197 | async run (m) { |
198 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
199 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
200 | const [portRef5, portRef6] = this.kernel.ports.createChannel() |
201 | |
202 | this.kernel.ports.bind('one', portRef1) |
203 | this.kernel.ports.bind('two', portRef3) |
204 | this.kernel.ports.bind('three', portRef5) |
205 | |
206 | const message1 = this.kernel.createMessage({ |
207 | ports: [portRef2] |
208 | }) |
209 | const message2 = this.kernel.createMessage({ |
210 | ports: [portRef4] |
211 | }) |
212 | const message3 = this.kernel.createMessage({ |
213 | ports: [portRef6] |
214 | }) |
215 | |
216 | this.kernel.createInstance('root', message1) |
217 | this.kernel.createInstance('root', message2) |
218 | this.kernel.createInstance('root', message3) |
219 | |
220 | throw new Error('it is a trap!!!') |
221 | } |
222 | } |
223 | |
224 | const hypervisor = new Hypervisor(node.dag) |
225 | |
226 | hypervisor.registerContainer('root', Root) |
227 | const root = await hypervisor.createInstance('root') |
228 | await root.run(root.createMessage()) |
229 | const stateRoot = await hypervisor.createStateRoot() |
230 | |
231 | t.deepEquals(stateRoot, { |
232 | '/': 'zdpuAwrMmQXqFusve7zcRYxVUuji4NVzZR5GyjwyStsjteCoW' |
233 | }, 'should revert the state') |
234 | }) |
235 | |
236 | tape('message should arrive in the correct oder if sent in order', async t => { |
237 | t.plan(2) |
238 | let runs = 0 |
239 | |
240 | class Root extends BaseContainer { |
241 | run (m) { |
242 | if (!runs) { |
243 | runs++ |
244 | |
245 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
246 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
247 | |
248 | this.kernel.ports.bind('two', portRef3) |
249 | this.kernel.ports.bind('one', portRef1) |
250 | |
251 | const message1 = this.kernel.createMessage({ |
252 | ports: [portRef2] |
253 | }) |
254 | const message2 = this.kernel.createMessage({ |
255 | ports: [portRef4] |
256 | }) |
257 | |
258 | this.kernel.createInstance('first', message1) |
259 | this.kernel.createInstance('second', message2) |
260 | |
261 | this.kernel.send(portRef1, this.kernel.createMessage()) |
262 | this.kernel.send(portRef3, this.kernel.createMessage()) |
263 | } else if (runs === 1) { |
264 | runs++ |
265 | t.equals(m.data, 'first', 'should recive the first message') |
266 | } else if (runs === 2) { |
267 | t.equals(m.data, 'second', 'should recived the second message') |
268 | } |
269 | } |
270 | } |
271 | |
272 | class First extends BaseContainer { |
273 | run (m) { |
274 | this.kernel.incrementTicks(2) |
275 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
276 | data: 'first' |
277 | })) |
278 | } |
279 | } |
280 | |
281 | class Second extends BaseContainer { |
282 | run (m) { |
283 | this.kernel.incrementTicks(3) |
284 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
285 | data: 'second' |
286 | })) |
287 | } |
288 | } |
289 | |
290 | const hypervisor = new Hypervisor(node.dag) |
291 | |
292 | hypervisor.registerContainer('root', Root) |
293 | hypervisor.registerContainer('first', First) |
294 | hypervisor.registerContainer('second', Second) |
295 | |
296 | const root = await hypervisor.createInstance('root') |
297 | |
298 | const [portRef1, portRef2] = root.ports.createChannel() |
299 | root.createInstance('root', root.createMessage({ |
300 | ports: [portRef2] |
301 | })) |
302 | |
303 | root.ports.bind('first', portRef1) |
304 | const message = root.createMessage() |
305 | root.send(portRef1, message) |
306 | }) |
307 | |
308 | tape('message should arrive in the correct oder if sent in order', async t => { |
309 | t.plan(2) |
310 | let runs = 0 |
311 | |
312 | class Root extends BaseContainer { |
313 | run (m) { |
314 | if (!runs) { |
315 | runs++ |
316 | |
317 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
318 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
319 | |
320 | this.kernel.ports.bind('one', portRef1) |
321 | this.kernel.ports.bind('two', portRef3) |
322 | |
323 | const message1 = this.kernel.createMessage({ |
324 | ports: [portRef2] |
325 | }) |
326 | const message2 = this.kernel.createMessage({ |
327 | ports: [portRef4] |
328 | }) |
329 | |
330 | this.kernel.createInstance('first', message1) |
331 | this.kernel.createInstance('second', message2) |
332 | |
333 | this.kernel.send(portRef1, this.kernel.createMessage()) |
334 | this.kernel.send(portRef3, this.kernel.createMessage()) |
335 | } else if (runs === 1) { |
336 | runs++ |
337 | t.equals(m.data, 'second', 'should recived the second message') |
338 | } else if (runs === 2) { |
339 | t.equals(m.data, 'first', 'should recive the first message') |
340 | } |
341 | } |
342 | } |
343 | |
344 | class First extends BaseContainer { |
345 | run (m) { |
346 | this.kernel.incrementTicks(2) |
347 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
348 | data: 'first' |
349 | })) |
350 | } |
351 | } |
352 | |
353 | class Second extends BaseContainer { |
354 | run (m) { |
355 | this.kernel.incrementTicks(1) |
356 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
357 | data: 'second' |
358 | })) |
359 | } |
360 | } |
361 | |
362 | const hypervisor = new Hypervisor(node.dag) |
363 | |
364 | hypervisor.registerContainer('root', Root) |
365 | hypervisor.registerContainer('first', First) |
366 | hypervisor.registerContainer('second', Second) |
367 | |
368 | const root = await hypervisor.createInstance('root') |
369 | |
370 | const [portRef1, portRef2] = root.ports.createChannel() |
371 | root.createInstance('root', root.createMessage({ |
372 | ports: [portRef2] |
373 | })) |
374 | |
375 | root.ports.bind('first', portRef1) |
376 | const message = root.createMessage() |
377 | root.send(portRef1, message) |
378 | }) |
379 | |
380 | tape('message should arrive in the correct oder if sent in order', async t => { |
381 | t.plan(2) |
382 | let runs = 0 |
383 | |
384 | class Root extends BaseContainer { |
385 | run (m) { |
386 | if (!runs) { |
387 | runs++ |
388 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
389 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
390 | |
391 | this.kernel.ports.bind('one', portRef1) |
392 | this.kernel.ports.bind('two', portRef3) |
393 | |
394 | const message1 = this.kernel.createMessage({ |
395 | ports: [portRef2] |
396 | }) |
397 | const message2 = this.kernel.createMessage({ |
398 | ports: [portRef4] |
399 | }) |
400 | |
401 | this.kernel.createInstance('first', message1) |
402 | this.kernel.createInstance('second', message2) |
403 | |
404 | this.kernel.send(portRef1, this.kernel.createMessage()) |
405 | this.kernel.send(portRef3, this.kernel.createMessage()) |
406 | |
407 | this.kernel.incrementTicks(6) |
408 | } else if (runs === 1) { |
409 | runs++ |
410 | t.equals(m.data, 'first', 'should recive the first message') |
411 | } else if (runs === 2) { |
412 | t.equals(m.data, 'second', 'should recived the second message') |
413 | } |
414 | } |
415 | } |
416 | |
417 | class First extends BaseContainer { |
418 | run (m) { |
419 | this.kernel.incrementTicks(1) |
420 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
421 | data: 'first' |
422 | })) |
423 | } |
424 | } |
425 | |
426 | class Second extends BaseContainer { |
427 | run (m) { |
428 | this.kernel.incrementTicks(2) |
429 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
430 | data: 'second' |
431 | })) |
432 | } |
433 | } |
434 | |
435 | const hypervisor = new Hypervisor(node.dag) |
436 | |
437 | hypervisor.registerContainer('root', Root) |
438 | hypervisor.registerContainer('first', First) |
439 | hypervisor.registerContainer('second', Second) |
440 | |
441 | const root = await hypervisor.createInstance('root') |
442 | const [portRef1, portRef2] = root.ports.createChannel() |
443 | root.createInstance('root', root.createMessage({ |
444 | ports: [portRef2] |
445 | })) |
446 | |
447 | root.ports.bind('first', portRef1) |
448 | const message = root.createMessage() |
449 | root.send(portRef1, message) |
450 | }) |
451 | |
452 | tape('saturation', async t => { |
453 | t.plan(2) |
454 | let runs = 0 |
455 | |
456 | class Root extends BaseContainer { |
457 | run (m) { |
458 | if (!runs) { |
459 | runs++ |
460 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
461 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
462 | |
463 | this.kernel.ports.bind('one', portRef1) |
464 | this.kernel.ports.bind('two', portRef3) |
465 | |
466 | const message1 = this.kernel.createMessage({ |
467 | ports: [portRef2] |
468 | }) |
469 | const message2 = this.kernel.createMessage({ |
470 | ports: [portRef4] |
471 | }) |
472 | |
473 | this.kernel.createInstance('first', message1) |
474 | this.kernel.createInstance('second', message2) |
475 | |
476 | this.kernel.send(portRef1, this.kernel.createMessage()) |
477 | this.kernel.send(portRef3, this.kernel.createMessage()) |
478 | |
479 | this.kernel.incrementTicks(6) |
480 | } else if (runs === 1) { |
481 | runs++ |
482 | t.equals(m.data, 'first', 'should recive the first message') |
483 | } else if (runs === 2) { |
484 | runs++ |
485 | t.equals(m.data, 'second', 'should recived the second message') |
486 | } |
487 | } |
488 | } |
489 | |
490 | class First extends BaseContainer { |
491 | run (m) { |
492 | this.kernel.incrementTicks(2) |
493 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
494 | data: 'first' |
495 | })) |
496 | } |
497 | } |
498 | |
499 | class Second extends BaseContainer { |
500 | run (m) { |
501 | this.kernel.incrementTicks(3) |
502 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
503 | data: 'second' |
504 | })) |
505 | } |
506 | } |
507 | |
508 | class Waiter extends BaseContainer { |
509 | initialize () { |
510 | return new Promise((resolve, reject) => { |
511 | setTimeout(() => { |
512 | resolve() |
513 | }, 200) |
514 | }) |
515 | } |
516 | } |
517 | |
518 | const hypervisor = new Hypervisor(node.dag) |
519 | |
520 | hypervisor.registerContainer('root', Root) |
521 | hypervisor.registerContainer('first', First) |
522 | hypervisor.registerContainer('second', Second) |
523 | hypervisor.registerContainer('waiter', Waiter) |
524 | |
525 | const root = await hypervisor.createInstance('root') |
526 | const [portRef1, portRef2] = root.ports.createChannel() |
527 | |
528 | const message = root.createMessage() |
529 | root.send(portRef1, message) |
530 | root.ports.bind('first', portRef1) |
531 | root.createInstance('root', root.createMessage({ |
532 | ports: [portRef2] |
533 | })) |
534 | |
535 | const [portRef3, portRef4] = root.ports.createChannel() |
536 | root.ports.bind('sencond', portRef3) |
537 | root.createInstance('waiter', root.createMessage({ |
538 | ports: [portRef4] |
539 | })) |
540 | |
541 | root.incrementTicks(100) |
542 | root.send(portRef1, root.createMessage({data: 'testss'})) |
543 | hypervisor.scheduler.done(root.id) |
544 | }) |
545 | |
546 | tape('message should arrive in the correct order, even in a tie of ticks', async t => { |
547 | t.plan(2) |
548 | |
549 | let runs = 0 |
550 | |
551 | class Root extends BaseContainer { |
552 | run (m) { |
553 | if (!runs) { |
554 | runs++ |
555 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
556 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
557 | |
558 | this.kernel.ports.bind('two', portRef3) |
559 | this.kernel.ports.bind('one', portRef1) |
560 | |
561 | const message1 = this.kernel.createMessage({ |
562 | ports: [portRef2] |
563 | }) |
564 | const message2 = this.kernel.createMessage({ |
565 | ports: [portRef4] |
566 | }) |
567 | |
568 | this.kernel.createInstance('first', message1) |
569 | this.kernel.createInstance('second', message2) |
570 | |
571 | this.kernel.send(portRef1, this.kernel.createMessage()) |
572 | this.kernel.send(portRef3, this.kernel.createMessage()) |
573 | |
574 | this.kernel.incrementTicks(6) |
575 | } else if (runs === 1) { |
576 | runs++ |
577 | t.equals(m.data, 'second', 'should recived the second message') |
578 | } else if (runs === 2) { |
579 | t.equals(m.data, 'first', 'should recive the first message') |
580 | } |
581 | } |
582 | } |
583 | |
584 | class First extends BaseContainer { |
585 | run (m) { |
586 | this.kernel.incrementTicks(2) |
587 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
588 | data: 'first' |
589 | })) |
590 | } |
591 | } |
592 | |
593 | class Second extends BaseContainer { |
594 | run (m) { |
595 | this.kernel.incrementTicks(2) |
596 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
597 | data: 'second' |
598 | })) |
599 | } |
600 | } |
601 | |
602 | const hypervisor = new Hypervisor(node.dag) |
603 | |
604 | hypervisor.registerContainer('root', Root) |
605 | hypervisor.registerContainer('first', First) |
606 | hypervisor.registerContainer('second', Second) |
607 | |
608 | const root = await hypervisor.createInstance('root') |
609 | const [portRef1, portRef2] = root.ports.createChannel() |
610 | const message = root.createMessage() |
611 | |
612 | root.send(portRef1, message) |
613 | root.ports.bind('first', portRef1) |
614 | root.createInstance('root', root.createMessage({ |
615 | ports: [portRef2] |
616 | })) |
617 | }) |
618 | |
619 | tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => { |
620 | t.plan(2) |
621 | |
622 | let runs = 0 |
623 | |
624 | class Root extends BaseContainer { |
625 | run (m) { |
626 | if (!runs) { |
627 | runs++ |
628 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
629 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
630 | |
631 | this.kernel.ports.bind('one', portRef1) |
632 | this.kernel.ports.bind('two', portRef3) |
633 | |
634 | const message1 = this.kernel.createMessage({ |
635 | ports: [portRef2] |
636 | }) |
637 | const message2 = this.kernel.createMessage({ |
638 | ports: [portRef4] |
639 | }) |
640 | |
641 | this.kernel.createInstance('first', message1) |
642 | this.kernel.createInstance('second', message2) |
643 | |
644 | this.kernel.send(portRef1, this.kernel.createMessage()) |
645 | this.kernel.send(portRef3, this.kernel.createMessage()) |
646 | |
647 | this.kernel.incrementTicks(6) |
648 | } else if (runs === 1) { |
649 | runs++ |
650 | t.equals(m.data, 'first', 'should recive the first message') |
651 | } else if (runs === 2) { |
652 | t.equals(m.data, 'second', 'should recived the second message') |
653 | } |
654 | } |
655 | } |
656 | |
657 | class First extends BaseContainer { |
658 | run (m) { |
659 | this.kernel.incrementTicks(2) |
660 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
661 | data: 'first' |
662 | })) |
663 | } |
664 | } |
665 | |
666 | class Second extends BaseContainer { |
667 | run (m) { |
668 | this.kernel.incrementTicks(2) |
669 | this.kernel.send(m.fromPort, this.kernel.createMessage({ |
670 | data: 'second' |
671 | })) |
672 | } |
673 | } |
674 | |
675 | const hypervisor = new Hypervisor(node.dag) |
676 | |
677 | hypervisor.registerContainer('root', Root) |
678 | hypervisor.registerContainer('first', First) |
679 | hypervisor.registerContainer('second', Second) |
680 | |
681 | const root = await hypervisor.createInstance('root') |
682 | const [portRef1, portRef2] = root.ports.createChannel() |
683 | const message = root.createMessage() |
684 | |
685 | root.send(portRef1, message) |
686 | root.ports.bind('first', portRef1) |
687 | root.createInstance('root', root.createMessage({ |
688 | ports: [portRef2] |
689 | })) |
690 | }) |
691 | |
692 | tape('send to the same container at the same time', async t => { |
693 | t.plan(2) |
694 | |
695 | let runs = 0 |
696 | let instance |
697 | |
698 | class Root extends BaseContainer { |
699 | run (m) { |
700 | let one = this.kernel.ports.get('one') |
701 | if (!one) { |
702 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
703 | this.kernel.ports.bind('one', portRef1) |
704 | const message1 = this.kernel.createMessage({ |
705 | ports: [portRef2] |
706 | }) |
707 | this.kernel.createInstance('first', message1) |
708 | } else { |
709 | this.kernel.send(one, this.kernel.createMessage()) |
710 | this.kernel.send(one, this.kernel.createMessage()) |
711 | } |
712 | } |
713 | } |
714 | |
715 | class First extends BaseContainer { |
716 | run (m) { |
717 | ++runs |
718 | if (runs === 2) { |
719 | t.equals(instance, this, 'should have same instances') |
720 | } else { |
721 | instance = this |
722 | } |
723 | } |
724 | } |
725 | |
726 | const hypervisor = new Hypervisor(node.dag) |
727 | |
728 | hypervisor.registerContainer('root', Root) |
729 | hypervisor.registerContainer('first', First) |
730 | |
731 | const root = await hypervisor.createInstance('root') |
732 | const [portRef1, portRef2] = root.ports.createChannel() |
733 | root.ports.bind('first', portRef1) |
734 | root.createInstance('root', root.createMessage({ |
735 | ports: [portRef2] |
736 | })) |
737 | |
738 | const message = root.createMessage() |
739 | root.send(portRef1, message) |
740 | await hypervisor.createStateRoot() |
741 | root.send(portRef1, root.createMessage()) |
742 | await hypervisor.createStateRoot() |
743 | t.equals(runs, 2) |
744 | }) |
745 | |
746 | tape('checking ports', async t => { |
747 | t.plan(4) |
748 | const hypervisor = new Hypervisor(node.dag) |
749 | hypervisor.registerContainer('base', BaseContainer) |
750 | |
751 | const root = await hypervisor.createInstance('base') |
752 | |
753 | const [portRef1, portRef2] = root.ports.createChannel() |
754 | root.createInstance('base', root.createMessage({ |
755 | ports: [portRef2] |
756 | })) |
757 | root.ports.bind('test', portRef1) |
758 | |
759 | try { |
760 | root.createMessage({ |
761 | ports: [portRef1] |
762 | }) |
763 | } catch (e) { |
764 | t.pass('should thow if sending a port that is bound') |
765 | } |
766 | |
767 | try { |
768 | await root.ports.bind('test', portRef1) |
769 | } catch (e) { |
770 | t.pass('should thow if binding an already bound port') |
771 | } |
772 | |
773 | try { |
774 | const [portRef3] = root.ports.createChannel() |
775 | await root.ports.bind('test', portRef3) |
776 | } catch (e) { |
777 | t.pass('should thow if binding an already bound name') |
778 | } |
779 | |
780 | await root.ports.unbind('test') |
781 | const message = root.createMessage({ |
782 | ports: [portRef1] |
783 | }) |
784 | t.equals(message.ports[0], portRef1, 'should create a message if the port is unbound') |
785 | }) |
786 | |
787 | tape('port deletion', async t => { |
788 | const expectedSr = { |
789 | '/': 'zdpuB2QXxn1KQtLFfBqaritTRoe5BuKP5sNFSrPtRT6sxkY7Z' |
790 | } |
791 | class Root extends BaseContainer { |
792 | run (m) { |
793 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
794 | this.kernel.ports.bind('one', portRef1) |
795 | const message1 = this.kernel.createMessage({ |
796 | ports: [portRef2] |
797 | }) |
798 | |
799 | this.kernel.createInstance('first', message1) |
800 | this.kernel.send(portRef1, this.kernel.createMessage()) |
801 | this.kernel.incrementTicks(6) |
802 | } |
803 | } |
804 | |
805 | class First extends BaseContainer { |
806 | run (m) { |
807 | this.kernel.incrementTicks(2) |
808 | this.kernel.ports.delete('root') |
809 | } |
810 | } |
811 | |
812 | const hypervisor = new Hypervisor(node.dag) |
813 | |
814 | hypervisor.registerContainer('root', Root) |
815 | hypervisor.registerContainer('first', First) |
816 | |
817 | const root = await hypervisor.createInstance('root') |
818 | const [portRef1, portRef2] = root.ports.createChannel() |
819 | root.ports.bind('first', portRef1) |
820 | root.createInstance('root', root.createMessage({ |
821 | ports: [portRef2] |
822 | })) |
823 | |
824 | const message = root.createMessage() |
825 | root.send(portRef1, message) |
826 | |
827 | const sr = await hypervisor.createStateRoot() |
828 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
829 | |
830 | t.end() |
831 | }) |
832 | |
833 | tape('clear unbounded ports', async t => { |
834 | const expectedSr = { |
835 | '/': 'zdpuB2QXxn1KQtLFfBqaritTRoe5BuKP5sNFSrPtRT6sxkY7Z' |
836 | } |
837 | class Root extends BaseContainer { |
838 | run (m) { |
839 | this.kernel.createInstance('root') |
840 | } |
841 | } |
842 | |
843 | const hypervisor = new Hypervisor(node.dag) |
844 | |
845 | hypervisor.registerContainer('root', Root) |
846 | |
847 | const root = await hypervisor.createInstance('root') |
848 | const [portRef1, portRef2] = root.ports.createChannel() |
849 | root.ports.bind('first', portRef1) |
850 | root.createInstance('root', root.createMessage({ |
851 | ports: [portRef2] |
852 | })) |
853 | |
854 | const message = root.createMessage() |
855 | root.send(portRef1, message) |
856 | const sr = await hypervisor.createStateRoot() |
857 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
858 | |
859 | t.end() |
860 | }) |
861 | |
862 | tape('should remove subgraphs', async t => { |
863 | const expectedSr = { |
864 | '/': 'zdpuB2QXxn1KQtLFfBqaritTRoe5BuKP5sNFSrPtRT6sxkY7Z' |
865 | } |
866 | class Root extends BaseContainer { |
867 | run (m) { |
868 | const [, portRef2] = this.kernel.ports.createChannel() |
869 | this.kernel.createInstance('sub', this.kernel.createMessage({ |
870 | ports: [portRef2] |
871 | })) |
872 | } |
873 | } |
874 | |
875 | class Sub extends BaseContainer { |
876 | initailize (message) { |
877 | this.kernel.ports.bind('root', message.ports[0]) |
878 | const [portRef1, portRef2] = root.ports.createChannel() |
879 | root.ports.bind('child', portRef1) |
880 | root.createInstance('root', root.createMessage({ |
881 | ports: [portRef2] |
882 | })) |
883 | } |
884 | } |
885 | |
886 | const hypervisor = new Hypervisor(node.dag) |
887 | |
888 | hypervisor.registerContainer('root', Root) |
889 | hypervisor.registerContainer('sub', Sub) |
890 | |
891 | const root = await hypervisor.createInstance('root') |
892 | const [portRef1, portRef2] = root.ports.createChannel() |
893 | root.ports.bind('first', portRef1) |
894 | root.createInstance('root', root.createMessage({ |
895 | ports: [portRef2] |
896 | })) |
897 | |
898 | root.send(portRef1, root.createMessage()) |
899 | const sr = await hypervisor.createStateRoot() |
900 | |
901 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
902 | t.end() |
903 | }) |
904 | |
905 | tape('should not remove connected nodes', async t => { |
906 | const expectedSr = { |
907 | '/': 'zdpuAwsZTd5mRZBCYA1FJSHrpYDPgSZSiaTQp9xkUeajaoMHM' |
908 | } |
909 | class Root extends BaseContainer { |
910 | run (m) { |
911 | if (m.ports.length) { |
912 | const port = this.kernel.ports.get('test1') |
913 | this.kernel.send(port, m) |
914 | this.kernel.ports.unbind('test1') |
915 | } else { |
916 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
917 | this.kernel.createInstance('sub', this.kernel.createMessage({ |
918 | ports: [portRef2] |
919 | })) |
920 | this.kernel.ports.bind('test1', portRef1) |
921 | |
922 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
923 | this.kernel.createInstance('sub', this.kernel.createMessage({ |
924 | ports: [portRef4] |
925 | })) |
926 | this.kernel.ports.bind('test2', portRef3) |
927 | this.kernel.send(portRef3, this.kernel.createMessage({ |
928 | data: 'getChannel' |
929 | })) |
930 | } |
931 | } |
932 | } |
933 | |
934 | class Sub extends BaseContainer { |
935 | run (message) { |
936 | if (message.data === 'getChannel') { |
937 | const ports = this.kernel.ports.createChannel() |
938 | this.kernel.ports.bind('channel', ports[0]) |
939 | this.kernel.send(message.fromPort, this.kernel.createMessage({ |
940 | data: 'bindPort', |
941 | ports: [ports[1]] |
942 | })) |
943 | } else if (message.data === 'bindPort') { |
944 | this.kernel.ports.bind('channel', message.ports[0]) |
945 | } |
946 | } |
947 | } |
948 | |
949 | const hypervisor = new Hypervisor(node.dag) |
950 | |
951 | hypervisor.registerContainer('root', Root) |
952 | hypervisor.registerContainer('sub', Sub) |
953 | |
954 | const root = await hypervisor.createInstance('root') |
955 | const [portRef1, portRef2] = root.ports.createChannel() |
956 | root.ports.bind('first', portRef1) |
957 | root.createInstance('root', root.createMessage({ |
958 | ports: [portRef2] |
959 | })) |
960 | |
961 | root.send(portRef1, root.createMessage()) |
962 | const sr = await hypervisor.createStateRoot() |
963 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
964 | // await hypervisor.graph.tree(sr, Infinity) |
965 | |
966 | t.end() |
967 | }) |
968 | |
969 | tape('should remove multiple subgraphs', async t => { |
970 | const expectedSr = { |
971 | '/': 'zdpuAmi9tkYTpoVsZvqQgxpQFRhCgYFVv4W3fjjfVhf1j8swv' |
972 | } |
973 | class Root extends BaseContainer { |
974 | run (m) { |
975 | if (m.ports.length) { |
976 | const port = this.kernel.ports.get('test1') |
977 | this.kernel.send(port, m) |
978 | this.kernel.ports.unbind('test1') |
979 | this.kernel.ports.unbind('test2') |
980 | } else { |
981 | const [portRef1, portRef2] = this.kernel.ports.createChannel() |
982 | this.kernel.createInstance('sub', this.kernel.createMessage({ |
983 | ports: [portRef2] |
984 | })) |
985 | this.kernel.ports.bind('test1', portRef1) |
986 | |
987 | const [portRef3, portRef4] = this.kernel.ports.createChannel() |
988 | this.kernel.createInstance('sub', this.kernel.createMessage({ |
989 | ports: [portRef4] |
990 | })) |
991 | this.kernel.ports.bind('test2', portRef3) |
992 | this.kernel.send(portRef3, this.kernel.createMessage({ |
993 | data: 'getChannel' |
994 | })) |
995 | } |
996 | } |
997 | } |
998 | |
999 | class Sub extends BaseContainer { |
1000 | run (message) { |
1001 | if (message.data === 'getChannel') { |
1002 | const ports = this.kernel.ports.createChannel() |
1003 | this.kernel.ports.bind('channel', ports[0]) |
1004 | this.kernel.send(message.fromPort, this.kernel.createMessage({ |
1005 | data: 'bindPort', |
1006 | ports: [ports[1]] |
1007 | })) |
1008 | } else if (message.data === 'bindPort') { |
1009 | this.kernel.ports.bind('channel', message.ports[0]) |
1010 | } |
1011 | } |
1012 | } |
1013 | |
1014 | const hypervisor = new Hypervisor(node.dag) |
1015 | |
1016 | hypervisor.registerContainer('root', Root) |
1017 | hypervisor.registerContainer('sub', Sub) |
1018 | |
1019 | const root = await hypervisor.createInstance('root') |
1020 | |
1021 | const [portRef1, portRef2] = root.ports.createChannel() |
1022 | root.ports.bind('first', portRef1) |
1023 | root.createInstance('root', root.createMessage({ |
1024 | ports: [portRef2] |
1025 | })) |
1026 | |
1027 | root.send(portRef1, root.createMessage()) |
1028 | |
1029 | const sr = await hypervisor.createStateRoot() |
1030 | t.deepEquals(sr, expectedSr, 'should produce the corret state root') |
1031 | |
1032 | t.end() |
1033 | }) |
1034 | |
1035 | tape('response ports', async t => { |
1036 | t.plan(2) |
1037 | let runs = 0 |
1038 | const returnValue = 'this is a test' |
1039 | |
1040 | class testVMContainer extends BaseContainer { |
1041 | run (m) { |
1042 | runs++ |
1043 | if (runs === 1) { |
1044 | return returnValue |
1045 | } else { |
1046 | t.equals(m.data, returnValue, 'should have correct return value') |
1047 | } |
1048 | } |
1049 | } |
1050 | |
1051 | const hypervisor = new Hypervisor(node.dag) |
1052 | |
1053 | hypervisor.registerContainer('test', testVMContainer) |
1054 | |
1055 | const rootContainer = await hypervisor.createInstance('test') |
1056 | |
1057 | const [portRef1, portRef2] = rootContainer.ports.createChannel() |
1058 | const initMessage = rootContainer.createMessage({ |
1059 | ports: [portRef2] |
1060 | }) |
1061 | |
1062 | rootContainer.createInstance('test', initMessage) |
1063 | |
1064 | rootContainer.ports.bind('first', portRef1) |
1065 | const message = rootContainer.createMessage() |
1066 | const rPort = rootContainer.getResponsePort(message) |
1067 | const rPort2 = rootContainer.getResponsePort(message) |
1068 | |
1069 | t.equals(rPort2, rPort) |
1070 | |
1071 | rootContainer.send(portRef1, message) |
1072 | rootContainer.ports.bind('response', rPort) |
1073 | }) |
1074 | }) |
1075 |
Built with git-ssb-web