git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 2306af1727ce5851183891346923734523247981

Files: 2306af1727ce5851183891346923734523247981 / tests / index.js

17355 bytesRaw
1const tape = require('tape')
2const IPFS = require('ipfs')
3const Hypervisor = require('../')
4const Message = require('primea-message')
5
6const node = new IPFS()
7
8class 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
21node.on('error', err => {
22 console.log(err)
23})
24
25node.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