Commit | Line | Data |
---|---|---|
a61a0724 | 1 | const { expect } = require('expect') |
a35560ba | 2 | const { |
a35560ba | 3 | DynamicThreadPool, |
3d6dd312 | 4 | FixedClusterPool, |
2ced693a | 5 | FixedThreadPool, |
3d6dd312 | 6 | WorkerChoiceStrategies |
cdace0e5 | 7 | } = require('../../../lib') |
86bf340d | 8 | const { CircularArray } = require('../../../lib/circular-array') |
a35560ba S |
9 | |
10 | describe('Selection strategies test suite', () => { | |
e1ffb94f JB |
11 | const min = 0 |
12 | const max = 3 | |
13 | ||
a35560ba S |
14 | it('Verify that WorkerChoiceStrategies enumeration provides string values', () => { |
15 | expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN') | |
e4543b14 JB |
16 | expect(WorkerChoiceStrategies.LEAST_USED).toBe('LEAST_USED') |
17 | expect(WorkerChoiceStrategies.LEAST_BUSY).toBe('LEAST_BUSY') | |
a7bbf44a | 18 | expect(WorkerChoiceStrategies.LEAST_ELU).toBe('LEAST_ELU') |
23ff945a | 19 | expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE') |
b3432a63 JB |
20 | expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe( |
21 | 'WEIGHTED_ROUND_ROBIN' | |
22 | ) | |
feec6e8c JB |
23 | expect(WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN).toBe( |
24 | 'INTERLEAVED_WEIGHTED_ROUND_ROBIN' | |
25 | ) | |
a35560ba S |
26 | }) |
27 | ||
e843b904 | 28 | it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => { |
e843b904 JB |
29 | const pool = new DynamicThreadPool( |
30 | min, | |
31 | max, | |
32 | './tests/worker-files/thread/testWorker.js' | |
33 | ) | |
34 | expect(pool.opts.workerChoiceStrategy).toBe( | |
35 | WorkerChoiceStrategies.ROUND_ROBIN | |
36 | ) | |
37 | // We need to clean up the resources after our test | |
38 | await pool.destroy() | |
39 | }) | |
40 | ||
594bfb84 JB |
41 | it('Verify available strategies are taken at pool creation', async () => { |
42 | for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { | |
43 | const pool = new FixedThreadPool( | |
44 | max, | |
45 | './tests/worker-files/thread/testWorker.js', | |
46 | { workerChoiceStrategy } | |
47 | ) | |
48 | expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy) | |
49 | expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe( | |
50 | workerChoiceStrategy | |
51 | ) | |
52 | await pool.destroy() | |
53 | } | |
d2f7b7a2 JB |
54 | }) |
55 | ||
594bfb84 JB |
56 | it('Verify available strategies can be set after pool creation', async () => { |
57 | for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { | |
58 | const pool = new DynamicThreadPool( | |
59 | min, | |
60 | max, | |
ec82cfa1 | 61 | './tests/worker-files/thread/testWorker.js' |
594bfb84 JB |
62 | ) |
63 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) | |
64 | expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy) | |
65 | expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe( | |
66 | workerChoiceStrategy | |
67 | ) | |
68 | await pool.destroy() | |
69 | } | |
70 | }) | |
71 | ||
72 | it('Verify available strategies default internals at pool creation', async () => { | |
73 | const pool = new FixedThreadPool( | |
e843b904 JB |
74 | max, |
75 | './tests/worker-files/thread/testWorker.js' | |
76 | ) | |
594bfb84 JB |
77 | for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { |
78 | if (workerChoiceStrategy === WorkerChoiceStrategies.ROUND_ROBIN) { | |
79 | expect( | |
80 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
81 | workerChoiceStrategy | |
9b106837 | 82 | ).nextWorkerNodeKey |
594bfb84 JB |
83 | ).toBe(0) |
84 | } else if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) { | |
08f3f44c JB |
85 | expect( |
86 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
87 | workerChoiceStrategy | |
b0d6ed8f | 88 | ).workersVirtualTaskEndTimestamp |
08f3f44c JB |
89 | ).toBeInstanceOf(Array) |
90 | expect( | |
91 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
92 | workerChoiceStrategy | |
b0d6ed8f | 93 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 94 | ).toBe(0) |
594bfb84 JB |
95 | } else if ( |
96 | workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
97 | ) { | |
98 | expect( | |
99 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
100 | workerChoiceStrategy | |
9b106837 | 101 | ).nextWorkerNodeKey |
594bfb84 JB |
102 | ).toBe(0) |
103 | expect( | |
104 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
105 | workerChoiceStrategy | |
106 | ).defaultWorkerWeight | |
107 | ).toBeGreaterThan(0) | |
08f3f44c JB |
108 | expect( |
109 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
110 | workerChoiceStrategy | |
111 | ).workerVirtualTaskRunTime | |
112 | ).toBe(0) | |
594bfb84 JB |
113 | } |
114 | } | |
e843b904 JB |
115 | await pool.destroy() |
116 | }) | |
117 | ||
6c6afb84 JB |
118 | it('Verify ROUND_ROBIN strategy default policy', async () => { |
119 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN | |
120 | let pool = new FixedThreadPool( | |
121 | max, | |
122 | './tests/worker-files/thread/testWorker.js', | |
123 | { workerChoiceStrategy } | |
124 | ) | |
125 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
94407def | 126 | dynamicWorkerUsage: false, |
b1aae695 | 127 | dynamicWorkerReady: true |
6c6afb84 JB |
128 | }) |
129 | await pool.destroy() | |
130 | pool = new DynamicThreadPool( | |
131 | min, | |
132 | max, | |
133 | './tests/worker-files/thread/testWorker.js', | |
134 | { workerChoiceStrategy } | |
135 | ) | |
136 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
94407def | 137 | dynamicWorkerUsage: false, |
b1aae695 | 138 | dynamicWorkerReady: true |
6c6afb84 JB |
139 | }) |
140 | // We need to clean up the resources after our test | |
141 | await pool.destroy() | |
142 | }) | |
143 | ||
144 | it('Verify ROUND_ROBIN strategy default tasks statistics requirements', async () => { | |
594bfb84 | 145 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN |
10fcfaf4 JB |
146 | let pool = new FixedThreadPool( |
147 | max, | |
d710242d | 148 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 149 | { workerChoiceStrategy } |
10fcfaf4 | 150 | ) |
87de9ff5 JB |
151 | expect( |
152 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
153 | ).toStrictEqual({ | |
932fc8be JB |
154 | runTime: { |
155 | aggregate: false, | |
156 | average: false, | |
157 | median: false | |
158 | }, | |
159 | waitTime: { | |
160 | aggregate: false, | |
161 | average: false, | |
162 | median: false | |
163 | }, | |
5df69fab JB |
164 | elu: { |
165 | aggregate: false, | |
166 | average: false, | |
167 | median: false | |
168 | } | |
86bf340d | 169 | }) |
fd7ebd49 | 170 | await pool.destroy() |
10fcfaf4 JB |
171 | pool = new DynamicThreadPool( |
172 | min, | |
173 | max, | |
d710242d | 174 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 175 | { workerChoiceStrategy } |
10fcfaf4 | 176 | ) |
87de9ff5 JB |
177 | expect( |
178 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
179 | ).toStrictEqual({ | |
932fc8be JB |
180 | runTime: { |
181 | aggregate: false, | |
182 | average: false, | |
183 | median: false | |
184 | }, | |
185 | waitTime: { | |
186 | aggregate: false, | |
187 | average: false, | |
188 | median: false | |
189 | }, | |
5df69fab JB |
190 | elu: { |
191 | aggregate: false, | |
192 | average: false, | |
193 | median: false | |
194 | } | |
86bf340d | 195 | }) |
10fcfaf4 JB |
196 | // We need to clean up the resources after our test |
197 | await pool.destroy() | |
198 | }) | |
199 | ||
bdaf31cd | 200 | it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
bdaf31cd JB |
201 | const pool = new FixedThreadPool( |
202 | max, | |
203 | './tests/worker-files/thread/testWorker.js', | |
204 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
205 | ) | |
bdaf31cd | 206 | // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` |
ee9f5295 | 207 | const promises = new Set() |
a20f0ba5 JB |
208 | const maxMultiplier = 2 |
209 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 210 | promises.add(pool.execute()) |
e211bc18 JB |
211 | } |
212 | await Promise.all(promises) | |
213 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 214 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
215 | tasks: { |
216 | executed: maxMultiplier, | |
217 | executing: 0, | |
218 | queued: 0, | |
df593701 | 219 | maxQueued: 0, |
68cbdc84 | 220 | stolen: 0, |
a4e07f72 JB |
221 | failed: 0 |
222 | }, | |
223 | runTime: { | |
a4e07f72 JB |
224 | history: expect.any(CircularArray) |
225 | }, | |
226 | waitTime: { | |
a4e07f72 JB |
227 | history: expect.any(CircularArray) |
228 | }, | |
5df69fab JB |
229 | elu: { |
230 | idle: { | |
5df69fab JB |
231 | history: expect.any(CircularArray) |
232 | }, | |
233 | active: { | |
5df69fab | 234 | history: expect.any(CircularArray) |
71514351 | 235 | } |
5df69fab | 236 | } |
e211bc18 | 237 | }) |
bdaf31cd | 238 | } |
9458090a JB |
239 | expect( |
240 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
241 | WorkerChoiceStrategies.ROUND_ROBIN | |
9b106837 | 242 | ).nextWorkerNodeKey |
9458090a | 243 | ).toBe(0) |
bdaf31cd JB |
244 | // We need to clean up the resources after our test |
245 | await pool.destroy() | |
246 | }) | |
247 | ||
248 | it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
bdaf31cd JB |
249 | const pool = new DynamicThreadPool( |
250 | min, | |
251 | max, | |
252 | './tests/worker-files/thread/testWorker.js', | |
253 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
254 | ) | |
bdaf31cd | 255 | // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` |
ee9f5295 | 256 | const promises = new Set() |
a20f0ba5 JB |
257 | const maxMultiplier = 2 |
258 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 259 | promises.add(pool.execute()) |
e211bc18 JB |
260 | } |
261 | await Promise.all(promises) | |
262 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 263 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 264 | tasks: { |
94407def | 265 | executed: expect.any(Number), |
a4e07f72 JB |
266 | executing: 0, |
267 | queued: 0, | |
df593701 | 268 | maxQueued: 0, |
68cbdc84 | 269 | stolen: 0, |
a4e07f72 JB |
270 | failed: 0 |
271 | }, | |
272 | runTime: { | |
a4e07f72 JB |
273 | history: expect.any(CircularArray) |
274 | }, | |
275 | waitTime: { | |
a4e07f72 JB |
276 | history: expect.any(CircularArray) |
277 | }, | |
5df69fab JB |
278 | elu: { |
279 | idle: { | |
5df69fab JB |
280 | history: expect.any(CircularArray) |
281 | }, | |
282 | active: { | |
5df69fab | 283 | history: expect.any(CircularArray) |
71514351 | 284 | } |
5df69fab | 285 | } |
e211bc18 | 286 | }) |
94407def JB |
287 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
288 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
289 | max * maxMultiplier | |
290 | ) | |
bdaf31cd | 291 | } |
9458090a JB |
292 | expect( |
293 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
294 | WorkerChoiceStrategies.ROUND_ROBIN | |
9b106837 | 295 | ).nextWorkerNodeKey |
9458090a | 296 | ).toBe(0) |
bdaf31cd JB |
297 | // We need to clean up the resources after our test |
298 | await pool.destroy() | |
299 | }) | |
300 | ||
2ced693a | 301 | it('Verify ROUND_ROBIN strategy runtime behavior', async () => { |
594bfb84 | 302 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN |
2ced693a JB |
303 | let pool = new FixedClusterPool( |
304 | max, | |
594bfb84 JB |
305 | './tests/worker-files/cluster/testWorker.js', |
306 | { workerChoiceStrategy } | |
2ced693a JB |
307 | ) |
308 | let results = new Set() | |
309 | for (let i = 0; i < max; i++) { | |
20dcad1a | 310 | results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.id) |
2ced693a JB |
311 | } |
312 | expect(results.size).toBe(max) | |
313 | await pool.destroy() | |
594bfb84 JB |
314 | pool = new FixedThreadPool( |
315 | max, | |
316 | './tests/worker-files/thread/testWorker.js', | |
317 | { workerChoiceStrategy } | |
318 | ) | |
2ced693a JB |
319 | results = new Set() |
320 | for (let i = 0; i < max; i++) { | |
20dcad1a | 321 | results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.threadId) |
2ced693a JB |
322 | } |
323 | expect(results.size).toBe(max) | |
324 | await pool.destroy() | |
325 | }) | |
326 | ||
a6f7f1b4 | 327 | it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => { |
594bfb84 | 328 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN |
a6f7f1b4 JB |
329 | let pool = new FixedThreadPool( |
330 | max, | |
331 | './tests/worker-files/thread/testWorker.js', | |
332 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
333 | ) | |
38f6e859 | 334 | expect( |
95c83464 | 335 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 336 | workerChoiceStrategy |
9b106837 | 337 | ).nextWorkerNodeKey |
b529c323 | 338 | ).toBeDefined() |
594bfb84 | 339 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 340 | expect( |
95c83464 | 341 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 342 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 343 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
344 | ).toBe(0) |
345 | await pool.destroy() | |
346 | pool = new DynamicThreadPool( | |
347 | min, | |
348 | max, | |
349 | './tests/worker-files/thread/testWorker.js', | |
350 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
351 | ) | |
38f6e859 | 352 | expect( |
95c83464 | 353 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 354 | workerChoiceStrategy |
9b106837 | 355 | ).nextWorkerNodeKey |
b529c323 | 356 | ).toBeDefined() |
594bfb84 | 357 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 358 | expect( |
95c83464 | 359 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 360 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 361 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
362 | ).toBe(0) |
363 | // We need to clean up the resources after our test | |
364 | await pool.destroy() | |
365 | }) | |
366 | ||
6c6afb84 JB |
367 | it('Verify LEAST_USED strategy default policy', async () => { |
368 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED | |
369 | let pool = new FixedThreadPool( | |
370 | max, | |
371 | './tests/worker-files/thread/testWorker.js', | |
372 | { workerChoiceStrategy } | |
373 | ) | |
374 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
375 | dynamicWorkerUsage: false, |
376 | dynamicWorkerReady: true | |
6c6afb84 JB |
377 | }) |
378 | await pool.destroy() | |
379 | pool = new DynamicThreadPool( | |
380 | min, | |
381 | max, | |
382 | './tests/worker-files/thread/testWorker.js', | |
383 | { workerChoiceStrategy } | |
384 | ) | |
385 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
386 | dynamicWorkerUsage: false, |
387 | dynamicWorkerReady: true | |
6c6afb84 JB |
388 | }) |
389 | // We need to clean up the resources after our test | |
390 | await pool.destroy() | |
391 | }) | |
392 | ||
393 | it('Verify LEAST_USED strategy default tasks statistics requirements', async () => { | |
e4543b14 | 394 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED |
10fcfaf4 JB |
395 | let pool = new FixedThreadPool( |
396 | max, | |
d710242d | 397 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 398 | { workerChoiceStrategy } |
10fcfaf4 | 399 | ) |
87de9ff5 JB |
400 | expect( |
401 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
402 | ).toStrictEqual({ | |
932fc8be JB |
403 | runTime: { |
404 | aggregate: false, | |
405 | average: false, | |
406 | median: false | |
407 | }, | |
408 | waitTime: { | |
409 | aggregate: false, | |
410 | average: false, | |
411 | median: false | |
412 | }, | |
5df69fab JB |
413 | elu: { |
414 | aggregate: false, | |
415 | average: false, | |
416 | median: false | |
417 | } | |
86bf340d | 418 | }) |
fd7ebd49 | 419 | await pool.destroy() |
10fcfaf4 JB |
420 | pool = new DynamicThreadPool( |
421 | min, | |
422 | max, | |
d710242d | 423 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 424 | { workerChoiceStrategy } |
10fcfaf4 | 425 | ) |
87de9ff5 JB |
426 | expect( |
427 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
428 | ).toStrictEqual({ | |
932fc8be JB |
429 | runTime: { |
430 | aggregate: false, | |
431 | average: false, | |
432 | median: false | |
433 | }, | |
434 | waitTime: { | |
435 | aggregate: false, | |
436 | average: false, | |
437 | median: false | |
438 | }, | |
5df69fab JB |
439 | elu: { |
440 | aggregate: false, | |
441 | average: false, | |
442 | median: false | |
443 | } | |
86bf340d | 444 | }) |
10fcfaf4 JB |
445 | // We need to clean up the resources after our test |
446 | await pool.destroy() | |
447 | }) | |
448 | ||
e4543b14 | 449 | it('Verify LEAST_USED strategy can be run in a fixed pool', async () => { |
b98ec2e6 JB |
450 | const pool = new FixedThreadPool( |
451 | max, | |
452 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 453 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED } |
b98ec2e6 | 454 | ) |
e4543b14 | 455 | // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose` |
ee9f5295 | 456 | const promises = new Set() |
a20f0ba5 JB |
457 | const maxMultiplier = 2 |
458 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 459 | promises.add(pool.execute()) |
e211bc18 JB |
460 | } |
461 | await Promise.all(promises) | |
462 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 463 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 464 | tasks: { |
76407b8e | 465 | executed: expect.any(Number), |
a4e07f72 JB |
466 | executing: 0, |
467 | queued: 0, | |
df593701 | 468 | maxQueued: 0, |
68cbdc84 | 469 | stolen: 0, |
a4e07f72 JB |
470 | failed: 0 |
471 | }, | |
472 | runTime: { | |
a4e07f72 JB |
473 | history: expect.any(CircularArray) |
474 | }, | |
475 | waitTime: { | |
a4e07f72 JB |
476 | history: expect.any(CircularArray) |
477 | }, | |
5df69fab JB |
478 | elu: { |
479 | idle: { | |
5df69fab JB |
480 | history: expect.any(CircularArray) |
481 | }, | |
482 | active: { | |
5df69fab | 483 | history: expect.any(CircularArray) |
71514351 | 484 | } |
5df69fab | 485 | } |
e211bc18 | 486 | }) |
465b2940 JB |
487 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
488 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
76407b8e JB |
489 | max * maxMultiplier |
490 | ) | |
a35560ba | 491 | } |
a35560ba S |
492 | // We need to clean up the resources after our test |
493 | await pool.destroy() | |
494 | }) | |
495 | ||
e4543b14 | 496 | it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => { |
ff5e76e1 JB |
497 | const pool = new DynamicThreadPool( |
498 | min, | |
499 | max, | |
500 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 501 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED } |
ff5e76e1 | 502 | ) |
e4543b14 | 503 | // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose` |
ee9f5295 | 504 | const promises = new Set() |
a20f0ba5 JB |
505 | const maxMultiplier = 2 |
506 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 507 | promises.add(pool.execute()) |
e211bc18 JB |
508 | } |
509 | await Promise.all(promises) | |
510 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 511 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 512 | tasks: { |
76407b8e | 513 | executed: expect.any(Number), |
a4e07f72 JB |
514 | executing: 0, |
515 | queued: 0, | |
df593701 | 516 | maxQueued: 0, |
68cbdc84 | 517 | stolen: 0, |
a4e07f72 JB |
518 | failed: 0 |
519 | }, | |
520 | runTime: { | |
a4e07f72 JB |
521 | history: expect.any(CircularArray) |
522 | }, | |
523 | waitTime: { | |
a4e07f72 JB |
524 | history: expect.any(CircularArray) |
525 | }, | |
5df69fab JB |
526 | elu: { |
527 | idle: { | |
5df69fab JB |
528 | history: expect.any(CircularArray) |
529 | }, | |
530 | active: { | |
5df69fab | 531 | history: expect.any(CircularArray) |
71514351 | 532 | } |
5df69fab | 533 | } |
e211bc18 | 534 | }) |
465b2940 JB |
535 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
536 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
76407b8e JB |
537 | max * maxMultiplier |
538 | ) | |
168c526f | 539 | } |
168c526f JB |
540 | // We need to clean up the resources after our test |
541 | await pool.destroy() | |
542 | }) | |
543 | ||
6c6afb84 JB |
544 | it('Verify LEAST_BUSY strategy default policy', async () => { |
545 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY | |
546 | let pool = new FixedThreadPool( | |
547 | max, | |
548 | './tests/worker-files/thread/testWorker.js', | |
549 | { workerChoiceStrategy } | |
550 | ) | |
551 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
552 | dynamicWorkerUsage: false, |
553 | dynamicWorkerReady: true | |
6c6afb84 JB |
554 | }) |
555 | await pool.destroy() | |
556 | pool = new DynamicThreadPool( | |
557 | min, | |
558 | max, | |
559 | './tests/worker-files/thread/testWorker.js', | |
560 | { workerChoiceStrategy } | |
561 | ) | |
562 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
563 | dynamicWorkerUsage: false, |
564 | dynamicWorkerReady: true | |
6c6afb84 JB |
565 | }) |
566 | // We need to clean up the resources after our test | |
567 | await pool.destroy() | |
568 | }) | |
569 | ||
570 | it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => { | |
e4543b14 | 571 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY |
168c526f JB |
572 | let pool = new FixedThreadPool( |
573 | max, | |
d710242d | 574 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 575 | { workerChoiceStrategy } |
168c526f | 576 | ) |
87de9ff5 JB |
577 | expect( |
578 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
579 | ).toStrictEqual({ | |
932fc8be JB |
580 | runTime: { |
581 | aggregate: true, | |
582 | average: false, | |
583 | median: false | |
584 | }, | |
585 | waitTime: { | |
586 | aggregate: true, | |
587 | average: false, | |
588 | median: false | |
589 | }, | |
5df69fab JB |
590 | elu: { |
591 | aggregate: false, | |
592 | average: false, | |
593 | median: false | |
594 | } | |
86bf340d | 595 | }) |
168c526f JB |
596 | await pool.destroy() |
597 | pool = new DynamicThreadPool( | |
598 | min, | |
599 | max, | |
d710242d | 600 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 601 | { workerChoiceStrategy } |
168c526f | 602 | ) |
87de9ff5 JB |
603 | expect( |
604 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
605 | ).toStrictEqual({ | |
932fc8be JB |
606 | runTime: { |
607 | aggregate: true, | |
608 | average: false, | |
609 | median: false | |
610 | }, | |
611 | waitTime: { | |
612 | aggregate: true, | |
613 | average: false, | |
614 | median: false | |
615 | }, | |
5df69fab JB |
616 | elu: { |
617 | aggregate: false, | |
618 | average: false, | |
619 | median: false | |
620 | } | |
86bf340d | 621 | }) |
168c526f JB |
622 | // We need to clean up the resources after our test |
623 | await pool.destroy() | |
624 | }) | |
625 | ||
e4543b14 | 626 | it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => { |
168c526f JB |
627 | const pool = new FixedThreadPool( |
628 | max, | |
629 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 630 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY } |
168c526f | 631 | ) |
e4543b14 | 632 | // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose` |
ee9f5295 | 633 | const promises = new Set() |
a20f0ba5 JB |
634 | const maxMultiplier = 2 |
635 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 636 | promises.add(pool.execute()) |
e211bc18 JB |
637 | } |
638 | await Promise.all(promises) | |
639 | for (const workerNode of pool.workerNodes) { | |
19dbc45b | 640 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 JB |
641 | tasks: { |
642 | executed: expect.any(Number), | |
643 | executing: 0, | |
644 | queued: 0, | |
df593701 | 645 | maxQueued: 0, |
68cbdc84 | 646 | stolen: 0, |
a4e07f72 JB |
647 | failed: 0 |
648 | }, | |
649 | runTime: { | |
a4e07f72 JB |
650 | history: expect.any(CircularArray) |
651 | }, | |
652 | waitTime: { | |
a4e07f72 JB |
653 | history: expect.any(CircularArray) |
654 | }, | |
5df69fab JB |
655 | elu: { |
656 | idle: { | |
5df69fab JB |
657 | history: expect.any(CircularArray) |
658 | }, | |
659 | active: { | |
5df69fab | 660 | history: expect.any(CircularArray) |
71514351 | 661 | } |
5df69fab | 662 | } |
e211bc18 | 663 | }) |
465b2940 JB |
664 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
665 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
666 | max * maxMultiplier |
667 | ) | |
19dbc45b JB |
668 | if (workerNode.usage.runTime.aggregate == null) { |
669 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
670 | } else { | |
671 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
672 | } | |
673 | if (workerNode.usage.waitTime.aggregate == null) { | |
674 | expect(workerNode.usage.waitTime.aggregate).toBeUndefined() | |
675 | } else { | |
676 | expect(workerNode.usage.waitTime.aggregate).toBeGreaterThan(0) | |
677 | } | |
168c526f | 678 | } |
168c526f JB |
679 | // We need to clean up the resources after our test |
680 | await pool.destroy() | |
681 | }) | |
682 | ||
e4543b14 | 683 | it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => { |
168c526f JB |
684 | const pool = new DynamicThreadPool( |
685 | min, | |
686 | max, | |
687 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 688 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY } |
168c526f | 689 | ) |
e4543b14 | 690 | // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose` |
ee9f5295 | 691 | const promises = new Set() |
a20f0ba5 JB |
692 | const maxMultiplier = 2 |
693 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 694 | promises.add(pool.execute()) |
e211bc18 JB |
695 | } |
696 | await Promise.all(promises) | |
697 | for (const workerNode of pool.workerNodes) { | |
19dbc45b | 698 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 JB |
699 | tasks: { |
700 | executed: expect.any(Number), | |
701 | executing: 0, | |
702 | queued: 0, | |
df593701 | 703 | maxQueued: 0, |
68cbdc84 | 704 | stolen: 0, |
a4e07f72 JB |
705 | failed: 0 |
706 | }, | |
707 | runTime: { | |
a4e07f72 JB |
708 | history: expect.any(CircularArray) |
709 | }, | |
710 | waitTime: { | |
a4e07f72 JB |
711 | history: expect.any(CircularArray) |
712 | }, | |
5df69fab JB |
713 | elu: { |
714 | idle: { | |
5df69fab JB |
715 | history: expect.any(CircularArray) |
716 | }, | |
717 | active: { | |
5df69fab | 718 | history: expect.any(CircularArray) |
71514351 | 719 | } |
5df69fab | 720 | } |
e211bc18 | 721 | }) |
465b2940 JB |
722 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
723 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
724 | max * maxMultiplier |
725 | ) | |
19dbc45b JB |
726 | if (workerNode.usage.runTime.aggregate == null) { |
727 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
728 | } else { | |
729 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
730 | } | |
731 | if (workerNode.usage.waitTime.aggregate == null) { | |
732 | expect(workerNode.usage.waitTime.aggregate).toBeUndefined() | |
733 | } else { | |
734 | expect(workerNode.usage.waitTime.aggregate).toBeGreaterThan(0) | |
735 | } | |
ff5e76e1 | 736 | } |
ff5e76e1 JB |
737 | // We need to clean up the resources after our test |
738 | await pool.destroy() | |
739 | }) | |
740 | ||
6c6afb84 JB |
741 | it('Verify LEAST_ELU strategy default policy', async () => { |
742 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU | |
743 | let pool = new FixedThreadPool( | |
744 | max, | |
745 | './tests/worker-files/thread/testWorker.js', | |
746 | { workerChoiceStrategy } | |
747 | ) | |
748 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
749 | dynamicWorkerUsage: false, |
750 | dynamicWorkerReady: true | |
6c6afb84 JB |
751 | }) |
752 | await pool.destroy() | |
753 | pool = new DynamicThreadPool( | |
754 | min, | |
755 | max, | |
756 | './tests/worker-files/thread/testWorker.js', | |
757 | { workerChoiceStrategy } | |
758 | ) | |
759 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
760 | dynamicWorkerUsage: false, |
761 | dynamicWorkerReady: true | |
6c6afb84 JB |
762 | }) |
763 | // We need to clean up the resources after our test | |
764 | await pool.destroy() | |
765 | }) | |
766 | ||
767 | it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => { | |
a7bbf44a JB |
768 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU |
769 | let pool = new FixedThreadPool( | |
770 | max, | |
771 | './tests/worker-files/thread/testWorker.js', | |
772 | { workerChoiceStrategy } | |
773 | ) | |
05302647 JB |
774 | expect( |
775 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
776 | ).toStrictEqual({ | |
e460940e JB |
777 | runTime: { |
778 | aggregate: false, | |
779 | average: false, | |
780 | median: false | |
781 | }, | |
782 | waitTime: { | |
783 | aggregate: false, | |
784 | average: false, | |
785 | median: false | |
786 | }, | |
5df69fab JB |
787 | elu: { |
788 | aggregate: true, | |
789 | average: false, | |
790 | median: false | |
791 | } | |
a7bbf44a JB |
792 | }) |
793 | await pool.destroy() | |
794 | pool = new DynamicThreadPool( | |
795 | min, | |
796 | max, | |
797 | './tests/worker-files/thread/testWorker.js', | |
798 | { workerChoiceStrategy } | |
799 | ) | |
05302647 JB |
800 | expect( |
801 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
802 | ).toStrictEqual({ | |
e460940e JB |
803 | runTime: { |
804 | aggregate: false, | |
805 | average: false, | |
806 | median: false | |
807 | }, | |
808 | waitTime: { | |
809 | aggregate: false, | |
810 | average: false, | |
811 | median: false | |
812 | }, | |
5df69fab JB |
813 | elu: { |
814 | aggregate: true, | |
815 | average: false, | |
816 | median: false | |
817 | } | |
a7bbf44a JB |
818 | }) |
819 | // We need to clean up the resources after our test | |
820 | await pool.destroy() | |
821 | }) | |
822 | ||
ae9cf3c8 | 823 | it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => { |
c5ad42cd JB |
824 | const pool = new FixedThreadPool( |
825 | max, | |
826 | './tests/worker-files/thread/testWorker.js', | |
827 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_ELU } | |
828 | ) | |
829 | // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose` | |
dd38581f | 830 | const promises = new Set() |
c5ad42cd JB |
831 | const maxMultiplier = 2 |
832 | for (let i = 0; i < max * maxMultiplier; i++) { | |
dd38581f | 833 | promises.add(pool.execute()) |
c5ad42cd | 834 | } |
dd38581f | 835 | await Promise.all(promises) |
c5ad42cd | 836 | for (const workerNode of pool.workerNodes) { |
71514351 | 837 | expect(workerNode.usage).toMatchObject({ |
c5ad42cd JB |
838 | tasks: { |
839 | executed: expect.any(Number), | |
840 | executing: 0, | |
841 | queued: 0, | |
df593701 | 842 | maxQueued: 0, |
68cbdc84 | 843 | stolen: 0, |
c5ad42cd JB |
844 | failed: 0 |
845 | }, | |
846 | runTime: { | |
c5ad42cd | 847 | history: expect.any(CircularArray) |
a1347286 JB |
848 | }, |
849 | waitTime: { | |
a1347286 | 850 | history: expect.any(CircularArray) |
5df69fab JB |
851 | }, |
852 | elu: { | |
68cbdc84 | 853 | idle: { |
5df69fab | 854 | history: expect.any(CircularArray) |
68cbdc84 JB |
855 | }, |
856 | active: { | |
5df69fab | 857 | history: expect.any(CircularArray) |
68cbdc84 | 858 | } |
a1347286 | 859 | } |
5df69fab | 860 | }) |
465b2940 JB |
861 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
862 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a1347286 JB |
863 | max * maxMultiplier |
864 | ) | |
71514351 JB |
865 | if (workerNode.usage.elu.utilization == null) { |
866 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
867 | } else { | |
868 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
869 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
870 | } | |
a1347286 JB |
871 | } |
872 | // We need to clean up the resources after our test | |
873 | await pool.destroy() | |
874 | }) | |
875 | ||
876 | it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => { | |
877 | const pool = new DynamicThreadPool( | |
878 | min, | |
879 | max, | |
880 | './tests/worker-files/thread/testWorker.js', | |
881 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_ELU } | |
882 | ) | |
883 | // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose` | |
dd38581f | 884 | const promises = new Set() |
a1347286 JB |
885 | const maxMultiplier = 2 |
886 | for (let i = 0; i < max * maxMultiplier; i++) { | |
dd38581f | 887 | promises.add(pool.execute()) |
a1347286 | 888 | } |
dd38581f | 889 | await Promise.all(promises) |
a1347286 | 890 | for (const workerNode of pool.workerNodes) { |
71514351 | 891 | expect(workerNode.usage).toMatchObject({ |
a1347286 JB |
892 | tasks: { |
893 | executed: expect.any(Number), | |
894 | executing: 0, | |
895 | queued: 0, | |
df593701 | 896 | maxQueued: 0, |
68cbdc84 | 897 | stolen: 0, |
a1347286 JB |
898 | failed: 0 |
899 | }, | |
900 | runTime: { | |
a1347286 | 901 | history: expect.any(CircularArray) |
c5ad42cd JB |
902 | }, |
903 | waitTime: { | |
c5ad42cd | 904 | history: expect.any(CircularArray) |
5df69fab JB |
905 | }, |
906 | elu: { | |
68cbdc84 | 907 | idle: { |
5df69fab | 908 | history: expect.any(CircularArray) |
68cbdc84 JB |
909 | }, |
910 | active: { | |
5df69fab | 911 | history: expect.any(CircularArray) |
68cbdc84 | 912 | } |
c5ad42cd | 913 | } |
5df69fab | 914 | }) |
465b2940 JB |
915 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
916 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
c5ad42cd JB |
917 | max * maxMultiplier |
918 | ) | |
71514351 JB |
919 | if (workerNode.usage.elu.utilization == null) { |
920 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
921 | } else { | |
922 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
923 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
924 | } | |
c5ad42cd JB |
925 | } |
926 | // We need to clean up the resources after our test | |
927 | await pool.destroy() | |
928 | }) | |
929 | ||
6c6afb84 JB |
930 | it('Verify FAIR_SHARE strategy default policy', async () => { |
931 | const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE | |
932 | let pool = new FixedThreadPool( | |
933 | max, | |
934 | './tests/worker-files/thread/testWorker.js', | |
935 | { workerChoiceStrategy } | |
936 | ) | |
937 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
938 | dynamicWorkerUsage: false, |
939 | dynamicWorkerReady: true | |
6c6afb84 JB |
940 | }) |
941 | await pool.destroy() | |
942 | pool = new DynamicThreadPool( | |
943 | min, | |
944 | max, | |
945 | './tests/worker-files/thread/testWorker.js', | |
946 | { workerChoiceStrategy } | |
947 | ) | |
948 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
949 | dynamicWorkerUsage: false, |
950 | dynamicWorkerReady: true | |
6c6afb84 JB |
951 | }) |
952 | // We need to clean up the resources after our test | |
953 | await pool.destroy() | |
954 | }) | |
955 | ||
956 | it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => { | |
594bfb84 | 957 | const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE |
10fcfaf4 JB |
958 | let pool = new FixedThreadPool( |
959 | max, | |
d710242d | 960 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 961 | { workerChoiceStrategy } |
10fcfaf4 | 962 | ) |
87de9ff5 JB |
963 | expect( |
964 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
965 | ).toStrictEqual({ | |
932fc8be JB |
966 | runTime: { |
967 | aggregate: true, | |
968 | average: true, | |
969 | median: false | |
970 | }, | |
971 | waitTime: { | |
972 | aggregate: false, | |
973 | average: false, | |
974 | median: false | |
975 | }, | |
5df69fab | 976 | elu: { |
9adcefab JB |
977 | aggregate: true, |
978 | average: true, | |
5df69fab JB |
979 | median: false |
980 | } | |
86bf340d | 981 | }) |
fd7ebd49 | 982 | await pool.destroy() |
10fcfaf4 JB |
983 | pool = new DynamicThreadPool( |
984 | min, | |
985 | max, | |
d710242d | 986 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 987 | { workerChoiceStrategy } |
10fcfaf4 | 988 | ) |
87de9ff5 JB |
989 | expect( |
990 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
991 | ).toStrictEqual({ | |
932fc8be JB |
992 | runTime: { |
993 | aggregate: true, | |
994 | average: true, | |
995 | median: false | |
996 | }, | |
997 | waitTime: { | |
998 | aggregate: false, | |
999 | average: false, | |
1000 | median: false | |
1001 | }, | |
5df69fab | 1002 | elu: { |
9adcefab JB |
1003 | aggregate: true, |
1004 | average: true, | |
5df69fab JB |
1005 | median: false |
1006 | } | |
86bf340d | 1007 | }) |
10fcfaf4 JB |
1008 | // We need to clean up the resources after our test |
1009 | await pool.destroy() | |
1010 | }) | |
1011 | ||
23ff945a | 1012 | it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => { |
23ff945a JB |
1013 | const pool = new FixedThreadPool( |
1014 | max, | |
1015 | './tests/worker-files/thread/testWorker.js', | |
1016 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
1017 | ) | |
1018 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
ee9f5295 | 1019 | const promises = new Set() |
a20f0ba5 JB |
1020 | const maxMultiplier = 2 |
1021 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1022 | promises.add(pool.execute()) |
23ff945a | 1023 | } |
e211bc18 | 1024 | await Promise.all(promises) |
138d29a8 | 1025 | for (const workerNode of pool.workerNodes) { |
71514351 | 1026 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 | 1027 | tasks: { |
d33be430 | 1028 | executed: expect.any(Number), |
a4e07f72 JB |
1029 | executing: 0, |
1030 | queued: 0, | |
df593701 | 1031 | maxQueued: 0, |
68cbdc84 | 1032 | stolen: 0, |
a4e07f72 JB |
1033 | failed: 0 |
1034 | }, | |
68cbdc84 | 1035 | runTime: { |
a4e07f72 | 1036 | history: expect.any(CircularArray) |
68cbdc84 | 1037 | }, |
a4e07f72 | 1038 | waitTime: { |
a4e07f72 JB |
1039 | history: expect.any(CircularArray) |
1040 | }, | |
5df69fab | 1041 | elu: { |
68cbdc84 | 1042 | idle: { |
5df69fab | 1043 | history: expect.any(CircularArray) |
68cbdc84 JB |
1044 | }, |
1045 | active: { | |
5df69fab | 1046 | history: expect.any(CircularArray) |
68cbdc84 | 1047 | } |
5df69fab | 1048 | } |
86bf340d | 1049 | }) |
465b2940 JB |
1050 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1051 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
d33be430 JB |
1052 | max * maxMultiplier |
1053 | ) | |
71514351 JB |
1054 | if (workerNode.usage.runTime.aggregate == null) { |
1055 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1056 | } else { | |
1057 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1058 | } | |
1059 | if (workerNode.usage.runTime.average == null) { | |
1060 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1061 | } else { | |
1062 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1063 | } | |
1064 | if (workerNode.usage.elu.utilization == null) { | |
1065 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
1066 | } else { | |
1067 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
1068 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
1069 | } | |
138d29a8 | 1070 | } |
97a2abc3 | 1071 | expect( |
95c83464 | 1072 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1073 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
b0d6ed8f | 1074 | ).workersVirtualTaskEndTimestamp.length |
f06e48d8 | 1075 | ).toBe(pool.workerNodes.length) |
23ff945a JB |
1076 | // We need to clean up the resources after our test |
1077 | await pool.destroy() | |
1078 | }) | |
1079 | ||
1080 | it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => { | |
23ff945a JB |
1081 | const pool = new DynamicThreadPool( |
1082 | min, | |
1083 | max, | |
1084 | './tests/worker-files/thread/testWorker.js', | |
1085 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
1086 | ) | |
1087 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
ee9f5295 | 1088 | const promises = new Set() |
f7070eee | 1089 | const maxMultiplier = 2 |
804a889e | 1090 | for (let i = 0; i < max * maxMultiplier; i++) { |
ee9f5295 | 1091 | promises.add(pool.execute()) |
23ff945a | 1092 | } |
e211bc18 | 1093 | await Promise.all(promises) |
138d29a8 | 1094 | for (const workerNode of pool.workerNodes) { |
71514351 | 1095 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 | 1096 | tasks: { |
6c6afb84 | 1097 | executed: expect.any(Number), |
a4e07f72 JB |
1098 | executing: 0, |
1099 | queued: 0, | |
df593701 | 1100 | maxQueued: 0, |
68cbdc84 | 1101 | stolen: 0, |
a4e07f72 JB |
1102 | failed: 0 |
1103 | }, | |
68cbdc84 | 1104 | runTime: { |
a4e07f72 | 1105 | history: expect.any(CircularArray) |
68cbdc84 | 1106 | }, |
a4e07f72 | 1107 | waitTime: { |
a4e07f72 JB |
1108 | history: expect.any(CircularArray) |
1109 | }, | |
5df69fab | 1110 | elu: { |
68cbdc84 | 1111 | idle: { |
5df69fab | 1112 | history: expect.any(CircularArray) |
68cbdc84 JB |
1113 | }, |
1114 | active: { | |
5df69fab | 1115 | history: expect.any(CircularArray) |
68cbdc84 | 1116 | } |
5df69fab | 1117 | } |
86bf340d | 1118 | }) |
465b2940 JB |
1119 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1120 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
6c6afb84 JB |
1121 | max * maxMultiplier |
1122 | ) | |
71514351 JB |
1123 | if (workerNode.usage.runTime.aggregate == null) { |
1124 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1125 | } else { | |
1126 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1127 | } | |
1128 | if (workerNode.usage.runTime.average == null) { | |
1129 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1130 | } else { | |
1131 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1132 | } | |
1133 | if (workerNode.usage.elu.utilization == null) { | |
1134 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
1135 | } else { | |
1136 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
1137 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
1138 | } | |
138d29a8 | 1139 | } |
2b4fddb8 JB |
1140 | expect( |
1141 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1142 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
b0d6ed8f | 1143 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1144 | ).toBe(pool.workerNodes.length) |
23ff945a JB |
1145 | // We need to clean up the resources after our test |
1146 | await pool.destroy() | |
1147 | }) | |
1148 | ||
9e775f96 | 1149 | it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => { |
010d7020 JB |
1150 | const pool = new DynamicThreadPool( |
1151 | min, | |
1152 | max, | |
1153 | './tests/worker-files/thread/testWorker.js', | |
1154 | { | |
1155 | workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE, | |
1156 | workerChoiceStrategyOptions: { | |
932fc8be | 1157 | runTime: { median: true } |
010d7020 JB |
1158 | } |
1159 | } | |
1160 | ) | |
1161 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
ee9f5295 | 1162 | const promises = new Set() |
010d7020 JB |
1163 | const maxMultiplier = 2 |
1164 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1165 | promises.add(pool.execute()) |
010d7020 | 1166 | } |
e211bc18 | 1167 | await Promise.all(promises) |
010d7020 | 1168 | for (const workerNode of pool.workerNodes) { |
71514351 | 1169 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 | 1170 | tasks: { |
6c6afb84 | 1171 | executed: expect.any(Number), |
a4e07f72 JB |
1172 | executing: 0, |
1173 | queued: 0, | |
df593701 | 1174 | maxQueued: 0, |
68cbdc84 | 1175 | stolen: 0, |
a4e07f72 JB |
1176 | failed: 0 |
1177 | }, | |
68cbdc84 | 1178 | runTime: { |
a4e07f72 | 1179 | history: expect.any(CircularArray) |
68cbdc84 | 1180 | }, |
a4e07f72 | 1181 | waitTime: { |
a4e07f72 JB |
1182 | history: expect.any(CircularArray) |
1183 | }, | |
5df69fab | 1184 | elu: { |
68cbdc84 | 1185 | idle: { |
5df69fab | 1186 | history: expect.any(CircularArray) |
68cbdc84 JB |
1187 | }, |
1188 | active: { | |
5df69fab | 1189 | history: expect.any(CircularArray) |
68cbdc84 | 1190 | } |
5df69fab | 1191 | } |
86bf340d | 1192 | }) |
465b2940 JB |
1193 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1194 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
6c6afb84 JB |
1195 | max * maxMultiplier |
1196 | ) | |
71514351 JB |
1197 | if (workerNode.usage.runTime.aggregate == null) { |
1198 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1199 | } else { | |
1200 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1201 | } | |
1202 | if (workerNode.usage.runTime.median == null) { | |
1203 | expect(workerNode.usage.runTime.median).toBeUndefined() | |
1204 | } else { | |
1205 | expect(workerNode.usage.runTime.median).toBeGreaterThan(0) | |
1206 | } | |
1207 | if (workerNode.usage.elu.utilization == null) { | |
1208 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
1209 | } else { | |
1210 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
1211 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
1212 | } | |
010d7020 | 1213 | } |
2b4fddb8 JB |
1214 | expect( |
1215 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1216 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
b0d6ed8f | 1217 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1218 | ).toBe(pool.workerNodes.length) |
010d7020 JB |
1219 | // We need to clean up the resources after our test |
1220 | await pool.destroy() | |
1221 | }) | |
1222 | ||
a6f7f1b4 | 1223 | it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => { |
594bfb84 | 1224 | const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE |
f0829c53 | 1225 | let pool = new FixedThreadPool( |
caeb9817 JB |
1226 | max, |
1227 | './tests/worker-files/thread/testWorker.js' | |
1228 | ) | |
1229 | expect( | |
95c83464 | 1230 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1231 | workerChoiceStrategy |
b0d6ed8f | 1232 | ).workersVirtualTaskEndTimestamp |
08f3f44c JB |
1233 | ).toBeInstanceOf(Array) |
1234 | expect( | |
1235 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1236 | workerChoiceStrategy | |
b0d6ed8f | 1237 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 1238 | ).toBe(0) |
2b4fddb8 JB |
1239 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
1240 | workerChoiceStrategy | |
b0d6ed8f | 1241 | ).workersVirtualTaskEndTimestamp[0] = performance.now() |
2b4fddb8 JB |
1242 | expect( |
1243 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1244 | workerChoiceStrategy | |
b0d6ed8f | 1245 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1246 | ).toBe(1) |
594bfb84 | 1247 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
08f3f44c JB |
1248 | expect( |
1249 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1250 | workerChoiceStrategy | |
b0d6ed8f | 1251 | ).workersVirtualTaskEndTimestamp |
08f3f44c | 1252 | ).toBeInstanceOf(Array) |
08f3f44c JB |
1253 | expect( |
1254 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1255 | workerChoiceStrategy | |
b0d6ed8f | 1256 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1257 | ).toBe(0) |
f0829c53 JB |
1258 | await pool.destroy() |
1259 | pool = new DynamicThreadPool( | |
1260 | min, | |
1261 | max, | |
1262 | './tests/worker-files/thread/testWorker.js' | |
1263 | ) | |
1264 | expect( | |
95c83464 | 1265 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1266 | workerChoiceStrategy |
b0d6ed8f | 1267 | ).workersVirtualTaskEndTimestamp |
08f3f44c | 1268 | ).toBeInstanceOf(Array) |
2b4fddb8 JB |
1269 | expect( |
1270 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1271 | workerChoiceStrategy | |
b0d6ed8f | 1272 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1273 | ).toBe(0) |
08f3f44c JB |
1274 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
1275 | workerChoiceStrategy | |
b0d6ed8f | 1276 | ).workersVirtualTaskEndTimestamp[0] = performance.now() |
08f3f44c JB |
1277 | expect( |
1278 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1279 | workerChoiceStrategy | |
b0d6ed8f | 1280 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 1281 | ).toBe(1) |
594bfb84 | 1282 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
08f3f44c JB |
1283 | expect( |
1284 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1285 | workerChoiceStrategy | |
b0d6ed8f | 1286 | ).workersVirtualTaskEndTimestamp |
08f3f44c JB |
1287 | ).toBeInstanceOf(Array) |
1288 | expect( | |
1289 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1290 | workerChoiceStrategy | |
b0d6ed8f | 1291 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 1292 | ).toBe(0) |
caeb9817 JB |
1293 | // We need to clean up the resources after our test |
1294 | await pool.destroy() | |
1295 | }) | |
1296 | ||
6c6afb84 JB |
1297 | it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => { |
1298 | const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
1299 | let pool = new FixedThreadPool( | |
1300 | max, | |
1301 | './tests/worker-files/thread/testWorker.js', | |
1302 | { workerChoiceStrategy } | |
1303 | ) | |
1304 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1305 | dynamicWorkerUsage: false, |
1306 | dynamicWorkerReady: true | |
6c6afb84 JB |
1307 | }) |
1308 | await pool.destroy() | |
1309 | pool = new DynamicThreadPool( | |
1310 | min, | |
1311 | max, | |
1312 | './tests/worker-files/thread/testWorker.js', | |
1313 | { workerChoiceStrategy } | |
1314 | ) | |
1315 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1316 | dynamicWorkerUsage: false, |
1317 | dynamicWorkerReady: true | |
6c6afb84 JB |
1318 | }) |
1319 | // We need to clean up the resources after our test | |
1320 | await pool.destroy() | |
1321 | }) | |
1322 | ||
1323 | it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => { | |
594bfb84 | 1324 | const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN |
10fcfaf4 JB |
1325 | let pool = new FixedThreadPool( |
1326 | max, | |
d710242d | 1327 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 1328 | { workerChoiceStrategy } |
10fcfaf4 | 1329 | ) |
87de9ff5 JB |
1330 | expect( |
1331 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1332 | ).toStrictEqual({ | |
932fc8be JB |
1333 | runTime: { |
1334 | aggregate: true, | |
1335 | average: true, | |
1336 | median: false | |
1337 | }, | |
1338 | waitTime: { | |
1339 | aggregate: false, | |
1340 | average: false, | |
1341 | median: false | |
1342 | }, | |
5df69fab JB |
1343 | elu: { |
1344 | aggregate: false, | |
1345 | average: false, | |
1346 | median: false | |
1347 | } | |
86bf340d | 1348 | }) |
fd7ebd49 | 1349 | await pool.destroy() |
10fcfaf4 JB |
1350 | pool = new DynamicThreadPool( |
1351 | min, | |
1352 | max, | |
d710242d | 1353 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 1354 | { workerChoiceStrategy } |
10fcfaf4 | 1355 | ) |
87de9ff5 JB |
1356 | expect( |
1357 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1358 | ).toStrictEqual({ | |
932fc8be JB |
1359 | runTime: { |
1360 | aggregate: true, | |
1361 | average: true, | |
1362 | median: false | |
1363 | }, | |
1364 | waitTime: { | |
1365 | aggregate: false, | |
1366 | average: false, | |
1367 | median: false | |
1368 | }, | |
5df69fab JB |
1369 | elu: { |
1370 | aggregate: false, | |
1371 | average: false, | |
1372 | median: false | |
1373 | } | |
86bf340d | 1374 | }) |
10fcfaf4 JB |
1375 | // We need to clean up the resources after our test |
1376 | await pool.destroy() | |
1377 | }) | |
1378 | ||
b3432a63 | 1379 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
b3432a63 JB |
1380 | const pool = new FixedThreadPool( |
1381 | max, | |
1382 | './tests/worker-files/thread/testWorker.js', | |
1383 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
1384 | ) | |
1385 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
ee9f5295 | 1386 | const promises = new Set() |
a20f0ba5 JB |
1387 | const maxMultiplier = 2 |
1388 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1389 | promises.add(pool.execute()) |
b3432a63 | 1390 | } |
e211bc18 | 1391 | await Promise.all(promises) |
138d29a8 | 1392 | for (const workerNode of pool.workerNodes) { |
465b2940 | 1393 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1394 | tasks: { |
1395 | executed: expect.any(Number), | |
1396 | executing: 0, | |
1397 | queued: 0, | |
df593701 | 1398 | maxQueued: 0, |
68cbdc84 | 1399 | stolen: 0, |
a4e07f72 JB |
1400 | failed: 0 |
1401 | }, | |
71514351 | 1402 | runTime: expect.objectContaining({ |
a4e07f72 | 1403 | history: expect.any(CircularArray) |
71514351 | 1404 | }), |
a4e07f72 | 1405 | waitTime: { |
a4e07f72 JB |
1406 | history: expect.any(CircularArray) |
1407 | }, | |
5df69fab JB |
1408 | elu: { |
1409 | idle: { | |
5df69fab JB |
1410 | history: expect.any(CircularArray) |
1411 | }, | |
1412 | active: { | |
5df69fab | 1413 | history: expect.any(CircularArray) |
71514351 | 1414 | } |
5df69fab | 1415 | } |
86bf340d | 1416 | }) |
465b2940 JB |
1417 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1418 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
1419 | max * maxMultiplier |
1420 | ) | |
71514351 JB |
1421 | if (workerNode.usage.runTime.aggregate == null) { |
1422 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1423 | } else { | |
1424 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1425 | } | |
1426 | if (workerNode.usage.runTime.average == null) { | |
1427 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1428 | } else { | |
1429 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1430 | } | |
138d29a8 | 1431 | } |
97a2abc3 | 1432 | expect( |
95c83464 | 1433 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1434 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
08f3f44c JB |
1435 | ).defaultWorkerWeight |
1436 | ).toBeGreaterThan(0) | |
1437 | expect( | |
1438 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1439 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1440 | ).workerVirtualTaskRunTime | |
1441 | ).toBeGreaterThanOrEqual(0) | |
b3432a63 JB |
1442 | // We need to clean up the resources after our test |
1443 | await pool.destroy() | |
1444 | }) | |
1445 | ||
1446 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
b3432a63 JB |
1447 | const pool = new DynamicThreadPool( |
1448 | min, | |
1449 | max, | |
1450 | './tests/worker-files/thread/testWorker.js', | |
1451 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
1452 | ) | |
1453 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
ee9f5295 | 1454 | const promises = new Set() |
138d29a8 | 1455 | const maxMultiplier = 2 |
5502c07c | 1456 | for (let i = 0; i < max * maxMultiplier; i++) { |
ee9f5295 | 1457 | promises.add(pool.execute()) |
b3432a63 | 1458 | } |
e211bc18 | 1459 | await Promise.all(promises) |
138d29a8 | 1460 | for (const workerNode of pool.workerNodes) { |
465b2940 | 1461 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1462 | tasks: { |
1463 | executed: expect.any(Number), | |
1464 | executing: 0, | |
1465 | queued: 0, | |
df593701 | 1466 | maxQueued: 0, |
68cbdc84 | 1467 | stolen: 0, |
a4e07f72 JB |
1468 | failed: 0 |
1469 | }, | |
b1aae695 | 1470 | runTime: expect.objectContaining({ |
a4e07f72 | 1471 | history: expect.any(CircularArray) |
b1aae695 | 1472 | }), |
a4e07f72 | 1473 | waitTime: { |
a4e07f72 JB |
1474 | history: expect.any(CircularArray) |
1475 | }, | |
5df69fab JB |
1476 | elu: { |
1477 | idle: { | |
5df69fab JB |
1478 | history: expect.any(CircularArray) |
1479 | }, | |
1480 | active: { | |
5df69fab | 1481 | history: expect.any(CircularArray) |
71514351 | 1482 | } |
5df69fab | 1483 | } |
86bf340d | 1484 | }) |
465b2940 JB |
1485 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1486 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
1487 | max * maxMultiplier |
1488 | ) | |
b1aae695 JB |
1489 | if (workerNode.usage.runTime.aggregate == null) { |
1490 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1491 | } else { | |
1492 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1493 | } | |
1494 | if (workerNode.usage.runTime.average == null) { | |
1495 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1496 | } else { | |
1497 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1498 | } | |
138d29a8 | 1499 | } |
2b4fddb8 JB |
1500 | expect( |
1501 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1502 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1503 | ).defaultWorkerWeight | |
1504 | ).toBeGreaterThan(0) | |
1505 | expect( | |
1506 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1507 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1508 | ).workerVirtualTaskRunTime | |
1509 | ).toBeGreaterThanOrEqual(0) | |
b3432a63 JB |
1510 | // We need to clean up the resources after our test |
1511 | await pool.destroy() | |
1512 | }) | |
1513 | ||
9e775f96 | 1514 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => { |
010d7020 JB |
1515 | const pool = new DynamicThreadPool( |
1516 | min, | |
1517 | max, | |
1518 | './tests/worker-files/thread/testWorker.js', | |
1519 | { | |
1520 | workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN, | |
1521 | workerChoiceStrategyOptions: { | |
932fc8be | 1522 | runTime: { median: true } |
010d7020 JB |
1523 | } |
1524 | } | |
1525 | ) | |
1526 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
ee9f5295 | 1527 | const promises = new Set() |
010d7020 JB |
1528 | const maxMultiplier = 2 |
1529 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1530 | promises.add(pool.execute()) |
010d7020 | 1531 | } |
e211bc18 | 1532 | await Promise.all(promises) |
010d7020 | 1533 | for (const workerNode of pool.workerNodes) { |
465b2940 | 1534 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1535 | tasks: { |
1536 | executed: expect.any(Number), | |
1537 | executing: 0, | |
1538 | queued: 0, | |
df593701 | 1539 | maxQueued: 0, |
68cbdc84 | 1540 | stolen: 0, |
a4e07f72 JB |
1541 | failed: 0 |
1542 | }, | |
b1aae695 | 1543 | runTime: expect.objectContaining({ |
a4e07f72 | 1544 | history: expect.any(CircularArray) |
b1aae695 | 1545 | }), |
a4e07f72 | 1546 | waitTime: { |
a4e07f72 JB |
1547 | history: expect.any(CircularArray) |
1548 | }, | |
5df69fab JB |
1549 | elu: { |
1550 | idle: { | |
5df69fab JB |
1551 | history: expect.any(CircularArray) |
1552 | }, | |
1553 | active: { | |
5df69fab | 1554 | history: expect.any(CircularArray) |
71514351 | 1555 | } |
5df69fab | 1556 | } |
86bf340d | 1557 | }) |
465b2940 JB |
1558 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1559 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
1560 | max * maxMultiplier |
1561 | ) | |
b1aae695 JB |
1562 | if (workerNode.usage.runTime.aggregate == null) { |
1563 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1564 | } else { | |
1565 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1566 | } | |
1567 | if (workerNode.usage.runTime.median == null) { | |
1568 | expect(workerNode.usage.runTime.median).toBeUndefined() | |
1569 | } else { | |
1570 | expect(workerNode.usage.runTime.median).toBeGreaterThan(0) | |
1571 | } | |
010d7020 | 1572 | } |
08f3f44c JB |
1573 | expect( |
1574 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1575 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1576 | ).defaultWorkerWeight | |
1577 | ).toBeGreaterThan(0) | |
1578 | expect( | |
1579 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1580 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1581 | ).workerVirtualTaskRunTime | |
1582 | ).toBeGreaterThanOrEqual(0) | |
010d7020 JB |
1583 | // We need to clean up the resources after our test |
1584 | await pool.destroy() | |
1585 | }) | |
1586 | ||
a6f7f1b4 | 1587 | it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => { |
594bfb84 | 1588 | const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN |
f0829c53 | 1589 | let pool = new FixedThreadPool( |
caeb9817 JB |
1590 | max, |
1591 | './tests/worker-files/thread/testWorker.js' | |
1592 | ) | |
38f6e859 | 1593 | expect( |
95c83464 | 1594 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1595 | workerChoiceStrategy |
9b106837 | 1596 | ).nextWorkerNodeKey |
b529c323 | 1597 | ).toBeDefined() |
38f6e859 | 1598 | expect( |
95c83464 | 1599 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1600 | workerChoiceStrategy |
b529c323 JB |
1601 | ).defaultWorkerWeight |
1602 | ).toBeDefined() | |
caeb9817 | 1603 | expect( |
95c83464 | 1604 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1605 | workerChoiceStrategy |
08f3f44c | 1606 | ).workerVirtualTaskRunTime |
b529c323 | 1607 | ).toBeDefined() |
594bfb84 | 1608 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 1609 | expect( |
95c83464 | 1610 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1611 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 1612 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
1613 | ).toBe(0) |
1614 | expect( | |
95c83464 | 1615 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1616 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
95c83464 | 1617 | ).defaultWorkerWeight |
a6f7f1b4 | 1618 | ).toBeGreaterThan(0) |
08f3f44c JB |
1619 | expect( |
1620 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1621 | workerChoiceStrategy | |
1622 | ).workerVirtualTaskRunTime | |
1623 | ).toBe(0) | |
f0829c53 JB |
1624 | await pool.destroy() |
1625 | pool = new DynamicThreadPool( | |
1626 | min, | |
1627 | max, | |
1628 | './tests/worker-files/thread/testWorker.js' | |
1629 | ) | |
38f6e859 | 1630 | expect( |
95c83464 | 1631 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1632 | workerChoiceStrategy |
9b106837 | 1633 | ).nextWorkerNodeKey |
b529c323 | 1634 | ).toBeDefined() |
38f6e859 | 1635 | expect( |
95c83464 | 1636 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1637 | workerChoiceStrategy |
b529c323 JB |
1638 | ).defaultWorkerWeight |
1639 | ).toBeDefined() | |
f0829c53 | 1640 | expect( |
95c83464 | 1641 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1642 | workerChoiceStrategy |
08f3f44c | 1643 | ).workerVirtualTaskRunTime |
b529c323 | 1644 | ).toBeDefined() |
594bfb84 | 1645 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 1646 | expect( |
95c83464 | 1647 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1648 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 1649 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
1650 | ).toBe(0) |
1651 | expect( | |
95c83464 | 1652 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1653 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
95c83464 | 1654 | ).defaultWorkerWeight |
a6f7f1b4 | 1655 | ).toBeGreaterThan(0) |
08f3f44c JB |
1656 | expect( |
1657 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1658 | workerChoiceStrategy | |
1659 | ).workerVirtualTaskRunTime | |
1660 | ).toBe(0) | |
caeb9817 JB |
1661 | // We need to clean up the resources after our test |
1662 | await pool.destroy() | |
1663 | }) | |
1664 | ||
6c6afb84 JB |
1665 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => { |
1666 | const workerChoiceStrategy = | |
1667 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1668 | let pool = new FixedThreadPool( | |
1669 | max, | |
1670 | './tests/worker-files/thread/testWorker.js', | |
1671 | { workerChoiceStrategy } | |
1672 | ) | |
1673 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1674 | dynamicWorkerUsage: false, |
1675 | dynamicWorkerReady: true | |
6c6afb84 JB |
1676 | }) |
1677 | await pool.destroy() | |
1678 | pool = new DynamicThreadPool( | |
1679 | min, | |
1680 | max, | |
1681 | './tests/worker-files/thread/testWorker.js', | |
1682 | { workerChoiceStrategy } | |
1683 | ) | |
1684 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1685 | dynamicWorkerUsage: false, |
1686 | dynamicWorkerReady: true | |
6c6afb84 JB |
1687 | }) |
1688 | // We need to clean up the resources after our test | |
1689 | await pool.destroy() | |
1690 | }) | |
1691 | ||
1692 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => { | |
e52fb978 JB |
1693 | const workerChoiceStrategy = |
1694 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1695 | let pool = new FixedThreadPool( | |
1696 | max, | |
1697 | './tests/worker-files/thread/testWorker.js', | |
1698 | { workerChoiceStrategy } | |
1699 | ) | |
87de9ff5 JB |
1700 | expect( |
1701 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1702 | ).toStrictEqual({ | |
932fc8be JB |
1703 | runTime: { |
1704 | aggregate: false, | |
1705 | average: false, | |
1706 | median: false | |
1707 | }, | |
1708 | waitTime: { | |
1709 | aggregate: false, | |
1710 | average: false, | |
1711 | median: false | |
1712 | }, | |
5df69fab JB |
1713 | elu: { |
1714 | aggregate: false, | |
1715 | average: false, | |
1716 | median: false | |
1717 | } | |
e52fb978 JB |
1718 | }) |
1719 | await pool.destroy() | |
1720 | pool = new DynamicThreadPool( | |
1721 | min, | |
1722 | max, | |
1723 | './tests/worker-files/thread/testWorker.js', | |
1724 | { workerChoiceStrategy } | |
1725 | ) | |
87de9ff5 JB |
1726 | expect( |
1727 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1728 | ).toStrictEqual({ | |
932fc8be JB |
1729 | runTime: { |
1730 | aggregate: false, | |
1731 | average: false, | |
1732 | median: false | |
1733 | }, | |
1734 | waitTime: { | |
1735 | aggregate: false, | |
1736 | average: false, | |
1737 | median: false | |
1738 | }, | |
5df69fab JB |
1739 | elu: { |
1740 | aggregate: false, | |
1741 | average: false, | |
1742 | median: false | |
1743 | } | |
e52fb978 JB |
1744 | }) |
1745 | // We need to clean up the resources after our test | |
1746 | await pool.destroy() | |
1747 | }) | |
1748 | ||
e62e7646 JB |
1749 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
1750 | const pool = new FixedThreadPool( | |
1751 | max, | |
1752 | './tests/worker-files/thread/testWorker.js', | |
1753 | { | |
1754 | workerChoiceStrategy: | |
1755 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1756 | } | |
1757 | ) | |
1758 | // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose` | |
1759 | const promises = new Set() | |
1760 | const maxMultiplier = 2 | |
1761 | for (let i = 0; i < max * maxMultiplier; i++) { | |
1762 | promises.add(pool.execute()) | |
1763 | } | |
1764 | await Promise.all(promises) | |
1765 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 1766 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1767 | tasks: { |
1768 | executed: maxMultiplier, | |
1769 | executing: 0, | |
1770 | queued: 0, | |
df593701 | 1771 | maxQueued: 0, |
68cbdc84 | 1772 | stolen: 0, |
a4e07f72 JB |
1773 | failed: 0 |
1774 | }, | |
1775 | runTime: { | |
a4e07f72 JB |
1776 | history: expect.any(CircularArray) |
1777 | }, | |
1778 | waitTime: { | |
a4e07f72 JB |
1779 | history: expect.any(CircularArray) |
1780 | }, | |
5df69fab JB |
1781 | elu: { |
1782 | idle: { | |
5df69fab JB |
1783 | history: expect.any(CircularArray) |
1784 | }, | |
1785 | active: { | |
5df69fab | 1786 | history: expect.any(CircularArray) |
71514351 | 1787 | } |
5df69fab | 1788 | } |
e62e7646 JB |
1789 | }) |
1790 | } | |
1791 | expect( | |
1792 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1793 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1794 | ).defaultWorkerWeight | |
1795 | ).toBeGreaterThan(0) | |
1796 | expect( | |
1797 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1798 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
d33be430 | 1799 | ).roundId |
e62e7646 JB |
1800 | ).toBe(0) |
1801 | expect( | |
1802 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1803 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1804 | ).nextWorkerNodeKey |
e62e7646 JB |
1805 | ).toBe(0) |
1806 | expect( | |
1807 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1808 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1809 | ).roundWeights | |
1810 | ).toStrictEqual([ | |
1811 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1812 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1813 | ).defaultWorkerWeight | |
1814 | ]) | |
1815 | // We need to clean up the resources after our test | |
1816 | await pool.destroy() | |
1817 | }) | |
1818 | ||
1819 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
1820 | const pool = new DynamicThreadPool( | |
1821 | min, | |
1822 | max, | |
1823 | './tests/worker-files/thread/testWorker.js', | |
1824 | { | |
1825 | workerChoiceStrategy: | |
1826 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1827 | } | |
1828 | ) | |
1829 | // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose` | |
1830 | const promises = new Set() | |
1831 | const maxMultiplier = 2 | |
1832 | for (let i = 0; i < max * maxMultiplier; i++) { | |
1833 | promises.add(pool.execute()) | |
1834 | } | |
1835 | await Promise.all(promises) | |
1836 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 1837 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 1838 | tasks: { |
b1aae695 | 1839 | executed: expect.any(Number), |
a4e07f72 JB |
1840 | executing: 0, |
1841 | queued: 0, | |
df593701 | 1842 | maxQueued: 0, |
68cbdc84 | 1843 | stolen: 0, |
a4e07f72 JB |
1844 | failed: 0 |
1845 | }, | |
1846 | runTime: { | |
a4e07f72 JB |
1847 | history: expect.any(CircularArray) |
1848 | }, | |
1849 | waitTime: { | |
a4e07f72 JB |
1850 | history: expect.any(CircularArray) |
1851 | }, | |
5df69fab JB |
1852 | elu: { |
1853 | idle: { | |
5df69fab JB |
1854 | history: expect.any(CircularArray) |
1855 | }, | |
1856 | active: { | |
5df69fab | 1857 | history: expect.any(CircularArray) |
71514351 | 1858 | } |
5df69fab | 1859 | } |
e62e7646 | 1860 | }) |
e43b8c2d JB |
1861 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1862 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
1863 | max * maxMultiplier | |
1864 | ) | |
e62e7646 JB |
1865 | } |
1866 | expect( | |
1867 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1868 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1869 | ).defaultWorkerWeight | |
1870 | ).toBeGreaterThan(0) | |
1871 | expect( | |
1872 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1873 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
d33be430 | 1874 | ).roundId |
e62e7646 JB |
1875 | ).toBe(0) |
1876 | expect( | |
1877 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1878 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1879 | ).nextWorkerNodeKey |
d2c73f82 | 1880 | ).toBe(0) |
e62e7646 JB |
1881 | expect( |
1882 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1883 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1884 | ).roundWeights | |
1885 | ).toStrictEqual([ | |
1886 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1887 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1888 | ).defaultWorkerWeight | |
1889 | ]) | |
1890 | // We need to clean up the resources after our test | |
1891 | await pool.destroy() | |
1892 | }) | |
1893 | ||
8c3ec188 JB |
1894 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => { |
1895 | const workerChoiceStrategy = | |
1896 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1897 | let pool = new FixedThreadPool( | |
1898 | max, | |
1899 | './tests/worker-files/thread/testWorker.js' | |
1900 | ) | |
1901 | expect( | |
1902 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1903 | workerChoiceStrategy | |
d33be430 | 1904 | ).roundId |
8c3ec188 JB |
1905 | ).toBeDefined() |
1906 | expect( | |
1907 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1908 | workerChoiceStrategy | |
9b106837 | 1909 | ).nextWorkerNodeKey |
8c3ec188 JB |
1910 | ).toBeDefined() |
1911 | expect( | |
1912 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1913 | workerChoiceStrategy | |
1914 | ).defaultWorkerWeight | |
1915 | ).toBeDefined() | |
1916 | expect( | |
1917 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1918 | workerChoiceStrategy | |
1919 | ).roundWeights | |
1920 | ).toBeDefined() | |
1921 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) | |
1922 | expect( | |
1923 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1924 | workerChoiceStrategy | |
d33be430 | 1925 | ).roundId |
8c3ec188 JB |
1926 | ).toBe(0) |
1927 | expect( | |
1928 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1929 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1930 | ).nextWorkerNodeKey |
8c3ec188 JB |
1931 | ).toBe(0) |
1932 | expect( | |
1933 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1934 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1935 | ).defaultWorkerWeight | |
1936 | ).toBeGreaterThan(0) | |
1937 | expect( | |
1938 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1939 | workerChoiceStrategy | |
1940 | ).roundWeights | |
1941 | ).toStrictEqual([ | |
1942 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1943 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1944 | ).defaultWorkerWeight | |
1945 | ]) | |
1946 | await pool.destroy() | |
1947 | pool = new DynamicThreadPool( | |
1948 | min, | |
1949 | max, | |
1950 | './tests/worker-files/thread/testWorker.js' | |
1951 | ) | |
1952 | expect( | |
1953 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1954 | workerChoiceStrategy | |
d33be430 | 1955 | ).roundId |
8c3ec188 JB |
1956 | ).toBeDefined() |
1957 | expect( | |
1958 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1959 | workerChoiceStrategy | |
9b106837 | 1960 | ).nextWorkerNodeKey |
8c3ec188 JB |
1961 | ).toBeDefined() |
1962 | expect( | |
1963 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1964 | workerChoiceStrategy | |
1965 | ).defaultWorkerWeight | |
1966 | ).toBeDefined() | |
1967 | expect( | |
1968 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1969 | workerChoiceStrategy | |
1970 | ).roundWeights | |
1971 | ).toBeDefined() | |
1972 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) | |
1973 | expect( | |
1974 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1975 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1976 | ).nextWorkerNodeKey |
8c3ec188 JB |
1977 | ).toBe(0) |
1978 | expect( | |
1979 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1980 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1981 | ).defaultWorkerWeight | |
1982 | ).toBeGreaterThan(0) | |
1983 | expect( | |
1984 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1985 | workerChoiceStrategy | |
1986 | ).roundWeights | |
1987 | ).toStrictEqual([ | |
1988 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1989 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1990 | ).defaultWorkerWeight | |
1991 | ]) | |
1992 | // We need to clean up the resources after our test | |
1993 | await pool.destroy() | |
1994 | }) | |
1995 | ||
89b09b26 | 1996 | it('Verify unknown strategy throw error', () => { |
a35560ba S |
1997 | expect( |
1998 | () => | |
1999 | new DynamicThreadPool( | |
2000 | min, | |
2001 | max, | |
2002 | './tests/worker-files/thread/testWorker.js', | |
1927ee67 | 2003 | { workerChoiceStrategy: 'UNKNOWN_STRATEGY' } |
a35560ba | 2004 | ) |
d4aeae5a | 2005 | ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'") |
a35560ba S |
2006 | }) |
2007 | }) |