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