git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 864bc27090fe788a4bf5a86c00246ca6e4391dd0

Files: 864bc27090fe788a4bf5a86c00246ca6e4391dd0 / tests / index.js

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

Built with git-ssb-web