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