fix: fix faire share worker choice stategy internals update
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
CommitLineData
a61a0724 1const { expect } = require('expect')
a35560ba
S
2const {
3 WorkerChoiceStrategies,
4 DynamicThreadPool,
2ced693a
JB
5 FixedThreadPool,
6 FixedClusterPool
cdace0e5 7} = require('../../../lib')
a35560ba
S
8
9describe('Selection strategies test suite', () => {
e1ffb94f
JB
10 const min = 0
11 const max = 3
12
a35560ba
S
13 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
14 expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN')
737c6d97 15 expect(WorkerChoiceStrategies.LESS_USED).toBe('LESS_USED')
168c526f 16 expect(WorkerChoiceStrategies.LESS_BUSY).toBe('LESS_BUSY')
23ff945a 17 expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE')
b3432a63
JB
18 expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe(
19 'WEIGHTED_ROUND_ROBIN'
20 )
a35560ba
S
21 })
22
e843b904 23 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
e843b904
JB
24 const pool = new DynamicThreadPool(
25 min,
26 max,
27 './tests/worker-files/thread/testWorker.js'
28 )
29 expect(pool.opts.workerChoiceStrategy).toBe(
30 WorkerChoiceStrategies.ROUND_ROBIN
31 )
32 // We need to clean up the resources after our test
33 await pool.destroy()
34 })
35
594bfb84
JB
36 it('Verify available strategies are taken at pool creation', async () => {
37 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
38 const pool = new FixedThreadPool(
39 max,
40 './tests/worker-files/thread/testWorker.js',
41 { workerChoiceStrategy }
42 )
43 expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy)
44 expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe(
45 workerChoiceStrategy
46 )
47 await pool.destroy()
48 }
d2f7b7a2
JB
49 })
50
594bfb84
JB
51 it('Verify available strategies can be set after pool creation', async () => {
52 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
53 const pool = new DynamicThreadPool(
54 min,
55 max,
ec82cfa1 56 './tests/worker-files/thread/testWorker.js'
594bfb84
JB
57 )
58 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
59 expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy)
60 expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe(
61 workerChoiceStrategy
62 )
63 await pool.destroy()
64 }
65 })
66
67 it('Verify available strategies default internals at pool creation', async () => {
68 const pool = new FixedThreadPool(
e843b904
JB
69 max,
70 './tests/worker-files/thread/testWorker.js'
71 )
594bfb84
JB
72 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
73 if (workerChoiceStrategy === WorkerChoiceStrategies.ROUND_ROBIN) {
74 expect(
75 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
76 workerChoiceStrategy
77 ).nextWorkerNodeId
78 ).toBe(0)
79 } else if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
08f3f44c
JB
80 expect(
81 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
82 workerChoiceStrategy
83 ).workersVirtualTaskTimestamp
84 ).toBeInstanceOf(Array)
85 expect(
86 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
87 workerChoiceStrategy
88 ).workersVirtualTaskTimestamp.length
89 ).toBe(0)
594bfb84
JB
90 } else if (
91 workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
92 ) {
93 expect(
94 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
95 workerChoiceStrategy
96 ).currentWorkerNodeId
97 ).toBe(0)
98 expect(
99 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
100 workerChoiceStrategy
101 ).defaultWorkerWeight
102 ).toBeGreaterThan(0)
08f3f44c
JB
103 expect(
104 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
105 workerChoiceStrategy
106 ).workerVirtualTaskRunTime
107 ).toBe(0)
594bfb84
JB
108 }
109 }
e843b904
JB
110 await pool.destroy()
111 })
112
10fcfaf4 113 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
594bfb84 114 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
10fcfaf4
JB
115 let pool = new FixedThreadPool(
116 max,
d710242d 117 './tests/worker-files/thread/testWorker.js',
594bfb84 118 { workerChoiceStrategy }
10fcfaf4 119 )
10fcfaf4 120 expect(
97a2abc3 121 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 122 ).toBe(false)
c6bd2650
JB
123 expect(
124 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
125 ).toBe(false)
78099a15
JB
126 expect(
127 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
128 ).toBe(false)
fd7ebd49 129 await pool.destroy()
10fcfaf4
JB
130 pool = new DynamicThreadPool(
131 min,
132 max,
d710242d 133 './tests/worker-files/thread/testWorker.js',
594bfb84 134 { workerChoiceStrategy }
10fcfaf4 135 )
10fcfaf4 136 expect(
97a2abc3 137 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 138 ).toBe(false)
c6bd2650
JB
139 expect(
140 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
141 ).toBe(false)
78099a15
JB
142 expect(
143 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
144 ).toBe(false)
10fcfaf4
JB
145 // We need to clean up the resources after our test
146 await pool.destroy()
147 })
148
bdaf31cd 149 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
bdaf31cd
JB
150 const pool = new FixedThreadPool(
151 max,
152 './tests/worker-files/thread/testWorker.js',
153 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
154 )
bdaf31cd
JB
155 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
156 const promises = []
a20f0ba5
JB
157 const maxMultiplier = 2
158 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 159 promises.push(pool.execute())
bdaf31cd
JB
160 }
161 await Promise.all(promises)
162 // We need to clean up the resources after our test
163 await pool.destroy()
164 })
165
166 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
bdaf31cd
JB
167 const pool = new DynamicThreadPool(
168 min,
169 max,
170 './tests/worker-files/thread/testWorker.js',
171 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
172 )
bdaf31cd
JB
173 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
174 const promises = []
a20f0ba5
JB
175 const maxMultiplier = 2
176 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 177 promises.push(pool.execute())
bdaf31cd
JB
178 }
179 await Promise.all(promises)
180 // We need to clean up the resources after our test
181 await pool.destroy()
182 })
183
2ced693a 184 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
594bfb84 185 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
2ced693a
JB
186 let pool = new FixedClusterPool(
187 max,
594bfb84
JB
188 './tests/worker-files/cluster/testWorker.js',
189 { workerChoiceStrategy }
2ced693a
JB
190 )
191 let results = new Set()
192 for (let i = 0; i < max; i++) {
adc3c320 193 results.add(pool.chooseWorkerNode()[1].worker.id)
2ced693a
JB
194 }
195 expect(results.size).toBe(max)
196 await pool.destroy()
594bfb84
JB
197 pool = new FixedThreadPool(
198 max,
199 './tests/worker-files/thread/testWorker.js',
200 { workerChoiceStrategy }
201 )
2ced693a
JB
202 results = new Set()
203 for (let i = 0; i < max; i++) {
adc3c320 204 results.add(pool.chooseWorkerNode()[1].worker.threadId)
2ced693a
JB
205 }
206 expect(results.size).toBe(max)
207 await pool.destroy()
208 })
209
a6f7f1b4 210 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
594bfb84 211 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
a6f7f1b4
JB
212 let pool = new FixedThreadPool(
213 max,
214 './tests/worker-files/thread/testWorker.js',
215 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
216 )
38f6e859 217 expect(
95c83464 218 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 219 workerChoiceStrategy
f06e48d8 220 ).nextWorkerNodeId
b529c323 221 ).toBeDefined()
594bfb84 222 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 223 expect(
95c83464 224 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 225 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 226 ).nextWorkerNodeId
a6f7f1b4
JB
227 ).toBe(0)
228 await pool.destroy()
229 pool = new DynamicThreadPool(
230 min,
231 max,
232 './tests/worker-files/thread/testWorker.js',
233 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
234 )
38f6e859 235 expect(
95c83464 236 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 237 workerChoiceStrategy
f06e48d8 238 ).nextWorkerNodeId
b529c323 239 ).toBeDefined()
594bfb84 240 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 241 expect(
95c83464 242 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 243 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 244 ).nextWorkerNodeId
a6f7f1b4
JB
245 ).toBe(0)
246 // We need to clean up the resources after our test
247 await pool.destroy()
248 })
249
737c6d97 250 it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => {
594bfb84 251 const workerChoiceStrategy = WorkerChoiceStrategies.LESS_USED
10fcfaf4
JB
252 let pool = new FixedThreadPool(
253 max,
d710242d 254 './tests/worker-files/thread/testWorker.js',
594bfb84 255 { workerChoiceStrategy }
10fcfaf4 256 )
10fcfaf4 257 expect(
97a2abc3 258 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 259 ).toBe(false)
c6bd2650
JB
260 expect(
261 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
262 ).toBe(false)
78099a15
JB
263 expect(
264 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
265 ).toBe(false)
fd7ebd49 266 await pool.destroy()
10fcfaf4
JB
267 pool = new DynamicThreadPool(
268 min,
269 max,
d710242d 270 './tests/worker-files/thread/testWorker.js',
594bfb84 271 { workerChoiceStrategy }
10fcfaf4 272 )
10fcfaf4 273 expect(
97a2abc3 274 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 275 ).toBe(false)
c6bd2650
JB
276 expect(
277 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
278 ).toBe(false)
78099a15
JB
279 expect(
280 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
281 ).toBe(false)
10fcfaf4
JB
282 // We need to clean up the resources after our test
283 await pool.destroy()
284 })
285
737c6d97 286 it('Verify LESS_USED strategy can be run in a fixed pool', async () => {
b98ec2e6
JB
287 const pool = new FixedThreadPool(
288 max,
289 './tests/worker-files/thread/testWorker.js',
737c6d97 290 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
b98ec2e6 291 )
168c526f 292 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
a35560ba 293 const promises = []
a20f0ba5
JB
294 const maxMultiplier = 2
295 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 296 promises.push(pool.execute())
a35560ba
S
297 }
298 await Promise.all(promises)
a35560ba
S
299 // We need to clean up the resources after our test
300 await pool.destroy()
301 })
302
737c6d97 303 it('Verify LESS_USED strategy can be run in a dynamic pool', async () => {
ff5e76e1
JB
304 const pool = new DynamicThreadPool(
305 min,
306 max,
307 './tests/worker-files/thread/testWorker.js',
737c6d97 308 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
ff5e76e1 309 )
168c526f
JB
310 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
311 const promises = []
a20f0ba5
JB
312 const maxMultiplier = 2
313 for (let i = 0; i < max * maxMultiplier; i++) {
168c526f
JB
314 promises.push(pool.execute())
315 }
316 await Promise.all(promises)
317 // We need to clean up the resources after our test
318 await pool.destroy()
319 })
320
168c526f 321 it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => {
594bfb84 322 const workerChoiceStrategy = WorkerChoiceStrategies.LESS_BUSY
168c526f
JB
323 let pool = new FixedThreadPool(
324 max,
d710242d 325 './tests/worker-files/thread/testWorker.js',
594bfb84 326 { workerChoiceStrategy }
168c526f 327 )
168c526f 328 expect(
97a2abc3 329 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
168c526f 330 ).toBe(true)
c6bd2650
JB
331 expect(
332 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
333 ).toBe(false)
78099a15
JB
334 expect(
335 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
336 ).toBe(false)
168c526f
JB
337 await pool.destroy()
338 pool = new DynamicThreadPool(
339 min,
340 max,
d710242d 341 './tests/worker-files/thread/testWorker.js',
594bfb84 342 { workerChoiceStrategy }
168c526f 343 )
168c526f 344 expect(
97a2abc3 345 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
168c526f 346 ).toBe(true)
c6bd2650
JB
347 expect(
348 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
349 ).toBe(false)
78099a15
JB
350 expect(
351 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
352 ).toBe(false)
168c526f
JB
353 // We need to clean up the resources after our test
354 await pool.destroy()
355 })
356
357 it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => {
358 const pool = new FixedThreadPool(
359 max,
360 './tests/worker-files/thread/testWorker.js',
361 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
362 )
363 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
364 const promises = []
a20f0ba5
JB
365 const maxMultiplier = 2
366 for (let i = 0; i < max * maxMultiplier; i++) {
168c526f
JB
367 promises.push(pool.execute())
368 }
369 await Promise.all(promises)
370 // We need to clean up the resources after our test
371 await pool.destroy()
372 })
373
374 it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => {
375 const pool = new DynamicThreadPool(
376 min,
377 max,
378 './tests/worker-files/thread/testWorker.js',
379 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
380 )
381 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
ff5e76e1 382 const promises = []
a20f0ba5
JB
383 const maxMultiplier = 2
384 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 385 promises.push(pool.execute())
ff5e76e1
JB
386 }
387 await Promise.all(promises)
ff5e76e1
JB
388 // We need to clean up the resources after our test
389 await pool.destroy()
390 })
391
10fcfaf4 392 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
594bfb84 393 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
10fcfaf4
JB
394 let pool = new FixedThreadPool(
395 max,
d710242d 396 './tests/worker-files/thread/testWorker.js',
594bfb84 397 { workerChoiceStrategy }
10fcfaf4 398 )
10fcfaf4 399 expect(
97a2abc3 400 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 401 ).toBe(true)
c6bd2650
JB
402 expect(
403 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
404 ).toBe(true)
78099a15
JB
405 expect(
406 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
407 ).toBe(false)
fd7ebd49 408 await pool.destroy()
10fcfaf4
JB
409 pool = new DynamicThreadPool(
410 min,
411 max,
d710242d 412 './tests/worker-files/thread/testWorker.js',
594bfb84 413 { workerChoiceStrategy }
10fcfaf4 414 )
10fcfaf4 415 expect(
97a2abc3 416 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 417 ).toBe(true)
c6bd2650
JB
418 expect(
419 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
420 ).toBe(true)
78099a15
JB
421 expect(
422 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
423 ).toBe(false)
10fcfaf4
JB
424 // We need to clean up the resources after our test
425 await pool.destroy()
426 })
427
23ff945a 428 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
23ff945a
JB
429 const pool = new FixedThreadPool(
430 max,
431 './tests/worker-files/thread/testWorker.js',
432 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
433 )
434 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
435 const promises = []
a20f0ba5
JB
436 const maxMultiplier = 2
437 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 438 promises.push(pool.execute())
23ff945a
JB
439 }
440 await Promise.all(promises)
138d29a8
JB
441 for (const workerNode of pool.workerNodes) {
442 expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
443 expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
444 expect(workerNode.tasksUsage.medRunTime).toBeDefined()
445 expect(workerNode.tasksUsage.medRunTime).toBe(0)
446 }
97a2abc3 447 expect(
95c83464 448 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 449 pool.workerChoiceStrategyContext.workerChoiceStrategy
08f3f44c 450 ).workersVirtualTaskTimestamp.length
f06e48d8 451 ).toBe(pool.workerNodes.length)
23ff945a
JB
452 // We need to clean up the resources after our test
453 await pool.destroy()
454 })
455
456 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
23ff945a
JB
457 const pool = new DynamicThreadPool(
458 min,
459 max,
460 './tests/worker-files/thread/testWorker.js',
461 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
462 )
463 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
464 const promises = []
f7070eee 465 const maxMultiplier = 2
804a889e 466 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 467 promises.push(pool.execute())
23ff945a
JB
468 }
469 await Promise.all(promises)
138d29a8
JB
470 for (const workerNode of pool.workerNodes) {
471 expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
472 expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
473 expect(workerNode.tasksUsage.medRunTime).toBeDefined()
474 expect(workerNode.tasksUsage.medRunTime).toBe(0)
475 }
2b4fddb8
JB
476 expect(
477 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
478 pool.workerChoiceStrategyContext.workerChoiceStrategy
479 ).workersVirtualTaskTimestamp.length
480 ).toBe(pool.workerNodes.length)
23ff945a
JB
481 // We need to clean up the resources after our test
482 await pool.destroy()
483 })
484
010d7020
JB
485 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median run time statistic', async () => {
486 const pool = new DynamicThreadPool(
487 min,
488 max,
489 './tests/worker-files/thread/testWorker.js',
490 {
491 workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE,
492 workerChoiceStrategyOptions: {
493 medRunTime: true
494 }
495 }
496 )
497 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
498 const promises = []
499 const maxMultiplier = 2
500 for (let i = 0; i < max * maxMultiplier; i++) {
501 promises.push(pool.execute())
502 }
503 await Promise.all(promises)
504 for (const workerNode of pool.workerNodes) {
505 expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
506 expect(workerNode.tasksUsage.avgRunTime).toBe(0)
507 expect(workerNode.tasksUsage.medRunTime).toBeDefined()
138d29a8 508 expect(workerNode.tasksUsage.medRunTime).toBeGreaterThanOrEqual(0)
010d7020 509 }
2b4fddb8
JB
510 expect(
511 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
512 pool.workerChoiceStrategyContext.workerChoiceStrategy
513 ).workersVirtualTaskTimestamp.length
514 ).toBe(pool.workerNodes.length)
010d7020
JB
515 // We need to clean up the resources after our test
516 await pool.destroy()
517 })
518
a6f7f1b4 519 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
594bfb84 520 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
f0829c53 521 let pool = new FixedThreadPool(
caeb9817
JB
522 max,
523 './tests/worker-files/thread/testWorker.js'
524 )
525 expect(
95c83464 526 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 527 workerChoiceStrategy
08f3f44c
JB
528 ).workersVirtualTaskTimestamp
529 ).toBeInstanceOf(Array)
530 expect(
531 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
532 workerChoiceStrategy
533 ).workersVirtualTaskTimestamp.length
534 ).toBe(0)
2b4fddb8
JB
535 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
536 workerChoiceStrategy
537 ).workersVirtualTaskTimestamp[0] = 0
538 expect(
539 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
540 workerChoiceStrategy
541 ).workersVirtualTaskTimestamp.length
542 ).toBe(1)
594bfb84 543 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
08f3f44c
JB
544 expect(
545 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
546 workerChoiceStrategy
547 ).workersVirtualTaskTimestamp
548 ).toBeInstanceOf(Array)
08f3f44c
JB
549 expect(
550 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
551 workerChoiceStrategy
552 ).workersVirtualTaskTimestamp.length
2b4fddb8 553 ).toBe(0)
f0829c53
JB
554 await pool.destroy()
555 pool = new DynamicThreadPool(
556 min,
557 max,
558 './tests/worker-files/thread/testWorker.js'
559 )
560 expect(
95c83464 561 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 562 workerChoiceStrategy
08f3f44c
JB
563 ).workersVirtualTaskTimestamp
564 ).toBeInstanceOf(Array)
2b4fddb8
JB
565 expect(
566 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
567 workerChoiceStrategy
568 ).workersVirtualTaskTimestamp.length
569 ).toBe(0)
08f3f44c
JB
570 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
571 workerChoiceStrategy
572 ).workersVirtualTaskTimestamp[0] = 0
573 expect(
574 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
575 workerChoiceStrategy
576 ).workersVirtualTaskTimestamp.length
577 ).toBe(1)
594bfb84 578 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
08f3f44c
JB
579 expect(
580 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
581 workerChoiceStrategy
582 ).workersVirtualTaskTimestamp
583 ).toBeInstanceOf(Array)
584 expect(
585 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
586 workerChoiceStrategy
587 ).workersVirtualTaskTimestamp.length
588 ).toBe(0)
caeb9817
JB
589 // We need to clean up the resources after our test
590 await pool.destroy()
591 })
592
10fcfaf4 593 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
594bfb84 594 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
10fcfaf4
JB
595 let pool = new FixedThreadPool(
596 max,
d710242d 597 './tests/worker-files/thread/testWorker.js',
594bfb84 598 { workerChoiceStrategy }
10fcfaf4 599 )
10fcfaf4 600 expect(
97a2abc3 601 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 602 ).toBe(true)
c6bd2650
JB
603 expect(
604 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
605 ).toBe(true)
78099a15
JB
606 expect(
607 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
608 ).toBe(false)
fd7ebd49 609 await pool.destroy()
10fcfaf4
JB
610 pool = new DynamicThreadPool(
611 min,
612 max,
d710242d 613 './tests/worker-files/thread/testWorker.js',
594bfb84 614 { workerChoiceStrategy }
10fcfaf4 615 )
10fcfaf4 616 expect(
97a2abc3 617 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 618 ).toBe(true)
c6bd2650
JB
619 expect(
620 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
621 ).toBe(true)
78099a15
JB
622 expect(
623 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
624 ).toBe(false)
10fcfaf4
JB
625 // We need to clean up the resources after our test
626 await pool.destroy()
627 })
628
b3432a63 629 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
b3432a63
JB
630 const pool = new FixedThreadPool(
631 max,
632 './tests/worker-files/thread/testWorker.js',
633 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
634 )
635 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
636 const promises = []
a20f0ba5
JB
637 const maxMultiplier = 2
638 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 639 promises.push(pool.execute())
b3432a63
JB
640 }
641 await Promise.all(promises)
138d29a8
JB
642 for (const workerNode of pool.workerNodes) {
643 expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
644 expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
645 expect(workerNode.tasksUsage.medRunTime).toBeDefined()
646 expect(workerNode.tasksUsage.medRunTime).toBe(0)
647 }
97a2abc3 648 expect(
95c83464 649 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 650 pool.workerChoiceStrategyContext.workerChoiceStrategy
08f3f44c
JB
651 ).defaultWorkerWeight
652 ).toBeGreaterThan(0)
653 expect(
654 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
655 pool.workerChoiceStrategyContext.workerChoiceStrategy
656 ).workerVirtualTaskRunTime
657 ).toBeGreaterThanOrEqual(0)
b3432a63
JB
658 // We need to clean up the resources after our test
659 await pool.destroy()
660 })
661
662 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
b3432a63
JB
663 const pool = new DynamicThreadPool(
664 min,
665 max,
666 './tests/worker-files/thread/testWorker.js',
667 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
668 )
669 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
670 const promises = []
138d29a8 671 const maxMultiplier = 2
5502c07c 672 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 673 promises.push(pool.execute())
b3432a63
JB
674 }
675 await Promise.all(promises)
138d29a8
JB
676 for (const workerNode of pool.workerNodes) {
677 expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
678 expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
679 expect(workerNode.tasksUsage.medRunTime).toBeDefined()
680 expect(workerNode.tasksUsage.medRunTime).toBe(0)
681 }
2b4fddb8
JB
682 expect(
683 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
684 pool.workerChoiceStrategyContext.workerChoiceStrategy
685 ).defaultWorkerWeight
686 ).toBeGreaterThan(0)
687 expect(
688 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
689 pool.workerChoiceStrategyContext.workerChoiceStrategy
690 ).workerVirtualTaskRunTime
691 ).toBeGreaterThanOrEqual(0)
b3432a63
JB
692 // We need to clean up the resources after our test
693 await pool.destroy()
694 })
695
010d7020
JB
696 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median run time statistic', async () => {
697 const pool = new DynamicThreadPool(
698 min,
699 max,
700 './tests/worker-files/thread/testWorker.js',
701 {
702 workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
703 workerChoiceStrategyOptions: {
704 medRunTime: true
705 }
706 }
707 )
708 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
709 const promises = []
710 const maxMultiplier = 2
711 for (let i = 0; i < max * maxMultiplier; i++) {
712 promises.push(pool.execute())
713 }
714 await Promise.all(promises)
715 for (const workerNode of pool.workerNodes) {
716 expect(workerNode.tasksUsage.avgRunTime).toBeDefined()
717 expect(workerNode.tasksUsage.avgRunTime).toBe(0)
718 expect(workerNode.tasksUsage.medRunTime).toBeDefined()
138d29a8 719 expect(workerNode.tasksUsage.medRunTime).toBeGreaterThanOrEqual(0)
010d7020 720 }
08f3f44c
JB
721 expect(
722 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
723 pool.workerChoiceStrategyContext.workerChoiceStrategy
724 ).defaultWorkerWeight
725 ).toBeGreaterThan(0)
726 expect(
727 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
728 pool.workerChoiceStrategyContext.workerChoiceStrategy
729 ).workerVirtualTaskRunTime
730 ).toBeGreaterThanOrEqual(0)
010d7020
JB
731 // We need to clean up the resources after our test
732 await pool.destroy()
733 })
734
a6f7f1b4 735 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
594bfb84 736 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
f0829c53 737 let pool = new FixedThreadPool(
caeb9817
JB
738 max,
739 './tests/worker-files/thread/testWorker.js'
740 )
38f6e859 741 expect(
95c83464 742 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 743 workerChoiceStrategy
f06e48d8 744 ).currentWorkerNodeId
b529c323 745 ).toBeDefined()
38f6e859 746 expect(
95c83464 747 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 748 workerChoiceStrategy
b529c323
JB
749 ).defaultWorkerWeight
750 ).toBeDefined()
caeb9817 751 expect(
95c83464 752 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 753 workerChoiceStrategy
08f3f44c 754 ).workerVirtualTaskRunTime
b529c323 755 ).toBeDefined()
594bfb84 756 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 757 expect(
95c83464 758 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 759 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 760 ).currentWorkerNodeId
a6f7f1b4
JB
761 ).toBe(0)
762 expect(
95c83464 763 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 764 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 765 ).defaultWorkerWeight
a6f7f1b4 766 ).toBeGreaterThan(0)
08f3f44c
JB
767 expect(
768 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
769 workerChoiceStrategy
770 ).workerVirtualTaskRunTime
771 ).toBe(0)
f0829c53
JB
772 await pool.destroy()
773 pool = new DynamicThreadPool(
774 min,
775 max,
776 './tests/worker-files/thread/testWorker.js'
777 )
38f6e859 778 expect(
95c83464 779 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 780 workerChoiceStrategy
f06e48d8 781 ).currentWorkerNodeId
b529c323 782 ).toBeDefined()
38f6e859 783 expect(
95c83464 784 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 785 workerChoiceStrategy
b529c323
JB
786 ).defaultWorkerWeight
787 ).toBeDefined()
f0829c53 788 expect(
95c83464 789 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 790 workerChoiceStrategy
08f3f44c 791 ).workerVirtualTaskRunTime
b529c323 792 ).toBeDefined()
594bfb84 793 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 794 expect(
95c83464 795 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 796 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 797 ).currentWorkerNodeId
a6f7f1b4
JB
798 ).toBe(0)
799 expect(
95c83464 800 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 801 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 802 ).defaultWorkerWeight
a6f7f1b4 803 ).toBeGreaterThan(0)
08f3f44c
JB
804 expect(
805 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
806 workerChoiceStrategy
807 ).workerVirtualTaskRunTime
808 ).toBe(0)
caeb9817
JB
809 // We need to clean up the resources after our test
810 await pool.destroy()
811 })
812
89b09b26 813 it('Verify unknown strategy throw error', () => {
a35560ba
S
814 expect(
815 () =>
816 new DynamicThreadPool(
817 min,
818 max,
819 './tests/worker-files/thread/testWorker.js',
1927ee67 820 { workerChoiceStrategy: 'UNKNOWN_STRATEGY' }
a35560ba 821 )
d4aeae5a 822 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")
a35560ba
S
823 })
824})