fix: fix worker function type definition and validation
[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
15d56315 7} = require('../../../lib/index')
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) {
80 for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies
81 .get(workerChoiceStrategy)
82 .workerLastVirtualTaskTimestamp.keys()) {
83 expect(
84 pool.workerChoiceStrategyContext.workerChoiceStrategies
85 .get(workerChoiceStrategy)
86 .workerLastVirtualTaskTimestamp.get(workerNodeKey).start
87 ).toBe(0)
88 expect(
89 pool.workerChoiceStrategyContext.workerChoiceStrategies
90 .get(workerChoiceStrategy)
91 .workerLastVirtualTaskTimestamp.get(workerNodeKey).end
92 ).toBe(0)
93 }
94 } else if (
95 workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
96 ) {
97 expect(
98 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
99 workerChoiceStrategy
100 ).currentWorkerNodeId
101 ).toBe(0)
102 expect(
103 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
104 workerChoiceStrategy
105 ).defaultWorkerWeight
106 ).toBeGreaterThan(0)
107 for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies
108 .get(workerChoiceStrategy)
109 .workersTaskRunTime.keys()) {
110 expect(
111 pool.workerChoiceStrategyContext.workerChoiceStrategies
112 .get(workerChoiceStrategy)
113 .workersTaskRunTime.get(workerNodeKey).weight
114 ).toBeGreaterThan(0)
115 expect(
116 pool.workerChoiceStrategyContext.workerChoiceStrategies
117 .get(workerChoiceStrategy)
118 .workersTaskRunTime.get(workerNodeKey).runTime
119 ).toBe(0)
120 }
121 }
122 }
e843b904
JB
123 await pool.destroy()
124 })
125
10fcfaf4 126 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
594bfb84 127 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
10fcfaf4
JB
128 let pool = new FixedThreadPool(
129 max,
d710242d 130 './tests/worker-files/thread/testWorker.js',
594bfb84 131 { workerChoiceStrategy }
10fcfaf4 132 )
10fcfaf4 133 expect(
97a2abc3 134 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 135 ).toBe(false)
c6bd2650
JB
136 expect(
137 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
138 ).toBe(false)
78099a15
JB
139 expect(
140 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
141 ).toBe(false)
fd7ebd49 142 await pool.destroy()
10fcfaf4
JB
143 pool = new DynamicThreadPool(
144 min,
145 max,
d710242d 146 './tests/worker-files/thread/testWorker.js',
594bfb84 147 { workerChoiceStrategy }
10fcfaf4 148 )
10fcfaf4 149 expect(
97a2abc3 150 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 151 ).toBe(false)
c6bd2650
JB
152 expect(
153 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
154 ).toBe(false)
78099a15
JB
155 expect(
156 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
157 ).toBe(false)
10fcfaf4
JB
158 // We need to clean up the resources after our test
159 await pool.destroy()
160 })
161
bdaf31cd 162 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
bdaf31cd
JB
163 const pool = new FixedThreadPool(
164 max,
165 './tests/worker-files/thread/testWorker.js',
166 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
167 )
bdaf31cd
JB
168 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
169 const promises = []
170 for (let i = 0; i < max * 2; i++) {
6db75ad9 171 promises.push(pool.execute())
bdaf31cd
JB
172 }
173 await Promise.all(promises)
174 // We need to clean up the resources after our test
175 await pool.destroy()
176 })
177
178 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
bdaf31cd
JB
179 const pool = new DynamicThreadPool(
180 min,
181 max,
182 './tests/worker-files/thread/testWorker.js',
183 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
184 )
bdaf31cd
JB
185 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
186 const promises = []
187 for (let i = 0; i < max * 2; i++) {
6db75ad9 188 promises.push(pool.execute())
bdaf31cd
JB
189 }
190 await Promise.all(promises)
191 // We need to clean up the resources after our test
192 await pool.destroy()
193 })
194
2ced693a 195 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
594bfb84 196 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
2ced693a
JB
197 let pool = new FixedClusterPool(
198 max,
594bfb84
JB
199 './tests/worker-files/cluster/testWorker.js',
200 { workerChoiceStrategy }
2ced693a
JB
201 )
202 let results = new Set()
203 for (let i = 0; i < max; i++) {
adc3c320 204 results.add(pool.chooseWorkerNode()[1].worker.id)
2ced693a
JB
205 }
206 expect(results.size).toBe(max)
207 await pool.destroy()
594bfb84
JB
208 pool = new FixedThreadPool(
209 max,
210 './tests/worker-files/thread/testWorker.js',
211 { workerChoiceStrategy }
212 )
2ced693a
JB
213 results = new Set()
214 for (let i = 0; i < max; i++) {
adc3c320 215 results.add(pool.chooseWorkerNode()[1].worker.threadId)
2ced693a
JB
216 }
217 expect(results.size).toBe(max)
218 await pool.destroy()
219 })
220
a6f7f1b4 221 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
594bfb84 222 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
a6f7f1b4
JB
223 let pool = new FixedThreadPool(
224 max,
225 './tests/worker-files/thread/testWorker.js',
226 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
227 )
38f6e859 228 expect(
95c83464 229 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 230 workerChoiceStrategy
f06e48d8 231 ).nextWorkerNodeId
b529c323 232 ).toBeDefined()
594bfb84 233 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 234 expect(
95c83464 235 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 236 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 237 ).nextWorkerNodeId
a6f7f1b4
JB
238 ).toBe(0)
239 await pool.destroy()
240 pool = new DynamicThreadPool(
241 min,
242 max,
243 './tests/worker-files/thread/testWorker.js',
244 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
245 )
38f6e859 246 expect(
95c83464 247 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 248 workerChoiceStrategy
f06e48d8 249 ).nextWorkerNodeId
b529c323 250 ).toBeDefined()
594bfb84 251 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 252 expect(
95c83464 253 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 254 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 255 ).nextWorkerNodeId
a6f7f1b4
JB
256 ).toBe(0)
257 // We need to clean up the resources after our test
258 await pool.destroy()
259 })
260
737c6d97 261 it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => {
594bfb84 262 const workerChoiceStrategy = WorkerChoiceStrategies.LESS_USED
10fcfaf4
JB
263 let pool = new FixedThreadPool(
264 max,
d710242d 265 './tests/worker-files/thread/testWorker.js',
594bfb84 266 { workerChoiceStrategy }
10fcfaf4 267 )
10fcfaf4 268 expect(
97a2abc3 269 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 270 ).toBe(false)
c6bd2650
JB
271 expect(
272 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
273 ).toBe(false)
78099a15
JB
274 expect(
275 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
276 ).toBe(false)
fd7ebd49 277 await pool.destroy()
10fcfaf4
JB
278 pool = new DynamicThreadPool(
279 min,
280 max,
d710242d 281 './tests/worker-files/thread/testWorker.js',
594bfb84 282 { workerChoiceStrategy }
10fcfaf4 283 )
10fcfaf4 284 expect(
97a2abc3 285 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 286 ).toBe(false)
c6bd2650
JB
287 expect(
288 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
289 ).toBe(false)
78099a15
JB
290 expect(
291 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
292 ).toBe(false)
10fcfaf4
JB
293 // We need to clean up the resources after our test
294 await pool.destroy()
295 })
296
737c6d97 297 it('Verify LESS_USED strategy can be run in a fixed pool', async () => {
b98ec2e6
JB
298 const pool = new FixedThreadPool(
299 max,
300 './tests/worker-files/thread/testWorker.js',
737c6d97 301 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
b98ec2e6 302 )
168c526f 303 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
a35560ba
S
304 const promises = []
305 for (let i = 0; i < max * 2; i++) {
6db75ad9 306 promises.push(pool.execute())
a35560ba
S
307 }
308 await Promise.all(promises)
a35560ba
S
309 // We need to clean up the resources after our test
310 await pool.destroy()
311 })
312
737c6d97 313 it('Verify LESS_USED strategy can be run in a dynamic pool', async () => {
ff5e76e1
JB
314 const pool = new DynamicThreadPool(
315 min,
316 max,
317 './tests/worker-files/thread/testWorker.js',
737c6d97 318 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED }
ff5e76e1 319 )
168c526f
JB
320 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
321 const promises = []
322 for (let i = 0; i < max * 2; i++) {
323 promises.push(pool.execute())
324 }
325 await Promise.all(promises)
326 // We need to clean up the resources after our test
327 await pool.destroy()
328 })
329
168c526f 330 it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => {
594bfb84 331 const workerChoiceStrategy = WorkerChoiceStrategies.LESS_BUSY
168c526f
JB
332 let pool = new FixedThreadPool(
333 max,
d710242d 334 './tests/worker-files/thread/testWorker.js',
594bfb84 335 { workerChoiceStrategy }
168c526f 336 )
168c526f 337 expect(
97a2abc3 338 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
168c526f 339 ).toBe(true)
c6bd2650
JB
340 expect(
341 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
342 ).toBe(false)
78099a15
JB
343 expect(
344 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
345 ).toBe(false)
168c526f
JB
346 await pool.destroy()
347 pool = new DynamicThreadPool(
348 min,
349 max,
d710242d 350 './tests/worker-files/thread/testWorker.js',
594bfb84 351 { workerChoiceStrategy }
168c526f 352 )
168c526f 353 expect(
97a2abc3 354 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
168c526f 355 ).toBe(true)
c6bd2650
JB
356 expect(
357 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
358 ).toBe(false)
78099a15
JB
359 expect(
360 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
361 ).toBe(false)
168c526f
JB
362 // We need to clean up the resources after our test
363 await pool.destroy()
364 })
365
366 it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => {
367 const pool = new FixedThreadPool(
368 max,
369 './tests/worker-files/thread/testWorker.js',
370 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
371 )
372 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
373 const promises = []
374 for (let i = 0; i < max * 2; i++) {
375 promises.push(pool.execute())
376 }
377 await Promise.all(promises)
378 // We need to clean up the resources after our test
379 await pool.destroy()
380 })
381
382 it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => {
383 const pool = new DynamicThreadPool(
384 min,
385 max,
386 './tests/worker-files/thread/testWorker.js',
387 { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY }
388 )
389 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
ff5e76e1
JB
390 const promises = []
391 for (let i = 0; i < max * 2; i++) {
6db75ad9 392 promises.push(pool.execute())
ff5e76e1
JB
393 }
394 await Promise.all(promises)
ff5e76e1
JB
395 // We need to clean up the resources after our test
396 await pool.destroy()
397 })
398
10fcfaf4 399 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
594bfb84 400 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
10fcfaf4
JB
401 let pool = new FixedThreadPool(
402 max,
d710242d 403 './tests/worker-files/thread/testWorker.js',
594bfb84 404 { workerChoiceStrategy }
10fcfaf4 405 )
10fcfaf4 406 expect(
97a2abc3 407 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 408 ).toBe(true)
c6bd2650
JB
409 expect(
410 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
411 ).toBe(true)
78099a15
JB
412 expect(
413 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
414 ).toBe(false)
fd7ebd49 415 await pool.destroy()
10fcfaf4
JB
416 pool = new DynamicThreadPool(
417 min,
418 max,
d710242d 419 './tests/worker-files/thread/testWorker.js',
594bfb84 420 { workerChoiceStrategy }
10fcfaf4 421 )
10fcfaf4 422 expect(
97a2abc3 423 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 424 ).toBe(true)
c6bd2650
JB
425 expect(
426 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
427 ).toBe(true)
78099a15
JB
428 expect(
429 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
430 ).toBe(false)
10fcfaf4
JB
431 // We need to clean up the resources after our test
432 await pool.destroy()
433 })
434
23ff945a 435 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
23ff945a
JB
436 const pool = new FixedThreadPool(
437 max,
438 './tests/worker-files/thread/testWorker.js',
439 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
440 )
441 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
442 const promises = []
443 for (let i = 0; i < max * 2; i++) {
6db75ad9 444 promises.push(pool.execute())
23ff945a
JB
445 }
446 await Promise.all(promises)
97a2abc3 447 expect(
95c83464 448 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 449 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 450 ).workerLastVirtualTaskTimestamp.size
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)
f7070eee
JB
470 // if (process.platform !== 'win32') {
471 // expect(
95c83464 472 // pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 473 // pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 474 // ).workerLastVirtualTaskTimestamp.size
f06e48d8 475 // ).toBe(pool.workerNodes.length)
f7070eee 476 // }
23ff945a
JB
477 // We need to clean up the resources after our test
478 await pool.destroy()
479 })
480
a6f7f1b4 481 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
594bfb84 482 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
f0829c53 483 let pool = new FixedThreadPool(
caeb9817
JB
484 max,
485 './tests/worker-files/thread/testWorker.js'
486 )
487 expect(
95c83464 488 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 489 workerChoiceStrategy
b529c323
JB
490 ).workerLastVirtualTaskTimestamp
491 ).toBeDefined()
594bfb84 492 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
f06e48d8 493 for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 494 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
95c83464 495 .workerLastVirtualTaskTimestamp.keys()) {
caeb9817 496 expect(
95c83464 497 pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 498 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
f06e48d8 499 .workerLastVirtualTaskTimestamp.get(workerNodeKey).start
caeb9817
JB
500 ).toBe(0)
501 expect(
95c83464 502 pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 503 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
f06e48d8 504 .workerLastVirtualTaskTimestamp.get(workerNodeKey).end
caeb9817
JB
505 ).toBe(0)
506 }
f0829c53
JB
507 await pool.destroy()
508 pool = new DynamicThreadPool(
509 min,
510 max,
511 './tests/worker-files/thread/testWorker.js'
512 )
513 expect(
95c83464 514 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 515 workerChoiceStrategy
b529c323
JB
516 ).workerLastVirtualTaskTimestamp
517 ).toBeDefined()
594bfb84 518 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
f06e48d8 519 for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 520 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
95c83464 521 .workerLastVirtualTaskTimestamp.keys()) {
f0829c53 522 expect(
95c83464 523 pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 524 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
f06e48d8 525 .workerLastVirtualTaskTimestamp.get(workerNodeKey).start
f0829c53
JB
526 ).toBe(0)
527 expect(
95c83464 528 pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 529 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
f06e48d8 530 .workerLastVirtualTaskTimestamp.get(workerNodeKey).end
f0829c53
JB
531 ).toBe(0)
532 }
caeb9817
JB
533 // We need to clean up the resources after our test
534 await pool.destroy()
535 })
536
10fcfaf4 537 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
594bfb84 538 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
10fcfaf4
JB
539 let pool = new FixedThreadPool(
540 max,
d710242d 541 './tests/worker-files/thread/testWorker.js',
594bfb84 542 { workerChoiceStrategy }
10fcfaf4 543 )
10fcfaf4 544 expect(
97a2abc3 545 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 546 ).toBe(true)
c6bd2650
JB
547 expect(
548 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
549 ).toBe(true)
78099a15
JB
550 expect(
551 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
552 ).toBe(false)
fd7ebd49 553 await pool.destroy()
10fcfaf4
JB
554 pool = new DynamicThreadPool(
555 min,
556 max,
d710242d 557 './tests/worker-files/thread/testWorker.js',
594bfb84 558 { workerChoiceStrategy }
10fcfaf4 559 )
10fcfaf4 560 expect(
97a2abc3 561 pool.workerChoiceStrategyContext.getRequiredStatistics().runTime
10fcfaf4 562 ).toBe(true)
c6bd2650
JB
563 expect(
564 pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime
565 ).toBe(true)
78099a15
JB
566 expect(
567 pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime
568 ).toBe(false)
10fcfaf4
JB
569 // We need to clean up the resources after our test
570 await pool.destroy()
571 })
572
b3432a63 573 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
b3432a63
JB
574 const pool = new FixedThreadPool(
575 max,
576 './tests/worker-files/thread/testWorker.js',
577 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
578 )
579 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
580 const promises = []
581 for (let i = 0; i < max * 2; i++) {
6db75ad9 582 promises.push(pool.execute())
b3432a63
JB
583 }
584 await Promise.all(promises)
97a2abc3 585 expect(
95c83464 586 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 587 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 588 ).workersTaskRunTime.size
f06e48d8 589 ).toBe(pool.workerNodes.length)
b3432a63
JB
590 // We need to clean up the resources after our test
591 await pool.destroy()
592 })
593
594 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
b3432a63
JB
595 const pool = new DynamicThreadPool(
596 min,
597 max,
598 './tests/worker-files/thread/testWorker.js',
599 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
600 )
601 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
602 const promises = []
5502c07c 603 const maxMultiplier =
95c83464 604 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 605 pool.workerChoiceStrategyContext.workerChoiceStrategy
8da9e84d 606 ).defaultWorkerWeight * 50
5502c07c 607 for (let i = 0; i < max * maxMultiplier; i++) {
6db75ad9 608 promises.push(pool.execute())
b3432a63
JB
609 }
610 await Promise.all(promises)
9f34a585
JB
611 if (process.platform !== 'win32') {
612 expect(
95c83464 613 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 614 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 615 ).workersTaskRunTime.size
f06e48d8 616 ).toBe(pool.workerNodes.length)
9f34a585 617 }
b3432a63
JB
618 // We need to clean up the resources after our test
619 await pool.destroy()
620 })
621
a6f7f1b4 622 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
594bfb84 623 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
f0829c53 624 let pool = new FixedThreadPool(
caeb9817
JB
625 max,
626 './tests/worker-files/thread/testWorker.js'
627 )
38f6e859 628 expect(
95c83464 629 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 630 workerChoiceStrategy
f06e48d8 631 ).currentWorkerNodeId
b529c323 632 ).toBeDefined()
38f6e859 633 expect(
95c83464 634 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 635 workerChoiceStrategy
b529c323
JB
636 ).defaultWorkerWeight
637 ).toBeDefined()
caeb9817 638 expect(
95c83464 639 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 640 workerChoiceStrategy
b529c323
JB
641 ).workersTaskRunTime
642 ).toBeDefined()
594bfb84 643 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 644 expect(
95c83464 645 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 646 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 647 ).currentWorkerNodeId
a6f7f1b4
JB
648 ).toBe(0)
649 expect(
95c83464 650 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 651 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 652 ).defaultWorkerWeight
a6f7f1b4 653 ).toBeGreaterThan(0)
f06e48d8 654 for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 655 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
95c83464 656 .workersTaskRunTime.keys()) {
caeb9817 657 expect(
95c83464 658 pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 659 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
f06e48d8 660 .workersTaskRunTime.get(workerNodeKey).runTime
caeb9817
JB
661 ).toBe(0)
662 }
f0829c53
JB
663 await pool.destroy()
664 pool = new DynamicThreadPool(
665 min,
666 max,
667 './tests/worker-files/thread/testWorker.js'
668 )
38f6e859 669 expect(
95c83464 670 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 671 workerChoiceStrategy
f06e48d8 672 ).currentWorkerNodeId
b529c323 673 ).toBeDefined()
38f6e859 674 expect(
95c83464 675 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 676 workerChoiceStrategy
b529c323
JB
677 ).defaultWorkerWeight
678 ).toBeDefined()
f0829c53 679 expect(
95c83464 680 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 681 workerChoiceStrategy
b529c323
JB
682 ).workersTaskRunTime
683 ).toBeDefined()
594bfb84 684 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
a6f7f1b4 685 expect(
95c83464 686 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 687 pool.workerChoiceStrategyContext.workerChoiceStrategy
f06e48d8 688 ).currentWorkerNodeId
a6f7f1b4
JB
689 ).toBe(0)
690 expect(
95c83464 691 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 692 pool.workerChoiceStrategyContext.workerChoiceStrategy
95c83464 693 ).defaultWorkerWeight
a6f7f1b4 694 ).toBeGreaterThan(0)
f06e48d8 695 for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 696 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
95c83464 697 .workersTaskRunTime.keys()) {
f0829c53 698 expect(
95c83464 699 pool.workerChoiceStrategyContext.workerChoiceStrategies
d710242d 700 .get(pool.workerChoiceStrategyContext.workerChoiceStrategy)
f06e48d8 701 .workersTaskRunTime.get(workerNodeKey).runTime
f0829c53
JB
702 ).toBe(0)
703 }
caeb9817
JB
704 // We need to clean up the resources after our test
705 await pool.destroy()
706 })
707
89b09b26 708 it('Verify unknown strategy throw error', () => {
a35560ba
S
709 expect(
710 () =>
711 new DynamicThreadPool(
712 min,
713 max,
714 './tests/worker-files/thread/testWorker.js',
1927ee67 715 { workerChoiceStrategy: 'UNKNOWN_STRATEGY' }
a35560ba 716 )
d4aeae5a 717 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")
a35560ba
S
718 })
719})