Files: 2306af1727ce5851183891346923734523247981 / tests / index.js
17355 bytesRaw
1 | const tape = require('tape') |
2 | const IPFS = require('ipfs') |
3 | const Hypervisor = require('../') |
4 | const Message = require('primea-message') |
5 | |
6 | const node = new IPFS() |
7 | |
8 | class BaseContainer { |
9 | constructor (kernel) { |
10 | this.kernel = kernel |
11 | } |
12 | |
13 | static createState (code) { |
14 | return { |
15 | nonce: [0], |
16 | ports: {} |
17 | } |
18 | } |
19 | } |
20 | |
21 | node.on('error', err => { |
22 | console.log(err) |
23 | }) |
24 | |
25 | node.on('start', () => { |
26 | tape.onFinish(() => { |
27 | node.stop(() => { |
28 | process.exit() |
29 | }) |
30 | }) |
31 | |
32 | tape('basic', async t => { |
33 | t.plan(2) |
34 | const message = new Message() |
35 | const expectedState = { |
36 | '/': 'zdpuAntkdU7yBJojcBT5Q9wBhrK56NmLnwpHPKaEGMFnAXpv7' |
37 | } |
38 | |
39 | class testVMContainer extends BaseContainer { |
40 | run (m) { |
41 | t.true(m === message, 'should recive a message') |
42 | } |
43 | } |
44 | |
45 | const hypervisor = new Hypervisor({dag: node.dag}) |
46 | hypervisor.registerContainer('test', testVMContainer) |
47 | |
48 | const rootContainer = await hypervisor.createInstance('test') |
49 | const port = await rootContainer.ports.create('test', 'first') |
50 | |
51 | await rootContainer.send(port, message) |
52 | |
53 | const stateRoot = await hypervisor.createStateRoot(rootContainer, Infinity) |
54 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
55 | }) |
56 | |
57 | tape('one child contract', async t => { |
58 | t.plan(4) |
59 | let message = new Message() |
60 | const expectedState = { |
61 | '/': 'zdpuAofSzrBqwYs6z1r28fMeb8z5oSKF6CcWA6m22RqazgoTB' |
62 | } |
63 | let hasResolved = false |
64 | |
65 | class testVMContainer2 extends BaseContainer { |
66 | run (m) { |
67 | t.true(m === message, 'should recive a message 2') |
68 | return new Promise((resolve, reject) => { |
69 | setTimeout(() => { |
70 | this.kernel.incrementTicks(1) |
71 | hasResolved = true |
72 | resolve() |
73 | }, 200) |
74 | }) |
75 | } |
76 | } |
77 | |
78 | class testVMContainer extends BaseContainer { |
79 | async run (m) { |
80 | const port = await this.kernel.ports.create('test2', 'child') |
81 | await this.kernel.send(port, m) |
82 | this.kernel.incrementTicks(1) |
83 | } |
84 | } |
85 | |
86 | const hypervisor = new Hypervisor({dag: node.dag}) |
87 | hypervisor.registerContainer('test', testVMContainer) |
88 | hypervisor.registerContainer('test2', testVMContainer2) |
89 | |
90 | let root = await hypervisor.createInstance('test') |
91 | let port = await root.ports.create('test', 'first') |
92 | |
93 | await root.send(port, message) |
94 | const stateRoot = await hypervisor.createStateRoot(root, Infinity) |
95 | t.true(hasResolved, 'should resolve before generating the state root') |
96 | t.deepEquals(stateRoot, expectedState, 'expected state') |
97 | |
98 | // test reviving the state |
99 | class testVMContainer3 extends BaseContainer { |
100 | async run (m) { |
101 | const port = this.kernel.ports.get('child') |
102 | await this.kernel.send(port, m) |
103 | this.kernel.incrementTicks(1) |
104 | } |
105 | } |
106 | |
107 | hypervisor.registerContainer('test', testVMContainer3) |
108 | root = await hypervisor.createInstance('test', stateRoot) |
109 | port = await root.ports.get('first') |
110 | |
111 | await root.send(port, message) |
112 | }) |
113 | |
114 | tape('ping pong', async t => { |
115 | class Ping extends BaseContainer { |
116 | async run (m) { |
117 | let port = this.kernel.ports.get('child') |
118 | if (!port) { |
119 | port = await this.kernel.ports.create('pong', 'child') |
120 | } |
121 | |
122 | if (this.kernel.ticks < 100) { |
123 | this.kernel.incrementTicks(1) |
124 | return this.kernel.send(port, new Message()) |
125 | } |
126 | } |
127 | } |
128 | |
129 | class Pong extends BaseContainer { |
130 | run (m) { |
131 | const port = m.fromPort |
132 | this.kernel.incrementTicks(2) |
133 | return this.kernel.send(port, new Message()) |
134 | } |
135 | } |
136 | |
137 | const hypervisor = new Hypervisor({ |
138 | dag: node.dag |
139 | }) |
140 | |
141 | hypervisor.registerContainer('ping', Ping) |
142 | hypervisor.registerContainer('pong', Pong) |
143 | const root = await hypervisor.createInstance('pong') |
144 | const port = await root.ports.create('ping', 'child') |
145 | |
146 | await root.send(port, new Message()) |
147 | await hypervisor.createStateRoot(root, Infinity) |
148 | |
149 | t.end() |
150 | }) |
151 | |
152 | tape('queing multiple messages', async t => { |
153 | t.plan(2) |
154 | let runs = 0 |
155 | |
156 | class Root extends BaseContainer { |
157 | async run (m) { |
158 | const one = this.kernel.ports.create('child', 'one') |
159 | const two = this.kernel.ports.create('child', 'two') |
160 | const three = this.kernel.ports.create('child', 'three') |
161 | |
162 | await Promise.all([ |
163 | this.kernel.send(one, new Message()), |
164 | this.kernel.send(two, new Message()), |
165 | this.kernel.send(three, new Message()) |
166 | ]) |
167 | |
168 | return new Promise((resolve, reject) => { |
169 | setTimeout(() => { |
170 | this.kernel.incrementTicks(6) |
171 | resolve() |
172 | }, 200) |
173 | }) |
174 | } |
175 | } |
176 | |
177 | class Child extends BaseContainer { |
178 | run (m) { |
179 | runs++ |
180 | this.kernel.incrementTicks(2) |
181 | } |
182 | } |
183 | |
184 | const hypervisor = new Hypervisor({ |
185 | dag: node.dag |
186 | }) |
187 | |
188 | hypervisor.registerContainer('root', Root) |
189 | hypervisor.registerContainer('child', Child) |
190 | |
191 | const root = await hypervisor.createInstance('root') |
192 | const port = await root.ports.create('root', 'first') |
193 | await root.send(port, new Message()) |
194 | await root.wait(Infinity) |
195 | |
196 | t.equals(runs, 3, 'the number of run should be 3') |
197 | const nonce = await hypervisor.graph.get(root.state, 'ports/first/link/nonce/0') |
198 | t.equals(nonce, 3, 'should have the correct nonce') |
199 | }) |
200 | |
201 | tape('traps', async t => { |
202 | t.plan(1) |
203 | class Root extends BaseContainer { |
204 | async run (m) { |
205 | this.kernel.ports.create('root', 'one') |
206 | this.kernel.ports.create('root', 'two') |
207 | this.kernel.ports.create('root', 'three') |
208 | |
209 | throw new Error('it is a trap!!!') |
210 | } |
211 | } |
212 | |
213 | const hypervisor = new Hypervisor({ |
214 | dag: node.dag |
215 | }) |
216 | |
217 | hypervisor.registerContainer('root', Root) |
218 | const root = await hypervisor.createInstance('root') |
219 | await root.run() |
220 | |
221 | t.deepEquals(root.state, { |
222 | '/': { |
223 | nonce: [0], |
224 | ports: {} |
225 | } |
226 | }, 'should revert the state') |
227 | }) |
228 | |
229 | tape('invalid port referances', async t => { |
230 | t.plan(2) |
231 | class Root extends BaseContainer { |
232 | async run (m) { |
233 | const ports = this.kernel.ports.create('root', 'three') |
234 | this.kernel.ports.delete('three') |
235 | try { |
236 | await this.kernel.send(ports, new Message()) |
237 | } catch (e) { |
238 | t.pass() |
239 | } |
240 | } |
241 | } |
242 | |
243 | const hypervisor = new Hypervisor({ |
244 | dag: node.dag |
245 | }) |
246 | |
247 | hypervisor.registerContainer('root', Root) |
248 | const root = await hypervisor.createInstance('root') |
249 | await root.run() |
250 | |
251 | t.deepEquals(root.state, { |
252 | '/': { |
253 | nonce: [1], |
254 | ports: {} |
255 | } |
256 | }) |
257 | }) |
258 | |
259 | tape('message should arrive in the correct oder if sent in order', async t => { |
260 | t.plan(2) |
261 | |
262 | class Root extends BaseContainer { |
263 | async run (m) { |
264 | if (!this.runs) { |
265 | this.runs = 1 |
266 | const one = this.kernel.ports.create('first', 'one') |
267 | const two = this.kernel.ports.create('second', 'two') |
268 | |
269 | await Promise.all([ |
270 | this.kernel.send(one, new Message()), |
271 | this.kernel.send(two, new Message()) |
272 | ]) |
273 | |
274 | this.kernel.incrementTicks(6) |
275 | } else if (this.runs === 1) { |
276 | this.runs++ |
277 | t.equals(m.data, 'first', 'should recive the first message') |
278 | } else if (this.runs === 2) { |
279 | t.equals(m.data, 'second', 'should recived the second message') |
280 | } |
281 | } |
282 | } |
283 | |
284 | class First extends BaseContainer { |
285 | async run (m) { |
286 | this.kernel.incrementTicks(1) |
287 | await this.kernel.send(m.fromPort, new Message({data: 'first'})) |
288 | } |
289 | } |
290 | |
291 | class Second extends BaseContainer { |
292 | async run (m) { |
293 | this.kernel.incrementTicks(2) |
294 | await this.kernel.send(m.fromPort, new Message({data: 'second'})) |
295 | } |
296 | } |
297 | |
298 | const hypervisor = new Hypervisor({ |
299 | dag: node.dag |
300 | }) |
301 | |
302 | hypervisor.registerContainer('root', Root) |
303 | hypervisor.registerContainer('first', First) |
304 | hypervisor.registerContainer('second', Second) |
305 | |
306 | const root = await hypervisor.createInstance('root') |
307 | const port = await root.ports.create('root', 'first') |
308 | await root.send(port, new Message()) |
309 | }) |
310 | |
311 | tape('message should arrive in the correct order, even if sent out of order', async t => { |
312 | t.plan(2) |
313 | |
314 | class Root extends BaseContainer { |
315 | async run (m) { |
316 | if (!this.runs) { |
317 | this.runs = 1 |
318 | const one = this.kernel.ports.create('first', 'one') |
319 | const two = this.kernel.ports.create('second', 'two') |
320 | |
321 | await Promise.all([ |
322 | this.kernel.send(one, new Message()), |
323 | this.kernel.send(two, new Message()) |
324 | ]) |
325 | |
326 | this.kernel.incrementTicks(6) |
327 | } else if (this.runs === 1) { |
328 | this.runs++ |
329 | t.equals(m.data, 'second', 'should recive the first message') |
330 | } else if (this.runs === 2) { |
331 | t.equals(m.data, 'first', 'should recived the second message') |
332 | } |
333 | } |
334 | } |
335 | |
336 | class First extends BaseContainer { |
337 | async run (m) { |
338 | this.kernel.incrementTicks(2) |
339 | await this.kernel.send(m.fromPort, new Message({data: 'first'})) |
340 | } |
341 | } |
342 | |
343 | class Second extends BaseContainer { |
344 | async run (m) { |
345 | this.kernel.incrementTicks(1) |
346 | await this.kernel.send(m.fromPort, new Message({data: 'second'})) |
347 | } |
348 | } |
349 | |
350 | const hypervisor = new Hypervisor({ |
351 | dag: node.dag |
352 | }) |
353 | |
354 | hypervisor.registerContainer('root', Root) |
355 | hypervisor.registerContainer('first', First) |
356 | hypervisor.registerContainer('second', Second) |
357 | |
358 | const root = await hypervisor.createInstance('root') |
359 | const port = await root.ports.create('root', 'first') |
360 | await root.send(port, new Message()) |
361 | }) |
362 | |
363 | tape('message should arrive in the correct order, even in a tie of ticks', async t => { |
364 | t.plan(2) |
365 | |
366 | class Root extends BaseContainer { |
367 | async run (m) { |
368 | if (!this.runs) { |
369 | this.runs = 1 |
370 | const one = this.kernel.ports.create('first', 'one') |
371 | const two = this.kernel.ports.create('second', 'two') |
372 | |
373 | await Promise.all([ |
374 | this.kernel.send(one, new Message()), |
375 | this.kernel.send(two, new Message()) |
376 | ]) |
377 | |
378 | this.kernel.incrementTicks(6) |
379 | } else if (this.runs === 1) { |
380 | this.runs++ |
381 | t.equals(m.data, 'first', 'should recived the second message') |
382 | } else if (this.runs === 2) { |
383 | t.equals(m.data, 'second', 'should recive the first message') |
384 | } |
385 | } |
386 | } |
387 | |
388 | class First extends BaseContainer { |
389 | async run (m) { |
390 | this.kernel.incrementTicks(2) |
391 | await this.kernel.send(m.fromPort, new Message({data: 'first'})) |
392 | } |
393 | } |
394 | |
395 | class Second extends BaseContainer { |
396 | async run (m) { |
397 | this.kernel.incrementTicks(2) |
398 | await this.kernel.send(m.fromPort, new Message({data: 'second'})) |
399 | } |
400 | } |
401 | |
402 | const hypervisor = new Hypervisor({ |
403 | dag: node.dag |
404 | }) |
405 | |
406 | hypervisor.registerContainer('root', Root) |
407 | hypervisor.registerContainer('first', First) |
408 | hypervisor.registerContainer('second', Second) |
409 | |
410 | const root = await hypervisor.createInstance('root') |
411 | const port = await root.ports.create('root', 'first') |
412 | await root.send(port, new Message()) |
413 | }) |
414 | |
415 | tape('message should arrive in the correct order, even in a tie of ticks', async t => { |
416 | t.plan(2) |
417 | |
418 | class Root extends BaseContainer { |
419 | async run (m) { |
420 | if (!this.runs) { |
421 | this.runs = 1 |
422 | const two = this.kernel.ports.create('second', 'two') |
423 | const one = this.kernel.ports.create('first', 'one') |
424 | |
425 | await Promise.all([ |
426 | this.kernel.send(two, new Message()), |
427 | this.kernel.send(one, new Message()) |
428 | ]) |
429 | |
430 | this.kernel.incrementTicks(6) |
431 | } else if (this.runs === 1) { |
432 | this.runs++ |
433 | t.equals(m.data, 'first', 'should recived the second message') |
434 | } else if (this.runs === 2) { |
435 | t.equals(m.data, 'second', 'should recive the first message') |
436 | } |
437 | } |
438 | } |
439 | |
440 | class First extends BaseContainer { |
441 | async run (m) { |
442 | this.kernel.incrementTicks(2) |
443 | await this.kernel.send(m.fromPort, new Message({data: 'first'})) |
444 | } |
445 | } |
446 | |
447 | class Second extends BaseContainer { |
448 | async run (m) { |
449 | this.kernel.incrementTicks(2) |
450 | await this.kernel.send(m.fromPort, new Message({data: 'second'})) |
451 | } |
452 | } |
453 | |
454 | const hypervisor = new Hypervisor({ |
455 | dag: node.dag |
456 | }) |
457 | |
458 | hypervisor.registerContainer('root', Root) |
459 | hypervisor.registerContainer('first', First) |
460 | hypervisor.registerContainer('second', Second) |
461 | |
462 | const root = await hypervisor.createInstance('root') |
463 | const port = await root.ports.create('root', 'first') |
464 | await root.send(port, new Message()) |
465 | }) |
466 | |
467 | tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => { |
468 | t.plan(2) |
469 | |
470 | class Root extends BaseContainer { |
471 | async run (m) { |
472 | if (!this.runs) { |
473 | this.runs = 1 |
474 | const one = this.kernel.ports.create('first', 'one') |
475 | const two = this.kernel.ports.create('second', 'two') |
476 | |
477 | await Promise.all([ |
478 | this.kernel.send(two, new Message()), |
479 | this.kernel.send(one, new Message()) |
480 | ]) |
481 | |
482 | this.kernel.incrementTicks(6) |
483 | } else if (this.runs === 1) { |
484 | this.runs++ |
485 | t.equals(m.data, 'first', 'should recive the first message') |
486 | } else if (this.runs === 2) { |
487 | t.equals(m.data, 'second', 'should recived the second message') |
488 | } |
489 | } |
490 | } |
491 | |
492 | class First extends BaseContainer { |
493 | async run (m) { |
494 | this.kernel.incrementTicks(2) |
495 | await this.kernel.send(m.fromPort, new Message({ |
496 | resources: { |
497 | priority: 100 |
498 | }, |
499 | data: 'first' |
500 | })) |
501 | } |
502 | } |
503 | |
504 | class Second extends BaseContainer { |
505 | async run (m) { |
506 | this.kernel.incrementTicks(2) |
507 | await this.kernel.send(m.fromPort, new Message({data: 'second'})) |
508 | } |
509 | } |
510 | |
511 | const hypervisor = new Hypervisor({ |
512 | dag: node.dag |
513 | }) |
514 | |
515 | hypervisor.registerContainer('root', Root) |
516 | hypervisor.registerContainer('first', First) |
517 | hypervisor.registerContainer('second', Second) |
518 | |
519 | const root = await hypervisor.createInstance('root') |
520 | const port = await root.ports.create('root', 'first') |
521 | await root.send(port, new Message()) |
522 | }) |
523 | |
524 | tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => { |
525 | t.plan(2) |
526 | |
527 | class Root extends BaseContainer { |
528 | async run (m) { |
529 | if (!this.runs) { |
530 | this.runs = 1 |
531 | const one = this.kernel.ports.create('first', 'one') |
532 | const two = this.kernel.ports.create('second', 'two') |
533 | |
534 | await Promise.all([ |
535 | this.kernel.send(two, new Message()), |
536 | this.kernel.send(one, new Message()) |
537 | ]) |
538 | |
539 | this.kernel.incrementTicks(6) |
540 | } else if (this.runs === 1) { |
541 | this.runs++ |
542 | t.equals(m.data, 'second', 'should recive the first message') |
543 | } else if (this.runs === 2) { |
544 | t.equals(m.data, 'first', 'should recived the second message') |
545 | } |
546 | } |
547 | } |
548 | |
549 | class First extends BaseContainer { |
550 | async run (m) { |
551 | this.kernel.incrementTicks(2) |
552 | await this.kernel.send(m.fromPort, new Message({ |
553 | data: 'first' |
554 | })) |
555 | } |
556 | } |
557 | |
558 | class Second extends BaseContainer { |
559 | async run (m) { |
560 | this.kernel.incrementTicks(2) |
561 | await this.kernel.send(m.fromPort, new Message({ |
562 | resources: { |
563 | priority: 100 |
564 | }, |
565 | data: 'second' |
566 | })) |
567 | } |
568 | } |
569 | |
570 | const hypervisor = new Hypervisor({ |
571 | dag: node.dag |
572 | }) |
573 | |
574 | hypervisor.registerContainer('root', Root) |
575 | hypervisor.registerContainer('first', First) |
576 | hypervisor.registerContainer('second', Second) |
577 | |
578 | const root = await hypervisor.createInstance('root') |
579 | const port = await root.ports.create('root', 'first') |
580 | await root.send(port, new Message()) |
581 | }) |
582 | |
583 | tape('should order parent messages correctly', async t => { |
584 | t.plan(1) |
585 | class Middle extends BaseContainer { |
586 | async run (m) { |
587 | if (!this.runs) { |
588 | this.runs = 1 |
589 | this.kernel.incrementTicks(1) |
590 | const leaf = this.kernel.ports.create('leaf', 'leaf') |
591 | await this.kernel.send(leaf, new Message()) |
592 | } else { |
593 | ++this.runs |
594 | if (this.runs === 3) { |
595 | t.equals(m.data, 'first') |
596 | } |
597 | } |
598 | } |
599 | } |
600 | |
601 | class Leaf extends BaseContainer { |
602 | async run (m) { |
603 | this.kernel.incrementTicks(2) |
604 | await this.kernel.send(m.fromPort, new Message({ |
605 | data: 'first' |
606 | })) |
607 | } |
608 | } |
609 | |
610 | const hypervisor = new Hypervisor({ |
611 | dag: node.dag |
612 | }) |
613 | |
614 | hypervisor.registerContainer('root', BaseContainer) |
615 | hypervisor.registerContainer('middle', Middle) |
616 | hypervisor.registerContainer('leaf', Leaf) |
617 | |
618 | const root = await hypervisor.createInstance('root') |
619 | root.incrementTicks(2) |
620 | |
621 | const port = await root.ports.create('middle', 'first') |
622 | |
623 | await root.send(port, new Message()) |
624 | await root.send(port, new Message()) |
625 | }) |
626 | }) |
627 | |
628 |
Built with git-ssb-web