Files: 4cca53d29be42c593457a41e7d0d5df90fe7a1aa / tests / index.js
12630 bytesRaw
1 | const tape = require('tape') |
2 | const IPFS = require('ipfs') |
3 | const Hypervisor = require('../') |
4 | |
5 | // start ipfs |
6 | const node = new IPFS({ |
7 | start: false |
8 | }) |
9 | |
10 | class 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 | |
23 | node.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('traps', async t => { |
113 | t.plan(1) |
114 | class Root extends BaseContainer { |
115 | async run (m) { |
116 | const one = this.exInterface.ports.create('root') |
117 | const two = this.exInterface.ports.create('root') |
118 | const three = this.exInterface.ports.create('root') |
119 | |
120 | this.exInterface.ports.bind('one', one) |
121 | this.exInterface.ports.bind('two', two) |
122 | this.exInterface.ports.bind('three', three) |
123 | |
124 | throw new Error('it is a trap!!!') |
125 | } |
126 | } |
127 | |
128 | const hypervisor = new Hypervisor(node.dag) |
129 | |
130 | hypervisor.registerContainer('root', Root) |
131 | const root = await hypervisor.createInstance('root') |
132 | await root.run(root.createMessage()) |
133 | // console.log('here', hypervisor.scheduler) |
134 | const stateRoot = await hypervisor.createStateRoot() |
135 | |
136 | t.deepEquals(stateRoot, { |
137 | '/': 'zdpuAwrMmQXqFusve7zcRYxVUuji4NVzZR5GyjwyStsjteCoW' |
138 | }, 'should revert the state') |
139 | }) |
140 | |
141 | tape('message should arrive in the correct oder if sent in order', async t => { |
142 | t.plan(2) |
143 | let runs = 0 |
144 | |
145 | class Root extends BaseContainer { |
146 | run (m) { |
147 | if (!runs) { |
148 | runs++ |
149 | const one = this.exInterface.ports.create('first') |
150 | const two = this.exInterface.ports.create('second') |
151 | |
152 | this.exInterface.ports.bind('one', one) |
153 | this.exInterface.ports.bind('two', two) |
154 | |
155 | this.exInterface.send(one, this.exInterface.createMessage()) |
156 | this.exInterface.send(two, this.exInterface.createMessage()) |
157 | |
158 | } else if (runs === 1) { |
159 | runs++ |
160 | t.equals(m.data, 'second', 'should recived the second message') |
161 | } else if (runs === 2) { |
162 | t.equals(m.data, 'first', 'should recive the first message') |
163 | } |
164 | } |
165 | } |
166 | |
167 | class First extends BaseContainer { |
168 | run (m) { |
169 | this.exInterface.incrementTicks(2) |
170 | this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'first'})) |
171 | } |
172 | } |
173 | |
174 | class Second extends BaseContainer { |
175 | run (m) { |
176 | this.exInterface.incrementTicks(1) |
177 | this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'second'})) |
178 | } |
179 | } |
180 | |
181 | const hypervisor = new Hypervisor(node.dag) |
182 | |
183 | hypervisor.registerContainer('root', Root) |
184 | hypervisor.registerContainer('first', First) |
185 | hypervisor.registerContainer('second', Second) |
186 | |
187 | const root = await hypervisor.createInstance('root') |
188 | const port = root.ports.create('root') |
189 | root.ports.bind('first', port) |
190 | |
191 | root.send(port, root.createMessage()) |
192 | }) |
193 | |
194 | tape('message should arrive in the correct oder if sent in order', async t => { |
195 | t.plan(2) |
196 | let runs = 0 |
197 | |
198 | class Root extends BaseContainer { |
199 | run (m) { |
200 | if (!runs) { |
201 | runs++ |
202 | const one = this.exInterface.ports.create('first') |
203 | const two = this.exInterface.ports.create('second') |
204 | |
205 | this.exInterface.ports.bind('one', one) |
206 | this.exInterface.ports.bind('two', two) |
207 | |
208 | this.exInterface.send(one, this.exInterface.createMessage()) |
209 | this.exInterface.send(two, this.exInterface.createMessage()) |
210 | |
211 | this.exInterface.incrementTicks(6) |
212 | } else if (runs === 1) { |
213 | runs++ |
214 | t.equals(m.data, 'first', 'should recive the first message') |
215 | } else if (runs === 2) { |
216 | t.equals(m.data, 'second', 'should recived the second message') |
217 | } |
218 | } |
219 | } |
220 | |
221 | class First extends BaseContainer { |
222 | run (m) { |
223 | this.exInterface.incrementTicks(1) |
224 | this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'first'})) |
225 | } |
226 | } |
227 | |
228 | class Second extends BaseContainer { |
229 | run (m) { |
230 | this.exInterface.incrementTicks(2) |
231 | this.exInterface.send(m.fromPort, this.exInterface.createMessage({data: 'second'})) |
232 | } |
233 | } |
234 | |
235 | const hypervisor = new Hypervisor(node.dag) |
236 | |
237 | hypervisor.registerContainer('root', Root) |
238 | hypervisor.registerContainer('first', First) |
239 | hypervisor.registerContainer('second', Second) |
240 | |
241 | const root = await hypervisor.createInstance('root') |
242 | const port = root.ports.create('root') |
243 | root.ports.bind('first', port) |
244 | |
245 | root.send(port, root.createMessage()) |
246 | }) |
247 | |
248 | tape('message should arrive in the correct order, even in a tie of ticks', async t => { |
249 | t.plan(2) |
250 | |
251 | let runs = 0 |
252 | |
253 | class Root extends BaseContainer { |
254 | run (m) { |
255 | if (!runs) { |
256 | runs++ |
257 | const one = this.exInterface.ports.create('first') |
258 | const two = this.exInterface.ports.create('second') |
259 | |
260 | this.exInterface.ports.bind('two', two) |
261 | this.exInterface.ports.bind('one', one) |
262 | |
263 | this.exInterface.send(one, this.exInterface.createMessage()) |
264 | this.exInterface.send(two, this.exInterface.createMessage()) |
265 | |
266 | this.exInterface.incrementTicks(6) |
267 | } else if (runs === 1) { |
268 | runs++ |
269 | t.equals(m.data, 'second', 'should recived the second message') |
270 | } else if (runs === 2) { |
271 | t.equals(m.data, 'first', 'should recive the first message') |
272 | } |
273 | } |
274 | } |
275 | |
276 | class First extends BaseContainer { |
277 | run (m) { |
278 | this.exInterface.incrementTicks(2) |
279 | return this.exInterface.send(m.fromPort, this.exInterface.createMessage({ |
280 | data: 'first' |
281 | })) |
282 | } |
283 | } |
284 | |
285 | class Second extends BaseContainer { |
286 | run (m) { |
287 | this.exInterface.incrementTicks(2) |
288 | return this.exInterface.send(m.fromPort, this.exInterface.createMessage({ |
289 | data: 'second' |
290 | })) |
291 | } |
292 | } |
293 | |
294 | const hypervisor = new Hypervisor(node.dag) |
295 | |
296 | hypervisor.registerContainer('root', Root) |
297 | hypervisor.registerContainer('first', First) |
298 | hypervisor.registerContainer('second', Second) |
299 | |
300 | const root = await hypervisor.createInstance('root') |
301 | |
302 | const port = root.ports.create('root') |
303 | root.ports.bind('first', port) |
304 | |
305 | root.send(port, root.createMessage()) |
306 | }) |
307 | |
308 | tape('message should arrive in the correct order, with a tie in ticks but with differnt proity', async t => { |
309 | t.plan(2) |
310 | |
311 | let runs = 0 |
312 | |
313 | class Root extends BaseContainer { |
314 | run (m) { |
315 | if (!runs) { |
316 | runs++ |
317 | const one = this.exInterface.ports.create('first') |
318 | const two = this.exInterface.ports.create('second') |
319 | |
320 | this.exInterface.ports.bind('one', one) |
321 | this.exInterface.ports.bind('two', two) |
322 | |
323 | this.exInterface.send(two, this.exInterface.createMessage()) |
324 | this.exInterface.send(one, this.exInterface.createMessage()) |
325 | |
326 | this.exInterface.incrementTicks(6) |
327 | } else if (runs === 1) { |
328 | runs++ |
329 | t.equals(m.data, 'first', 'should recive the first message') |
330 | } else if (runs === 2) { |
331 | t.equals(m.data, 'second', 'should recived the second message') |
332 | } |
333 | } |
334 | } |
335 | |
336 | class First extends BaseContainer { |
337 | run (m) { |
338 | this.exInterface.incrementTicks(2) |
339 | return this.exInterface.send(m.fromPort, this.exInterface.createMessage({ |
340 | data: 'first' |
341 | })) |
342 | } |
343 | } |
344 | |
345 | class Second extends BaseContainer { |
346 | run (m) { |
347 | this.exInterface.incrementTicks(2) |
348 | return this.exInterface.send(m.fromPort, this.exInterface.createMessage({ |
349 | data: 'second' |
350 | })) |
351 | } |
352 | } |
353 | |
354 | const hypervisor = new Hypervisor(node.dag) |
355 | |
356 | hypervisor.registerContainer('root', Root) |
357 | hypervisor.registerContainer('first', First) |
358 | hypervisor.registerContainer('second', Second) |
359 | |
360 | const root = await hypervisor.createInstance('root') |
361 | const port = root.ports.create('root') |
362 | root.ports.bind('first', port) |
363 | root.send(port, root.createMessage()) |
364 | }) |
365 | |
366 | tape('checking ports', async t => { |
367 | t.plan(4) |
368 | const hypervisor = new Hypervisor(node.dag) |
369 | hypervisor.registerContainer('base', BaseContainer) |
370 | |
371 | const root = await hypervisor.createInstance('base') |
372 | let port = root.ports.create('base') |
373 | await root.ports.bind('test', port) |
374 | |
375 | try { |
376 | root.createMessage({ |
377 | ports: [port] |
378 | }) |
379 | } catch (e) { |
380 | t.pass('should thow if sending a port that is bound') |
381 | } |
382 | |
383 | try { |
384 | await root.ports.bind('test', port) |
385 | } catch (e) { |
386 | t.pass('should thow if binding an already bound port') |
387 | } |
388 | |
389 | try { |
390 | let port2 = root.ports.create('base') |
391 | await root.ports.bind('test', port2) |
392 | } catch (e) { |
393 | t.pass('should thow if binding an already bound name') |
394 | } |
395 | |
396 | await root.ports.unbind('test') |
397 | const message = root.createMessage({ports: [port]}) |
398 | t.equals(message.ports[0], port, 'should create a message if the port is unbound') |
399 | }) |
400 | |
401 | tape.only('port deletion', async t => { |
402 | t.plan(2) |
403 | |
404 | class Root extends BaseContainer { |
405 | run (m) { |
406 | const one = this.exInterface.ports.create('first') |
407 | this.exInterface.ports.bind('one', one) |
408 | this.exInterface.send(one, this.exInterface.createMessage()) |
409 | this.exInterface.incrementTicks(6) |
410 | } |
411 | } |
412 | |
413 | class First extends BaseContainer { |
414 | run (m) { |
415 | this.exInterface.incrementTicks(2) |
416 | this.exInterface.ports.delete('root') |
417 | } |
418 | } |
419 | |
420 | const hypervisor = new Hypervisor(node.dag) |
421 | |
422 | hypervisor.registerContainer('root', Root) |
423 | hypervisor.registerContainer('first', First) |
424 | |
425 | const root = await hypervisor.createInstance('root') |
426 | const port = root.ports.create('root') |
427 | root.ports.bind('first', port) |
428 | root.send(port, root.createMessage()) |
429 | }) |
430 | }) |
431 |
Built with git-ssb-web