1 const { expect
} = require('expect')
3 WorkerChoiceStrategies
,
7 } = require('../../../lib/index')
9 describe('Selection strategies test suite', () => {
13 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
14 expect(WorkerChoiceStrategies
.ROUND_ROBIN
).toBe('ROUND_ROBIN')
15 expect(WorkerChoiceStrategies
.LESS_USED
).toBe('LESS_USED')
16 expect(WorkerChoiceStrategies
.LESS_BUSY
).toBe('LESS_BUSY')
17 expect(WorkerChoiceStrategies
.FAIR_SHARE
).toBe('FAIR_SHARE')
18 expect(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
).toBe(
19 'WEIGHTED_ROUND_ROBIN'
23 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
24 const pool
= new DynamicThreadPool(
27 './tests/worker-files/thread/testWorker.js'
29 expect(pool
.opts
.workerChoiceStrategy
).toBe(
30 WorkerChoiceStrategies
.ROUND_ROBIN
32 // We need to clean up the resources after our test
36 it('Verify ROUND_ROBIN strategy is taken at pool creation', async () => {
37 const pool
= new FixedThreadPool(
39 './tests/worker-files/thread/testWorker.js',
40 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
42 expect(pool
.opts
.workerChoiceStrategy
).toBe(
43 WorkerChoiceStrategies
.ROUND_ROBIN
46 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.nextWorkerId
48 // We need to clean up the resources after our test
52 it('Verify ROUND_ROBIN strategy can be set after pool creation', async () => {
53 const pool
= new DynamicThreadPool(
56 './tests/worker-files/thread/testWorker.js'
58 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
59 expect(pool
.opts
.workerChoiceStrategy
).toBe(
60 WorkerChoiceStrategies
.ROUND_ROBIN
62 // We need to clean up the resources after our test
66 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
67 let pool
= new FixedThreadPool(
69 './tests/worker-files/thread/testWorker.js'
71 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
73 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
76 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
79 pool
= new DynamicThreadPool(
82 './tests/worker-files/thread/testWorker.js'
84 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
86 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
89 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
91 // We need to clean up the resources after our test
95 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
96 const pool
= new FixedThreadPool(
98 './tests/worker-files/thread/testWorker.js',
99 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
101 expect(pool
.opts
.workerChoiceStrategy
).toBe(
102 WorkerChoiceStrategies
.ROUND_ROBIN
104 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
106 for (let i
= 0; i
< max
* 2; i
++) {
107 promises
.push(pool
.execute())
109 await Promise
.all(promises
)
110 // We need to clean up the resources after our test
114 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
115 const pool
= new DynamicThreadPool(
118 './tests/worker-files/thread/testWorker.js',
119 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
121 expect(pool
.opts
.workerChoiceStrategy
).toBe(
122 WorkerChoiceStrategies
.ROUND_ROBIN
124 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
126 for (let i
= 0; i
< max
* 2; i
++) {
127 promises
.push(pool
.execute())
129 await Promise
.all(promises
)
130 // We need to clean up the resources after our test
134 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
135 let pool
= new FixedClusterPool(
137 './tests/worker-files/cluster/testWorker.js'
139 let results
= new Set()
140 for (let i
= 0; i
< max
; i
++) {
141 results
.add(pool
.chooseWorker()[1].id
)
143 expect(results
.size
).toBe(max
)
145 pool
= new FixedThreadPool(max
, './tests/worker-files/thread/testWorker.js')
147 for (let i
= 0; i
< max
; i
++) {
148 results
.add(pool
.chooseWorker()[1].threadId
)
150 expect(results
.size
).toBe(max
)
154 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
155 let pool
= new FixedThreadPool(
157 './tests/worker-files/thread/testWorker.js',
158 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
161 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.nextWorkerId
163 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
165 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.nextWorkerId
168 pool
= new DynamicThreadPool(
171 './tests/worker-files/thread/testWorker.js',
172 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
175 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
178 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
180 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
183 // We need to clean up the resources after our test
187 it('Verify LESS_USED strategy is taken at pool creation', async () => {
188 const pool
= new FixedThreadPool(
190 './tests/worker-files/thread/testWorker.js',
191 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
193 expect(pool
.opts
.workerChoiceStrategy
).toBe(
194 WorkerChoiceStrategies
.LESS_USED
196 // We need to clean up the resources after our test
200 it('Verify LESS_USED strategy can be set after pool creation', async () => {
201 const pool
= new FixedThreadPool(
203 './tests/worker-files/thread/testWorker.js'
205 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
206 expect(pool
.opts
.workerChoiceStrategy
).toBe(
207 WorkerChoiceStrategies
.LESS_USED
209 // We need to clean up the resources after our test
213 it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => {
214 let pool
= new FixedThreadPool(
216 './tests/worker-files/thread/testWorker.js'
218 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
220 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
223 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
226 pool
= new DynamicThreadPool(
229 './tests/worker-files/thread/testWorker.js'
231 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
233 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
236 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
238 // We need to clean up the resources after our test
242 it('Verify LESS_USED strategy can be run in a fixed pool', async () => {
243 const pool
= new FixedThreadPool(
245 './tests/worker-files/thread/testWorker.js',
246 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
248 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
250 for (let i
= 0; i
< max
* 2; i
++) {
251 promises
.push(pool
.execute())
253 await Promise
.all(promises
)
254 // We need to clean up the resources after our test
258 it('Verify LESS_USED strategy can be run in a dynamic pool', async () => {
259 const pool
= new DynamicThreadPool(
262 './tests/worker-files/thread/testWorker.js',
263 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
265 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
267 for (let i
= 0; i
< max
* 2; i
++) {
268 promises
.push(pool
.execute())
270 await Promise
.all(promises
)
271 // We need to clean up the resources after our test
275 it('Verify LESS_BUSY strategy is taken at pool creation', async () => {
276 const pool
= new FixedThreadPool(
278 './tests/worker-files/thread/testWorker.js',
279 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
281 expect(pool
.opts
.workerChoiceStrategy
).toBe(
282 WorkerChoiceStrategies
.LESS_BUSY
284 // We need to clean up the resources after our test
288 it('Verify LESS_BUSY strategy can be set after pool creation', async () => {
289 const pool
= new FixedThreadPool(
291 './tests/worker-files/thread/testWorker.js'
293 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
294 expect(pool
.opts
.workerChoiceStrategy
).toBe(
295 WorkerChoiceStrategies
.LESS_BUSY
297 // We need to clean up the resources after our test
301 it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => {
302 let pool
= new FixedThreadPool(
304 './tests/worker-files/thread/testWorker.js'
306 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
308 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
311 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
314 pool
= new DynamicThreadPool(
317 './tests/worker-files/thread/testWorker.js'
319 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
321 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
324 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
326 // We need to clean up the resources after our test
330 it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => {
331 const pool
= new FixedThreadPool(
333 './tests/worker-files/thread/testWorker.js',
334 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
336 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
338 for (let i
= 0; i
< max
* 2; i
++) {
339 promises
.push(pool
.execute())
341 await Promise
.all(promises
)
342 // We need to clean up the resources after our test
346 it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => {
347 const pool
= new DynamicThreadPool(
350 './tests/worker-files/thread/testWorker.js',
351 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
353 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
355 for (let i
= 0; i
< max
* 2; i
++) {
356 promises
.push(pool
.execute())
358 await Promise
.all(promises
)
359 // We need to clean up the resources after our test
363 it('Verify FAIR_SHARE strategy is taken at pool creation', async () => {
364 const pool
= new FixedThreadPool(
366 './tests/worker-files/thread/testWorker.js',
367 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
369 expect(pool
.opts
.workerChoiceStrategy
).toBe(
370 WorkerChoiceStrategies
.FAIR_SHARE
372 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
374 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
379 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
384 // We need to clean up the resources after our test
388 it('Verify FAIR_SHARE strategy can be set after pool creation', async () => {
389 const pool
= new FixedThreadPool(
391 './tests/worker-files/thread/testWorker.js'
393 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
394 expect(pool
.opts
.workerChoiceStrategy
).toBe(
395 WorkerChoiceStrategies
.FAIR_SHARE
397 // We need to clean up the resources after our test
401 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
402 let pool
= new FixedThreadPool(
404 './tests/worker-files/thread/testWorker.js'
406 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
408 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
411 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
414 pool
= new DynamicThreadPool(
417 './tests/worker-files/thread/testWorker.js'
419 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
421 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
424 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
426 // We need to clean up the resources after our test
430 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
431 const pool
= new FixedThreadPool(
433 './tests/worker-files/thread/testWorker.js',
434 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
436 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
438 for (let i
= 0; i
< max
* 2; i
++) {
439 promises
.push(pool
.execute())
441 await Promise
.all(promises
)
443 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
444 .workerLastVirtualTaskTimestamp
.size
445 ).toBe(pool
.workers
.length
)
446 // We need to clean up the resources after our test
450 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
451 const pool
= new DynamicThreadPool(
454 './tests/worker-files/thread/testWorker.js',
455 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
457 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
459 const maxMultiplier
= 2
460 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
461 promises
.push(pool
.execute())
463 await Promise
.all(promises
)
464 // if (process.platform !== 'win32') {
466 // pool.workerChoiceStrategyContext.workerChoiceStrategy
467 // .workerChoiceStrategy.workerLastVirtualTaskTimestamp.size
468 // ).toBe(pool.workers.length)
470 // We need to clean up the resources after our test
474 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
475 let pool
= new FixedThreadPool(
477 './tests/worker-files/thread/testWorker.js'
480 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
481 .workerLastVirtualTaskTimestamp
483 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
484 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
486 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
491 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
497 pool
= new DynamicThreadPool(
500 './tests/worker-files/thread/testWorker.js'
503 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
504 .workerLastVirtualTaskTimestamp
506 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
507 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
509 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
514 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
519 // We need to clean up the resources after our test
523 it('Verify WEIGHTED_ROUND_ROBIN strategy is taken at pool creation', async () => {
524 const pool
= new FixedThreadPool(
526 './tests/worker-files/thread/testWorker.js',
527 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
529 expect(pool
.opts
.workerChoiceStrategy
).toBe(
530 WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
533 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
536 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
538 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.keys()) {
540 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
545 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
550 // We need to clean up the resources after our test
554 it('Verify WEIGHTED_ROUND_ROBIN strategy can be set after pool creation', async () => {
555 const pool
= new FixedThreadPool(
557 './tests/worker-files/thread/testWorker.js'
559 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
560 expect(pool
.opts
.workerChoiceStrategy
).toBe(
561 WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
563 // We need to clean up the resources after our test
567 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
568 let pool
= new FixedThreadPool(
570 './tests/worker-files/thread/testWorker.js'
572 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
574 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
577 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
580 pool
= new DynamicThreadPool(
583 './tests/worker-files/thread/testWorker.js'
585 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
587 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
590 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
592 // We need to clean up the resources after our test
596 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
597 const pool
= new FixedThreadPool(
599 './tests/worker-files/thread/testWorker.js',
600 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
602 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
604 for (let i
= 0; i
< max
* 2; i
++) {
605 promises
.push(pool
.execute())
607 await Promise
.all(promises
)
609 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
611 ).toBe(pool
.workers
.length
)
612 // We need to clean up the resources after our test
616 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
617 const pool
= new DynamicThreadPool(
620 './tests/worker-files/thread/testWorker.js',
621 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
623 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
625 const maxMultiplier
=
626 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
627 .defaultWorkerWeight
* 2
628 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
629 promises
.push(pool
.execute())
631 await Promise
.all(promises
)
632 if (process
.platform
!== 'win32') {
634 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
635 .workerChoiceStrategy
.workersTaskRunTime
.size
636 ).toBe(pool
.workers
.length
)
638 // We need to clean up the resources after our test
642 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
643 let pool
= new FixedThreadPool(
645 './tests/worker-files/thread/testWorker.js'
648 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
651 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
654 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
656 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
658 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
661 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
663 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.keys()) {
665 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
671 pool
= new DynamicThreadPool(
674 './tests/worker-files/thread/testWorker.js'
677 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
681 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
685 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
688 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
690 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
694 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
697 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
.workersTaskRunTime
.keys()) {
699 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerChoiceStrategy
.workersTaskRunTime
.get(
704 // We need to clean up the resources after our test
708 it('Verify unknown strategies throw error', () => {
711 new DynamicThreadPool(
714 './tests/worker-files/thread/testWorker.js',
715 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
718 new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found")