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