git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: d9b6113bb6b82443c2fb8a9a9b1afa58b1206f67

Files: d9b6113bb6b82443c2fb8a9a9b1afa58b1206f67 / tests / index.js

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

Built with git-ssb-web