git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 6b20ce6345f5cf4e554a3d7b67876db977eb8070

Files: 6b20ce6345f5cf4e554a3d7b67876db977eb8070 / tests / index.js

12965 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', async t => {
51 t.plan(4)
52 let message
53 const expectedState = {
54 '/': 'zdpuAtVcH6MUnvt2RXnLsDXyLB3CBSQ7aydfh2ogSKGCejJCQ'
55 }
56 let hasResolved = false
57
58 class testVMContainer2 extends BaseContainer {
59 run (m) {
60 t.true(m === message, 'should recive a message')
61 return new Promise((resolve, reject) => {
62 setTimeout(() => {
63 this.exInterface.incrementTicks(1)
64 hasResolved = true
65 resolve()
66 }, 200)
67 })
68 }
69 }
70
71 class testVMContainer extends BaseContainer {
72 run (m) {
73 const port = this.exInterface.ports.create('test2')
74 this.exInterface.ports.bind('child', port)
75 this.exInterface.send(port, m)
76 this.exInterface.incrementTicks(1)
77 }
78 }
79
80 const hypervisor = new Hypervisor(node.dag)
81 hypervisor.registerContainer('test', testVMContainer)
82 hypervisor.registerContainer('test2', testVMContainer2)
83
84 let root = await hypervisor.createInstance('test')
85 const rootId = root.id
86 let port = root.ports.create('test')
87
88 root.ports.bind('first', port)
89 message = root.createMessage()
90
91 root.send(port, message)
92 const stateRoot = await hypervisor.createStateRoot(Infinity)
93 t.true(hasResolved, 'should resolve before generating the state root')
94 t.deepEquals(stateRoot, expectedState, 'expected state')
95 // await hypervisor.graph.tree(hypervisor._state, Infinity)
96 // console.log(JSON.stringify(hypervisor._state, null, 2))
97 // test reviving the state
98 class testVMContainer3 extends BaseContainer {
99 run (m) {
100 const port = this.exInterface.ports.get('child')
101 this.exInterface.send(port, m)
102 this.exInterface.incrementTicks(1)
103 }
104 }
105
106 hypervisor.registerContainer('test', testVMContainer3)
107 root = await hypervisor.getInstance(rootId)
108 port = root.ports.get('first')
109 root.send(port, message)
110 })
111
112 tape.skip('ping pong', async t => {
113 class Ping extends BaseContainer {
114 async run (m) {
115 let port = this.exInterface.ports.get('child')
116 if (!port) {
117 port = this.exInterface.ports.create('pong')
118 this.exInterface.ports.bind(port, 'child')
119 }
120
121 if (this.exInterface.ticks < 100) {
122 this.exInterface.incrementTicks(1)
123 return this.exInterface.send(port, this.exInterface.createMessage())
124 }
125 }
126 }
127
128 class Pong extends BaseContainer {
129 run (m) {
130 const port = m.fromPort
131 this.exInterface.incrementTicks(2)
132 return this.exInterface.send(port, this.exInterface.createMessage())
133 }
134 }
135
136 const hypervisor = new Hypervisor(node.dag)
137
138 hypervisor.registerContainer('ping', Ping)
139 hypervisor.registerContainer('pong', Pong)
140 const root = await hypervisor.createInstance('pong')
141 const port = root.ports.create('ping')
142 root.ports.bind(port, 'child')
143
144 await root.send(port, root.createMessage())
145 await hypervisor.createStateRoot(root, Infinity)
146
147 t.end()
148 })
149
150 tape('traps', async t => {
151 t.plan(1)
152 class Root extends BaseContainer {
153 async run (m) {
154 const one = this.exInterface.ports.create('root')
155 const two = this.exInterface.ports.create('root')
156 const three = this.exInterface.ports.create('root')
157
158 this.exInterface.ports.bind('one', one)
159 this.exInterface.ports.bind('two', two)
160 this.exInterface.ports.bind('three', three)
161
162 throw new Error('it is a trap!!!')
163 }
164 }
165
166 const hypervisor = new Hypervisor(node.dag)
167
168 hypervisor.registerContainer('root', Root)
169 const root = await hypervisor.createInstance('root')
170 await root.run(root.createMessage())
171 // console.log('here', hypervisor.scheduler)
172 const stateRoot = await hypervisor.createStateRoot()
173
174 t.deepEquals(stateRoot, {
175 '/': 'zdpuAwrMmQXqFusve7zcRYxVUuji4NVzZR5GyjwyStsjteCoW'
176 }, 'should revert the state')
177 })
178
179 tape('message should arrive in the correct oder if sent in order', async t => {
180 t.plan(2)
181 let runs = 0
182
183 class Root extends BaseContainer {
184 run (m) {
185 if (!runs) {
186 runs++
187 const one = this.exInterface.ports.create('first')
188 const two = this.exInterface.ports.create('second')
189
190 this.exInterface.ports.bind('one', one)
191 this.exInterface.ports.bind('two', two)
192
193 this.exInterface.send(one, this.exInterface.createMessage())
194 this.exInterface.send(two, this.exInterface.createMessage())
195
196 } else if (runs === 1) {
197 runs++
198 t.equals(m.data, 'second', 'should recived the second message')
199 } else if (runs === 2) {
200 t.equals(m.data, 'first', 'should recive the first message')
201 }
202 }
203 }
204
205 class First extends BaseContainer {
206 run (m) {
207 this.exInterface.incrementTicks(2)
208 this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'first'}))
209 }
210 }
211
212 class Second extends BaseContainer {
213 run (m) {
214 this.exInterface.incrementTicks(1)
215 this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'second'}))
216 }
217 }
218
219 const hypervisor = new Hypervisor(node.dag)
220
221 hypervisor.registerContainer('root', Root)
222 hypervisor.registerContainer('first', First)
223 hypervisor.registerContainer('second', Second)
224
225 const root = await hypervisor.createInstance('root')
226 const port = root.ports.create('root')
227 root.ports.bind('first', port)
228
229 root.send(port, root.createMessage())
230 })
231
232 tape('message should arrive in the correct oder if sent in order', async t => {
233 t.plan(2)
234 let runs = 0
235
236 class Root extends BaseContainer {
237 run (m) {
238 if (!runs) {
239 runs++
240 const one = this.exInterface.ports.create('first')
241 const two = this.exInterface.ports.create('second')
242
243 this.exInterface.ports.bind('one', one)
244 this.exInterface.ports.bind('two', two)
245
246 this.exInterface.send(one, this.exInterface.createMessage())
247 this.exInterface.send(two, this.exInterface.createMessage())
248
249 this.exInterface.incrementTicks(6)
250 } else if (runs === 1) {
251 runs++
252 t.equals(m.data, 'first', 'should recive the first message')
253 } else if (runs === 2) {
254 t.equals(m.data, 'second', 'should recived the second message')
255 }
256 }
257 }
258
259 class First extends BaseContainer {
260 run (m) {
261 this.exInterface.incrementTicks(1)
262 this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'first'}))
263 }
264 }
265
266 class Second extends BaseContainer {
267 run (m) {
268 this.exInterface.incrementTicks(2)
269 this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'second'}))
270 }
271 }
272
273 const hypervisor = new Hypervisor(node.dag)
274
275 hypervisor.registerContainer('root', Root)
276 hypervisor.registerContainer('first', First)
277 hypervisor.registerContainer('second', Second)
278
279 const root = await hypervisor.createInstance('root')
280 const port = root.ports.create('root')
281 root.ports.bind('first', port)
282
283 root.send(port, root.createMessage())
284 })
285
286 tape('message should arrive in the correct order, even in a tie of ticks', async t => {
287 t.plan(2)
288
289 let runs = 0
290
291 class Root extends BaseContainer {
292 run (m) {
293 if (!runs) {
294 runs++
295 const one = this.exInterface.ports.create('first')
296 const two = this.exInterface.ports.create('second')
297
298 this.exInterface.ports.bind('two', two)
299 this.exInterface.ports.bind('one', one)
300
301 this.exInterface.send(one, this.exInterface.createMessage())
302 this.exInterface.send(two, this.exInterface.createMessage())
303
304 this.exInterface.incrementTicks(6)
305 } else if (runs === 1) {
306 runs++
307 t.equals(m.data, 'second', 'should recived the second message')
308 } else if (runs === 2) {
309 t.equals(m.data, 'first', 'should recive the first message')
310 }
311 }
312 }
313
314 class First extends BaseContainer {
315 run (m) {
316 this.exInterface.incrementTicks(2)
317 return this.exInterface.send(m.fromPort, this.exInterface.createMessage({
318 data: 'first'
319 }))
320 }
321 }
322
323 class Second extends BaseContainer {
324 run (m) {
325 this.exInterface.incrementTicks(2)
326 return this.exInterface.send(m.fromPort, this.exInterface.createMessage({
327 data: 'second'
328 }))
329 }
330 }
331
332 const hypervisor = new Hypervisor(node.dag)
333
334 hypervisor.registerContainer('root', Root)
335 hypervisor.registerContainer('first', First)
336 hypervisor.registerContainer('second', Second)
337
338 const root = await hypervisor.createInstance('root')
339
340 const port = root.ports.create('root')
341 root.ports.bind('first', port)
342
343 root.send(port, root.createMessage())
344 })
345
346 tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => {
347 t.plan(2)
348
349 let runs = 0
350
351 class Root extends BaseContainer {
352 run (m) {
353 if (!runs) {
354 runs++
355 const one = this.exInterface.ports.create('first')
356 const two = this.exInterface.ports.create('second')
357
358 this.exInterface.ports.bind('one', one)
359 this.exInterface.ports.bind('two', two)
360
361 this.exInterface.send(two, this.exInterface.createMessage())
362 this.exInterface.send(one, this.exInterface.createMessage())
363
364 this.exInterface.incrementTicks(6)
365 } else if (runs === 1) {
366 runs++
367 t.equals(m.data, 'first', 'should recive the first message')
368 } else if (runs === 2) {
369 t.equals(m.data, 'second', 'should recived the second message')
370 }
371 }
372 }
373
374 class First extends BaseContainer {
375 run (m) {
376 this.exInterface.incrementTicks(2)
377 return this.exInterface.send(m.fromPort, this.exInterface.createMessage({
378 resources: {
379 priority: 100
380 },
381 data: 'first'
382 }))
383 }
384 }
385
386 class Second extends BaseContainer {
387 run (m) {
388 this.exInterface.incrementTicks(2)
389 return this.exInterface.send(m.fromPort, this.exInterface.createMessage({
390 data: 'second'
391 }))
392 }
393 }
394
395 const hypervisor = new Hypervisor(node.dag)
396
397 hypervisor.registerContainer('root', Root)
398 hypervisor.registerContainer('first', First)
399 hypervisor.registerContainer('second', Second)
400
401 const root = await hypervisor.createInstance('root')
402 const port = root.ports.create('root')
403 root.ports.bind('first', port)
404 root.send(port, root.createMessage())
405 })
406
407 tape('checking ports', async t => {
408 t.plan(4)
409 const hypervisor = new Hypervisor(node.dag)
410 hypervisor.registerContainer('base', BaseContainer)
411
412 const root = await hypervisor.createInstance('base')
413 let port = root.ports.create('base')
414 await root.ports.bind('test', port)
415
416 try {
417 root.createMessage({
418 ports: [port]
419 })
420 } catch (e) {
421 t.pass('should thow if sending a port that is bound')
422 }
423
424 try {
425 await root.ports.bind('test', port)
426 } catch (e) {
427 t.pass('should thow if binding an already bound port')
428 }
429
430 try {
431 let port2 = root.ports.create('base')
432 await root.ports.bind('test', port2)
433 } catch (e) {
434 t.pass('should thow if binding an already bound name')
435 }
436
437 await root.ports.unbind('test')
438 const message = root.createMessage({ports: [port]})
439 t.equals(message.ports[0], port, 'should create a message if the port is unbound')
440 })
441})
442

Built with git-ssb-web