tests/index.jsView |
---|
1 | 1 | const tape = require('tape') |
2 | | -const AbstractContainer = require('primea-abstract-container') |
3 | | -const Message = require('primea-message') |
| 2 | +const Message = require('../message.js') |
4 | 3 | const Hypervisor = require('../') |
5 | 4 | |
6 | 5 | const level = require('level-browserify') |
7 | 6 | const RadixTree = require('dfinity-radix-tree') |
8 | 7 | const db = level('./testdb') |
9 | 8 | |
10 | | -class BaseContainer extends AbstractContainer { |
11 | | - onCreation () {} |
| 9 | +class BaseContainer { |
| 10 | + static validate () {} |
| 11 | + static compile () {} |
12 | 12 | static get typeId () { |
13 | 13 | return 9 |
14 | 14 | } |
| 15 | + |
| 16 | + static exports (m, id) { |
| 17 | + return Object.keys(this.functions()).map(name => { |
| 18 | + return { |
| 19 | + name, |
| 20 | + destId: id |
| 21 | + } |
| 22 | + }) |
| 23 | + } |
| 24 | + static instance (actor) { |
| 25 | + return { |
| 26 | + exports: this.functions(actor) |
| 27 | + } |
| 28 | + } |
15 | 29 | } |
16 | 30 | |
17 | 31 | tape('basic', async t => { |
18 | 32 | t.plan(2) |
19 | | - let message |
20 | 33 | const expectedState = { |
21 | 34 | '/': Buffer.from('926de6b7eb39cfa8d7f8a44d1ef191d3bcb765a7', 'hex') |
22 | 35 | } |
23 | 36 | |
25 | 38 | db: db |
26 | 39 | }) |
27 | 40 | |
28 | 41 | class testVMContainer extends BaseContainer { |
29 | | - onMessage (m, tag) { |
30 | | - t.true(m === message, 'should recive a message') |
| 42 | + static functions () { |
| 43 | + return { |
| 44 | + onMessage: (m) => { |
| 45 | + t.true(m === 1, 'should recive a message') |
| 46 | + } |
| 47 | + } |
31 | 48 | } |
32 | 49 | } |
33 | 50 | |
34 | 51 | const hypervisor = new Hypervisor(tree) |
35 | 52 | hypervisor.registerContainer(testVMContainer) |
36 | 53 | |
37 | | - let rootCap = await hypervisor.createActor(testVMContainer.typeId, new Message()) |
| 54 | + let {exports} = await hypervisor.createActor(testVMContainer.typeId) |
38 | 55 | |
39 | | - message = new Message() |
40 | | - hypervisor.send(rootCap, message) |
| 56 | + const message = new Message({ |
| 57 | + funcRef: exports[0], |
| 58 | + funcArguments: [1] |
| 59 | + }) |
| 60 | + hypervisor.send(message) |
41 | 61 | |
42 | 62 | const stateRoot = await hypervisor.createStateRoot() |
43 | 63 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
44 | 64 | }) |
45 | 65 | |
46 | 66 | tape('two communicating actors', async t => { |
47 | 67 | t.plan(2) |
48 | | - let message |
49 | 68 | const expectedState = { |
50 | 69 | '/': Buffer.from('a4c7ceacd8c867ae1d0b472d8bffa3cb10048331', 'hex') |
51 | 70 | } |
52 | 71 | |
54 | 73 | db: db |
55 | 74 | }) |
56 | 75 | |
57 | 76 | class testVMContainerA extends BaseContainer { |
58 | | - onCreation (m) { |
59 | | - message = new Message() |
60 | | - this.actor.send(m.caps[0], message) |
| 77 | + static functions (actor) { |
| 78 | + return { |
| 79 | + onMessage: (funcRef) => { |
| 80 | + const message = new Message({ |
| 81 | + funcRef: funcRef, |
| 82 | + funcArguments: [2] |
| 83 | + }) |
| 84 | + return actor.send(message) |
| 85 | + } |
| 86 | + } |
61 | 87 | } |
62 | 88 | } |
63 | 89 | |
64 | 90 | class testVMContainerB extends BaseContainer { |
65 | | - onMessage (m) { |
66 | | - t.true(m === message, 'should recive a message') |
| 91 | + static functions () { |
| 92 | + return { |
| 93 | + onMessage: (args) => { |
| 94 | + t.true(args === 2, 'should recive a message') |
| 95 | + } |
| 96 | + } |
67 | 97 | } |
68 | 98 | |
69 | 99 | static get typeId () { |
70 | 100 | return 8 |
74 | 104 | const hypervisor = new Hypervisor(tree) |
75 | 105 | hypervisor.registerContainer(testVMContainerA) |
76 | 106 | hypervisor.registerContainer(testVMContainerB) |
77 | 107 | |
78 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
79 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
80 | | - caps: [capB] |
81 | | - })) |
| 108 | + const {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId) |
| 109 | + const {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId) |
| 110 | + const message = new Message({ |
| 111 | + funcRef: exportsA[0], |
| 112 | + funcArguments: [exportsB[0]] |
| 113 | + }) |
82 | 114 | |
| 115 | + await hypervisor.send(message) |
| 116 | + |
83 | 117 | const stateRoot = await hypervisor.createStateRoot() |
84 | 118 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
85 | 119 | }) |
86 | 120 | |
87 | 121 | tape('three communicating actors', async t => { |
88 | 122 | t.plan(3) |
89 | | - let message |
90 | 123 | const expectedState = { |
91 | 124 | '/': Buffer.from('4633ac4b9f8212e501b6c56906039ec081fbe5a3', 'hex') |
92 | 125 | } |
93 | 126 | |
95 | 128 | db: db |
96 | 129 | }) |
97 | 130 | |
98 | 131 | class testVMContainerA extends BaseContainer { |
99 | | - onCreation (m) { |
100 | | - message = new Message() |
101 | | - this.actor.send(m.caps[0], message) |
| 132 | + static functions (actor) { |
| 133 | + return { |
| 134 | + onMessage: (funcRef) => { |
| 135 | + const message = new Message({ |
| 136 | + funcRef: funcRef, |
| 137 | + funcArguments: [2] |
| 138 | + }) |
| 139 | + actor.send(message) |
| 140 | + } |
| 141 | + } |
102 | 142 | } |
103 | 143 | } |
104 | 144 | |
105 | 145 | class testVMContainerB extends BaseContainer { |
106 | | - onMessage (m) { |
107 | | - t.true(m === message, 'should recive a message') |
| 146 | + static functions () { |
| 147 | + return { |
| 148 | + onMessage: (arg) => { |
| 149 | + t.equals(arg, 2, 'should recive a message') |
| 150 | + } |
| 151 | + } |
108 | 152 | } |
109 | 153 | |
110 | 154 | static get typeId () { |
111 | 155 | return 8 |
115 | 159 | const hypervisor = new Hypervisor(tree) |
116 | 160 | hypervisor.registerContainer(testVMContainerA) |
117 | 161 | hypervisor.registerContainer(testVMContainerB) |
118 | 162 | |
119 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
120 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
121 | | - caps: [capB] |
122 | | - })) |
| 163 | + let {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId) |
| 164 | + let {exports: exportsA0} = await hypervisor.createActor(testVMContainerA.typeId) |
| 165 | + let {exports: exportsA1} = await hypervisor.createActor(testVMContainerA.typeId) |
123 | 166 | |
124 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
125 | | - caps: [capB] |
126 | | - })) |
| 167 | + const message0 = new Message({ |
| 168 | + funcRef: exportsA0[0], |
| 169 | + funcArguments: [exportsB[0]] |
| 170 | + }) |
127 | 171 | |
| 172 | + const message1 = new Message({ |
| 173 | + funcRef: exportsA1[0], |
| 174 | + funcArguments: [exportsB[0]] |
| 175 | + }) |
| 176 | + |
| 177 | + await hypervisor.send(message0) |
| 178 | + await hypervisor.send(message1) |
| 179 | + |
128 | 180 | const stateRoot = await hypervisor.createStateRoot() |
129 | 181 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
130 | 182 | }) |
131 | 183 | |
132 | 184 | tape('three communicating actors, with tick counting', async t => { |
133 | 185 | t.plan(3) |
134 | | - let message |
135 | 186 | const expectedState = { |
136 | 187 | '/': Buffer.from('4633ac4b9f8212e501b6c56906039ec081fbe5a3', 'hex') |
137 | 188 | } |
138 | 189 | |
139 | 190 | const tree = new RadixTree({ |
140 | 191 | db: db |
141 | 192 | }) |
142 | 193 | |
143 | | - let ticks = 1 |
144 | | - |
145 | 194 | class testVMContainerA extends BaseContainer { |
146 | | - async onCreation (m) { |
147 | | - this.actor.incrementTicks(ticks) |
148 | | - ticks++ |
149 | | - message = new Message() |
150 | | - this.actor.send(m.caps[0], message) |
| 195 | + static functions (actor) { |
| 196 | + return { |
| 197 | + onMessage: funcRef => { |
| 198 | + actor.incrementTicks(1) |
| 199 | + const message = new Message({ |
| 200 | + funcRef: funcRef, |
| 201 | + funcArguments: [2] |
| 202 | + }) |
| 203 | + actor.send(message) |
| 204 | + } |
| 205 | + } |
151 | 206 | } |
152 | 207 | } |
153 | 208 | |
154 | 209 | class testVMContainerB extends BaseContainer { |
155 | | - onMessage (m) { |
156 | | - t.true(m, 'should recive a message') |
| 210 | + static functions (actor) { |
| 211 | + return { |
| 212 | + onMessage: arg => { |
| 213 | + t.equals(arg, 2, 'should recive a message') |
| 214 | + } |
| 215 | + } |
157 | 216 | } |
158 | 217 | |
159 | 218 | static get typeId () { |
160 | 219 | return 8 |
164 | 223 | const hypervisor = new Hypervisor(tree) |
165 | 224 | hypervisor.registerContainer(testVMContainerA) |
166 | 225 | hypervisor.registerContainer(testVMContainerB) |
167 | 226 | |
168 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
169 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
170 | | - caps: [capB] |
171 | | - })) |
| 227 | + let actorB = await hypervisor.createActor(testVMContainerB.typeId) |
| 228 | + let actorA0 = await hypervisor.createActor(testVMContainerA.typeId) |
| 229 | + let actorA1 = await hypervisor.createActor(testVMContainerA.typeId) |
172 | 230 | |
173 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
174 | | - caps: [capB] |
175 | | - })) |
| 231 | + const message0 = new Message({ |
| 232 | + funcRef: actorA0.exports[0], |
| 233 | + funcArguments: [actorB.exports[0]] |
| 234 | + }) |
176 | 235 | |
| 236 | + const message1 = new Message({ |
| 237 | + funcRef: actorA1.exports[0], |
| 238 | + funcArguments: actorB.exports |
| 239 | + }) |
| 240 | + |
| 241 | + hypervisor.send(message0) |
| 242 | + hypervisor.send(message1) |
| 243 | + |
177 | 244 | const stateRoot = await hypervisor.createStateRoot() |
178 | | - |
179 | 245 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
180 | 246 | }) |
181 | 247 | |
182 | 248 | tape('errors', async t => { |
183 | 249 | t.plan(3) |
184 | | - let message |
185 | 250 | const expectedState = { |
186 | 251 | '/': Buffer.from('a4c7ceacd8c867ae1d0b472d8bffa3cb10048331', 'hex') |
187 | 252 | } |
188 | 253 | |
190 | 255 | db: db |
191 | 256 | }) |
192 | 257 | |
193 | 258 | class testVMContainerA extends BaseContainer { |
194 | | - onCreation (m) { |
195 | | - message = new Message() |
196 | | - message.on('execution:error', () => { |
197 | | - t.pass('should recive a exeption') |
198 | | - }) |
199 | | - this.actor.send(m.caps[0], message) |
| 259 | + static functions (actor) { |
| 260 | + return { |
| 261 | + onMessage: funcRef => { |
| 262 | + const message = new Message({ |
| 263 | + funcRef |
| 264 | + }) |
| 265 | + message.on('execution:error', () => { |
| 266 | + t.pass('should recive a exeption') |
| 267 | + }) |
| 268 | + actor.send(message) |
| 269 | + } |
| 270 | + } |
200 | 271 | } |
201 | 272 | } |
202 | 273 | |
203 | 274 | class testVMContainerB extends BaseContainer { |
204 | | - onMessage (m) { |
205 | | - t.true(m === message, 'should recive a message') |
206 | | - throw new Error('test error') |
| 275 | + static functions (actor) { |
| 276 | + return { |
| 277 | + onMessage: funcRef => { |
| 278 | + t.true(true, 'should recive a message') |
| 279 | + throw new Error('test error') |
| 280 | + } |
| 281 | + } |
207 | 282 | } |
208 | 283 | |
209 | 284 | static get typeId () { |
210 | 285 | return 8 |
214 | 289 | const hypervisor = new Hypervisor(tree) |
215 | 290 | hypervisor.registerContainer(testVMContainerA) |
216 | 291 | hypervisor.registerContainer(testVMContainerB) |
217 | 292 | |
218 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
219 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
220 | | - caps: [capB] |
221 | | - })) |
222 | | - |
| 293 | + let {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId) |
| 294 | + let {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId) |
| 295 | + const message = new Message({ |
| 296 | + funcRef: exportsA[0], |
| 297 | + funcArguments: exportsB |
| 298 | + }) |
| 299 | + hypervisor.send(message) |
223 | 300 | const stateRoot = await hypervisor.createStateRoot() |
224 | 301 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
225 | 302 | }) |
226 | 303 | |
227 | 304 | tape('actor creation', async t => { |
228 | 305 | t.plan(2) |
229 | | - let message |
230 | 306 | const expectedState = { |
231 | 307 | '/': Buffer.from('f47377a763c91247e62138408d706a09bccaaf36', 'hex') |
232 | 308 | } |
233 | 309 | |
235 | 311 | db: db |
236 | 312 | }) |
237 | 313 | |
238 | 314 | class testVMContainerA extends BaseContainer { |
239 | | - onCreation (m) { |
240 | | - message = new Message() |
241 | | - const cap = this.actor.mintCap() |
242 | | - message.caps.push(cap) |
243 | | - return this.actor.createActor(testVMContainerB.typeId, message) |
| 315 | + static functions (actor) { |
| 316 | + return { |
| 317 | + onCreation: async funcRef => { |
| 318 | + const {exports} = await actor.createActor(testVMContainerB.typeId) |
| 319 | + const message = new Message({ |
| 320 | + funcRef: exports[0], |
| 321 | + funcArguments: [actor.getFuncRef('onMessage')] |
| 322 | + }) |
| 323 | + actor.send(message) |
| 324 | + }, |
| 325 | + onMessage: data => { |
| 326 | + t.equals(data, 'test', 'should recive a response message') |
| 327 | + } |
| 328 | + } |
244 | 329 | } |
245 | | - |
246 | | - onMessage (m) { |
247 | | - t.equals(m.data, 'test', 'should recive a response message') |
248 | | - } |
249 | 330 | } |
250 | 331 | |
251 | 332 | class testVMContainerB extends BaseContainer { |
252 | | - onCreation (m) { |
253 | | - const cap = m.caps[0] |
254 | | - this.actor.send(cap, new Message({data: 'test'})) |
| 333 | + static functions (actor) { |
| 334 | + return { |
| 335 | + onCreation: funcRef => { |
| 336 | + actor.send(new Message({funcRef, funcArguments: ['test']})) |
| 337 | + } |
| 338 | + } |
255 | 339 | } |
256 | 340 | |
257 | 341 | static get typeId () { |
258 | 342 | return 8 |
262 | 346 | const hypervisor = new Hypervisor(tree) |
263 | 347 | hypervisor.registerContainer(testVMContainerA) |
264 | 348 | hypervisor.registerContainer(testVMContainerB) |
265 | 349 | |
266 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
| 350 | + const {exports} = await hypervisor.createActor(testVMContainerA.typeId) |
| 351 | + await hypervisor.send(new Message({funcRef: exports[0]})) |
267 | 352 | |
268 | 353 | const stateRoot = await hypervisor.createStateRoot() |
269 | 354 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
270 | 355 | }) |
279 | 364 | db: db |
280 | 365 | }) |
281 | 366 | |
282 | 367 | class testVMContainerA extends BaseContainer { |
283 | | - onCreation (m) { |
284 | | - const message1 = new Message({ |
285 | | - data: 'first' |
286 | | - }) |
287 | | - const message2 = new Message({ |
288 | | - data: 'second' |
289 | | - }) |
290 | | - const message3 = new Message({ |
291 | | - data: 'third' |
292 | | - }) |
293 | | - this.actor.send(m.caps[0], message1) |
294 | | - this.actor.incrementTicks(1) |
295 | | - this.actor.send(m.caps[0], message2) |
296 | | - this.actor.incrementTicks(1) |
297 | | - this.actor.send(m.caps[0], message3) |
| 368 | + static functions (actor) { |
| 369 | + return { |
| 370 | + onCreation: funcRef => { |
| 371 | + const message1 = new Message({ |
| 372 | + funcArguments: ['first'], |
| 373 | + funcRef |
| 374 | + }) |
| 375 | + const message2 = new Message({ |
| 376 | + funcArguments: ['second'], |
| 377 | + funcRef |
| 378 | + }) |
| 379 | + const message3 = new Message({ |
| 380 | + funcArguments: ['third'], |
| 381 | + funcRef |
| 382 | + }) |
| 383 | + actor.send(message1) |
| 384 | + actor.incrementTicks(1) |
| 385 | + actor.send(message2) |
| 386 | + actor.incrementTicks(1) |
| 387 | + actor.send(message3) |
| 388 | + } |
| 389 | + } |
298 | 390 | } |
299 | 391 | } |
300 | 392 | |
301 | 393 | let recMsg = 0 |
302 | 394 | |
303 | 395 | class testVMContainerB extends BaseContainer { |
304 | | - onMessage (m) { |
305 | | - if (recMsg === 0) { |
306 | | - t.equal(m.data, 'first', 'should recive fist message') |
307 | | - } else if (recMsg === 1) { |
308 | | - t.equal(m.data, 'second', 'should recive second message') |
309 | | - } else { |
310 | | - t.equal(m.data, 'third', 'should recive third message') |
| 396 | + static functions (actor) { |
| 397 | + return { |
| 398 | + onMessage: data => { |
| 399 | + actor.incrementTicks(1) |
| 400 | + if (recMsg === 0) { |
| 401 | + t.equal(data, 'first', 'should recive fist message') |
| 402 | + } else if (recMsg === 1) { |
| 403 | + t.equal(data, 'second', 'should recive second message') |
| 404 | + } else { |
| 405 | + t.equal(data, 'third', 'should recive third message') |
| 406 | + } |
| 407 | + recMsg++ |
| 408 | + } |
311 | 409 | } |
312 | | - recMsg++ |
313 | 410 | } |
314 | 411 | |
315 | 412 | static get typeId () { |
316 | 413 | return 8 |
320 | 417 | const hypervisor = new Hypervisor(tree) |
321 | 418 | hypervisor.registerContainer(testVMContainerA) |
322 | 419 | hypervisor.registerContainer(testVMContainerB) |
323 | 420 | |
324 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
325 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
326 | | - caps: [capB] |
327 | | - })) |
| 421 | + const {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId) |
| 422 | + const {exports: exportsA} = await hypervisor.createActor(testVMContainerA.typeId) |
| 423 | + const message = new Message({ |
| 424 | + funcRef: exportsA[0], |
| 425 | + funcArguments: exportsB |
| 426 | + }) |
| 427 | + hypervisor.send(message) |
328 | 428 | |
329 | 429 | const stateRoot = await hypervisor.createStateRoot() |
330 | 430 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
331 | 431 | }) |
341 | 441 | db: db |
342 | 442 | }) |
343 | 443 | |
344 | 444 | class testVMContainerA extends BaseContainer { |
345 | | - onCreation (m) { |
346 | | - message = new Message({ |
347 | | - data: m.data |
348 | | - }) |
349 | | - this.actor.send(m.caps[0], message) |
| 445 | + static functions (actor) { |
| 446 | + return { |
| 447 | + onCreation: (funcRef, funcArguments) => { |
| 448 | + actor.incrementTicks(1) |
| 449 | + message = new Message({ |
| 450 | + funcRef, |
| 451 | + funcArguments: [funcArguments] |
| 452 | + }) |
| 453 | + return actor.send(message) |
| 454 | + } |
| 455 | + } |
350 | 456 | } |
351 | 457 | } |
352 | 458 | |
353 | 459 | let recMsg = 0 |
354 | 460 | |
355 | 461 | class testVMContainerB extends BaseContainer { |
356 | | - onMessage (m) { |
357 | | - if (recMsg === 0) { |
358 | | - t.equal(m.data, 'first', 'should recive fist message') |
359 | | - } else if (recMsg === 1) { |
360 | | - t.equal(m.data, 'second', 'should recive second message') |
361 | | - } else { |
362 | | - t.equal(m.data, 'third', 'should recive third message') |
| 462 | + static functions (actor) { |
| 463 | + return { |
| 464 | + onMessage: data => { |
| 465 | + if (recMsg === 0) { |
| 466 | + t.equal(data, 'first', 'should recive fist message') |
| 467 | + } else if (recMsg === 1) { |
| 468 | + t.equal(data, 'second', 'should recive second message') |
| 469 | + } else { |
| 470 | + t.equal(data, 'third', 'should recive third message') |
| 471 | + } |
| 472 | + recMsg++ |
| 473 | + } |
363 | 474 | } |
364 | | - recMsg++ |
365 | 475 | } |
366 | 476 | |
367 | 477 | static get typeId () { |
368 | 478 | return 8 |
372 | 482 | const hypervisor = new Hypervisor(tree) |
373 | 483 | hypervisor.registerContainer(testVMContainerA) |
374 | 484 | hypervisor.registerContainer(testVMContainerB) |
375 | 485 | |
376 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
377 | | - hypervisor.send(capB, new Message({ |
378 | | - data: 'first' |
| 486 | + let {exports: exportsB} = await hypervisor.createActor(testVMContainerB.typeId) |
| 487 | + hypervisor.send(new Message({ |
| 488 | + funcRef: exportsB[0], |
| 489 | + funcArguments: ['first'] |
379 | 490 | })) |
380 | 491 | |
381 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
382 | | - caps: [capB], |
383 | | - data: 'second' |
| 492 | + const {exports: exportsA0} = await hypervisor.createActor(testVMContainerA.typeId) |
| 493 | + |
| 494 | + hypervisor.send(new Message({ |
| 495 | + funcRef: exportsA0[0], |
| 496 | + funcArguments: [exportsB[0], 'second'] |
384 | 497 | })) |
385 | 498 | |
386 | | - await hypervisor.createActor(testVMContainerA.typeId, new Message({ |
387 | | - caps: [capB], |
388 | | - data: 'third' |
| 499 | + const {exports: exportsA1} = await hypervisor.createActor(testVMContainerA.typeId) |
| 500 | + hypervisor.send(new Message({ |
| 501 | + funcRef: exportsA1[0], |
| 502 | + funcArguments: [exportsB[0], 'third'] |
389 | 503 | })) |
390 | 504 | |
391 | 505 | const stateRoot = await hypervisor.createStateRoot() |
392 | 506 | t.deepEquals(stateRoot, expectedState, 'expected root!') |
393 | 507 | }) |
394 | 508 | |
395 | | -tape('basic tagged caps', async t => { |
396 | | - t.plan(4) |
397 | | - const expectedState = { |
398 | | - '/': Buffer.from('b8eb399087a990e30373e954b627a9512c9af40b', 'hex') |
399 | | - } |
400 | | - |
| 509 | +tape('random', async t => { |
| 510 | + const numOfActors = 10 |
| 511 | + const depth = 10 |
| 512 | + const messageOrder = {} |
| 513 | + let numOfMsg = 0 |
401 | 514 | const tree = new RadixTree({ |
402 | 515 | db: db |
403 | 516 | }) |
404 | 517 | |
405 | | - class testVMContainerA extends BaseContainer { |
406 | | - async onMessage (m) { |
407 | | - t.true(m, 'should recive first message') |
408 | | - const rCap = this.actor.mintCap(1) |
409 | | - const message = new Message({caps: [rCap]}) |
410 | | - this.actor.send(m.caps[0], message) |
411 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([1], 44) |
412 | | - t.true(rMessage, 'should recive a response message') |
413 | | - } |
414 | | - } |
415 | | - |
416 | | - class testVMContainerB extends BaseContainer { |
417 | | - onMessage (m) { |
418 | | - t.true(m, 'should recive a message') |
419 | | - this.actor.send(m.caps[0], new Message()) |
420 | | - } |
421 | | - |
422 | | - static get typeId () { |
423 | | - return 8 |
424 | | - } |
425 | | - } |
426 | | - |
427 | | - const hypervisor = new Hypervisor(tree) |
428 | | - hypervisor.registerContainer(testVMContainerA) |
429 | | - hypervisor.registerContainer(testVMContainerB) |
430 | | - |
431 | | - let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
432 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
433 | | - |
434 | | - hypervisor.send(capA, new Message({caps: [capB]})) |
435 | | - |
436 | | - const stateRoot = await hypervisor.createStateRoot() |
437 | | - t.deepEquals(stateRoot, expectedState, 'expected root!') |
438 | | -}) |
439 | | - |
440 | | -tape('trying to listen for caps more then once', async t => { |
441 | | - t.plan(4) |
442 | | - const expectedState = { |
443 | | - '/': Buffer.from('b8eb399087a990e30373e954b627a9512c9af40b', 'hex') |
444 | | - } |
445 | | - |
446 | | - const tree = new RadixTree({ |
447 | | - db: db |
448 | | - }) |
449 | | - |
450 | | - class testVMContainerA extends BaseContainer { |
451 | | - async onMessage (m) { |
452 | | - t.true(m, 'should recive first message') |
453 | | - const message = new Message({data: 'first'}) |
454 | | - this.actor.send(m.caps[0], message) |
455 | | - const promise = this.actor.inbox.nextTaggedMessage([1], 44) |
456 | | - try { |
457 | | - await this.actor.inbox.nextTaggedMessage([1], 44) |
458 | | - } catch (e) { |
459 | | - t.true(e, 'should error if waiting twice') |
| 518 | + class BenchmarkContainer extends BaseContainer { |
| 519 | + static functions (actor) { |
| 520 | + return { |
| 521 | + onMessage: function () { |
| 522 | + const refs = [...arguments] |
| 523 | + const ref = refs.pop() |
| 524 | + const last = messageOrder[actor.id.toString('hex')] |
| 525 | + const message = actor.currentMessage |
| 526 | + if (last) { |
| 527 | + t.ok(last <= message._fromTicks) |
| 528 | + } |
| 529 | + messageOrder[actor.id.toString('hex')] = message._fromTicks |
| 530 | + numOfMsg++ |
| 531 | + actor.incrementTicks(10) |
| 532 | + if (ref) { |
| 533 | + return actor.send(new Message({ |
| 534 | + funcRef: ref, |
| 535 | + funcArguments: refs |
| 536 | + })) |
| 537 | + } |
| 538 | + } |
460 | 539 | } |
461 | | - return promise |
462 | 540 | } |
463 | 541 | } |
464 | 542 | |
465 | | - class testVMContainerB extends BaseContainer { |
466 | | - onMessage (m) { |
467 | | - t.true(m, 'should recive a message') |
468 | | - } |
469 | | - |
470 | | - static get typeId () { |
471 | | - return 8 |
472 | | - } |
473 | | - } |
474 | | - |
475 | 543 | const hypervisor = new Hypervisor(tree) |
476 | | - hypervisor.registerContainer(testVMContainerA) |
477 | | - hypervisor.registerContainer(testVMContainerB) |
| 544 | + hypervisor.registerContainer(BenchmarkContainer) |
478 | 545 | |
479 | | - let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
480 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
481 | | - |
482 | | - await hypervisor.send(capA, new Message({caps: [capB]})) |
483 | | - |
484 | | - const stateRoot = await hypervisor.createStateRoot() |
485 | | - t.deepEquals(stateRoot, expectedState, 'expected root!') |
486 | | -}) |
487 | | - |
488 | | -tape('multple messages to restore on waiting for tags', async t => { |
489 | | - t.plan(6) |
490 | | - const expectedState = { |
491 | | - '/': Buffer.from('b2025e9430f0ce3a53767a36124fa622f782a38f', 'hex') |
| 546 | + const refernces = [] |
| 547 | + let _numOfActors = numOfActors |
| 548 | + while (_numOfActors--) { |
| 549 | + const {exports} = await hypervisor.createActor(BenchmarkContainer.typeId) |
| 550 | + refernces.push(exports[0]) |
492 | 551 | } |
493 | | - |
494 | | - const tree = new RadixTree({ |
495 | | - db: db |
496 | | - }) |
497 | | - |
498 | | - class testVMContainerA extends BaseContainer { |
499 | | - async onMessage (m) { |
500 | | - t.true(m, 'should recive first message') |
501 | | - if (m.caps.length) { |
502 | | - const cap1 = this.actor.mintCap(1) |
503 | | - const cap2 = this.actor.mintCap(2) |
504 | | - const message1 = new Message({ |
505 | | - data: 'first' |
506 | | - }) |
507 | | - const message2 = new Message({ |
508 | | - data: 'second' |
509 | | - }) |
510 | | - message1.caps.push(cap1) |
511 | | - message2.caps.push(cap2) |
512 | | - this.actor.send(m.caps[0], message1) |
513 | | - this.actor.send(m.caps[1], message2) |
514 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44) |
515 | | - t.true(rMessage, 'should recive a response message') |
516 | | - } |
| 552 | + _numOfActors = numOfActors |
| 553 | + let msgs = [] |
| 554 | + while (_numOfActors--) { |
| 555 | + let _depth = depth |
| 556 | + const funcArguments = [] |
| 557 | + while (_depth--) { |
| 558 | + const r = Math.floor(Math.random() * numOfActors) |
| 559 | + const ref = refernces[r] |
| 560 | + funcArguments.push(ref) |
517 | 561 | } |
| 562 | + const message = new Message({ |
| 563 | + funcArguments, |
| 564 | + funcRef: refernces[_numOfActors] |
| 565 | + }) |
| 566 | + msgs.push(message) |
518 | 567 | } |
519 | 568 | |
520 | | - class testVMContainerB extends BaseContainer { |
521 | | - onMessage (m) { |
522 | | - t.true(m, 'should recive a message') |
523 | | - const cap = m.caps[0] |
524 | | - this.actor.incrementTicks(1) |
525 | | - this.actor.send(cap, new Message({data: m.data})) |
526 | | - } |
527 | | - |
528 | | - static get typeId () { |
529 | | - return 8 |
530 | | - } |
531 | | - } |
532 | | - |
533 | | - const hypervisor = new Hypervisor(tree) |
534 | | - hypervisor.registerContainer(testVMContainerA) |
535 | | - hypervisor.registerContainer(testVMContainerB) |
536 | | - |
537 | | - let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
538 | | - let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
539 | | - let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
540 | | - |
541 | | - hypervisor.send(capA, new Message({caps: [capB1, capB2]})) |
542 | | - |
543 | | - const stateRoot = await hypervisor.createStateRoot() |
544 | | - |
545 | | - t.deepEquals(stateRoot, expectedState, 'expected root!') |
| 569 | + msgs.forEach(msg => hypervisor.send(msg)) |
| 570 | + |
| 571 | + await hypervisor.scheduler.wait(Infinity) |
| 572 | + t.equals(numOfMsg, 110) |
| 573 | + t.end() |
546 | 574 | }) |
547 | | - |
548 | | -tape('multple messages to backup on waiting for tags', async t => { |
549 | | - t.plan(6) |
550 | | - const expectedState = { |
551 | | - '/': Buffer.from('b2025e9430f0ce3a53767a36124fa622f782a38f', 'hex') |
552 | | - } |
553 | | - |
554 | | - const tree = new RadixTree({ |
555 | | - db: db |
556 | | - }) |
557 | | - |
558 | | - class testVMContainerA extends BaseContainer { |
559 | | - async onMessage (m) { |
560 | | - t.true(m, 'should recive first message') |
561 | | - if (m.caps.length) { |
562 | | - const cap1 = this.actor.mintCap(1) |
563 | | - const cap2 = this.actor.mintCap(2) |
564 | | - const message1 = new Message({ |
565 | | - data: 'first' |
566 | | - }) |
567 | | - const message2 = new Message({ |
568 | | - data: 'second' |
569 | | - }) |
570 | | - message1.caps.push(cap1) |
571 | | - message2.caps.push(cap2) |
572 | | - this.actor.send(m.caps[0], message1) |
573 | | - this.actor.send(m.caps[1], message2) |
574 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([1, 2], 44) |
575 | | - t.true(rMessage, 'should recive a response message') |
576 | | - } |
577 | | - } |
578 | | - } |
579 | | - |
580 | | - class testVMContainerB extends BaseContainer { |
581 | | - async onMessage (m) { |
582 | | - t.true(m, 'should recive a message') |
583 | | - const cap = m.caps[0] |
584 | | - this.actor.incrementTicks(1) |
585 | | - this.actor.send(cap, new Message({data: m.data})) |
586 | | - } |
587 | | - |
588 | | - static get typeId () { |
589 | | - return 8 |
590 | | - } |
591 | | - } |
592 | | - |
593 | | - const hypervisor = new Hypervisor(tree) |
594 | | - hypervisor.registerContainer(testVMContainerA) |
595 | | - hypervisor.registerContainer(testVMContainerB) |
596 | | - |
597 | | - let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
598 | | - let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
599 | | - let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
600 | | - |
601 | | - hypervisor.send(capA, new Message({caps: [capB1, capB2]})) |
602 | | - |
603 | | - const stateRoot = await hypervisor.createStateRoot() |
604 | | - t.deepEquals(stateRoot, expectedState, 'expected root!') |
605 | | -}) |
606 | | - |
607 | | -tape('multple messages, but single tag', async t => { |
608 | | - t.plan(6) |
609 | | - const expectedState = { |
610 | | - '/': Buffer.from('b2025e9430f0ce3a53767a36124fa622f782a38f', 'hex') |
611 | | - } |
612 | | - |
613 | | - const tree = new RadixTree({ |
614 | | - db: db |
615 | | - }) |
616 | | - |
617 | | - class testVMContainerA extends BaseContainer { |
618 | | - async onMessage (m) { |
619 | | - t.true(m, 'should recive first message') |
620 | | - if (m.caps.length) { |
621 | | - const cap1 = this.actor.mintCap(1) |
622 | | - const cap2 = this.actor.mintCap(2) |
623 | | - const message1 = new Message({ |
624 | | - data: 'first' |
625 | | - }) |
626 | | - const message2 = new Message({ |
627 | | - data: 'second' |
628 | | - }) |
629 | | - message1.caps.push(cap1) |
630 | | - message2.caps.push(cap2) |
631 | | - await this.actor.send(m.caps[0], message1) |
632 | | - await this.actor.send(m.caps[1], message2) |
633 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([2], 44) |
634 | | - t.true(rMessage, 'should recive a response message') |
635 | | - } |
636 | | - } |
637 | | - } |
638 | | - |
639 | | - class testVMContainerB extends BaseContainer { |
640 | | - async onMessage (m) { |
641 | | - t.true(m, 'should recive a message') |
642 | | - const cap = m.caps[0] |
643 | | - this.actor.incrementTicks(1) |
644 | | - this.actor.send(cap, new Message({data: m.data})) |
645 | | - } |
646 | | - |
647 | | - static get typeId () { |
648 | | - return 8 |
649 | | - } |
650 | | - } |
651 | | - |
652 | | - const hypervisor = new Hypervisor(tree) |
653 | | - hypervisor.registerContainer(testVMContainerA) |
654 | | - hypervisor.registerContainer(testVMContainerB) |
655 | | - |
656 | | - let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
657 | | - let capB1 = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
658 | | - let capB2 = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
659 | | - |
660 | | - hypervisor.send(capA, new Message({caps: [capB1, capB2]})) |
661 | | - |
662 | | - const stateRoot = await hypervisor.createStateRoot() |
663 | | - t.deepEquals(stateRoot, expectedState, 'expected root!') |
664 | | -}) |
665 | | - |
666 | | -tape('deadlock test', async t => { |
667 | | - t.plan(7) |
668 | | - const expectedState = { |
669 | | - '/': Buffer.from('54f55756d0255d849e6878cc706f4c1565396e5c', 'hex') |
670 | | - } |
671 | | - |
672 | | - const tree = new RadixTree({ |
673 | | - db: db |
674 | | - }) |
675 | | - |
676 | | - class testVMContainerA extends BaseContainer { |
677 | | - async onMessage (m) { |
678 | | - t.true(m, 'should recive first message 1') |
679 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([1], 50) |
680 | | - t.equals(rMessage, undefined, 'should recive a response message 1') |
681 | | - } |
682 | | - } |
683 | | - |
684 | | - class testVMContainerB extends BaseContainer { |
685 | | - async onMessage (m) { |
686 | | - t.true(m, 'should recive first message 2') |
687 | | - this.actor.incrementTicks(47) |
688 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1) |
689 | | - t.equals(rMessage, undefined, 'should recive a response message 2') |
690 | | - } |
691 | | - |
692 | | - static get typeId () { |
693 | | - return 8 |
694 | | - } |
695 | | - } |
696 | | - |
697 | | - class testVMContainerC extends BaseContainer { |
698 | | - async onMessage (m) { |
699 | | - t.true(m, 'should recive first message 3') |
700 | | - this.actor.incrementTicks(45) |
701 | | - const rMessage = await this.actor.inbox.nextTaggedMessage([1], 1) |
702 | | - t.equals(rMessage, undefined, 'should recive a response message 3') |
703 | | - } |
704 | | - |
705 | | - static get typeId () { |
706 | | - return 7 |
707 | | - } |
708 | | - } |
709 | | - |
710 | | - const hypervisor = new Hypervisor(tree) |
711 | | - hypervisor.registerContainer(testVMContainerA) |
712 | | - hypervisor.registerContainer(testVMContainerB) |
713 | | - hypervisor.registerContainer(testVMContainerC) |
714 | | - |
715 | | - let capA = await hypervisor.createActor(testVMContainerA.typeId, new Message()) |
716 | | - let capB = await hypervisor.createActor(testVMContainerB.typeId, new Message()) |
717 | | - let capC = await hypervisor.createActor(testVMContainerC.typeId, new Message()) |
718 | | - |
719 | | - hypervisor.send(capA, new Message()) |
720 | | - hypervisor.send(capB, new Message()) |
721 | | - hypervisor.send(capC, new Message()) |
722 | | - |
723 | | - const stateRoot = await hypervisor.createStateRoot() |
724 | | - t.deepEquals(stateRoot, expectedState, 'expected root!') |
725 | | -}) |