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
.nextWorkerId
177 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
179 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.nextWorkerId
181 // We need to clean up the resources after our test
185 it('Verify LESS_USED strategy is taken at pool creation', async () => {
186 const pool
= new FixedThreadPool(
188 './tests/worker-files/thread/testWorker.js',
189 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
191 expect(pool
.opts
.workerChoiceStrategy
).toBe(
192 WorkerChoiceStrategies
.LESS_USED
194 // We need to clean up the resources after our test
198 it('Verify LESS_USED strategy can be set after pool creation', async () => {
199 const pool
= new FixedThreadPool(
201 './tests/worker-files/thread/testWorker.js'
203 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
204 expect(pool
.opts
.workerChoiceStrategy
).toBe(
205 WorkerChoiceStrategies
.LESS_USED
207 // We need to clean up the resources after our test
211 it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => {
212 let pool
= new FixedThreadPool(
214 './tests/worker-files/thread/testWorker.js'
216 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
218 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
221 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
224 pool
= new DynamicThreadPool(
227 './tests/worker-files/thread/testWorker.js'
229 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
231 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
234 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
236 // We need to clean up the resources after our test
240 it('Verify LESS_USED strategy can be run in a fixed pool', async () => {
241 const pool
= new FixedThreadPool(
243 './tests/worker-files/thread/testWorker.js',
244 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
246 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
248 for (let i
= 0; i
< max
* 2; i
++) {
249 promises
.push(pool
.execute())
251 await Promise
.all(promises
)
252 // We need to clean up the resources after our test
256 it('Verify LESS_USED strategy can be run in a dynamic pool', async () => {
257 const pool
= new DynamicThreadPool(
260 './tests/worker-files/thread/testWorker.js',
261 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
263 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
265 for (let i
= 0; i
< max
* 2; i
++) {
266 promises
.push(pool
.execute())
268 await Promise
.all(promises
)
269 // We need to clean up the resources after our test
273 it('Verify LESS_BUSY strategy is taken at pool creation', async () => {
274 const pool
= new FixedThreadPool(
276 './tests/worker-files/thread/testWorker.js',
277 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
279 expect(pool
.opts
.workerChoiceStrategy
).toBe(
280 WorkerChoiceStrategies
.LESS_BUSY
282 // We need to clean up the resources after our test
286 it('Verify LESS_BUSY strategy can be set after pool creation', async () => {
287 const pool
= new FixedThreadPool(
289 './tests/worker-files/thread/testWorker.js'
291 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
292 expect(pool
.opts
.workerChoiceStrategy
).toBe(
293 WorkerChoiceStrategies
.LESS_BUSY
295 // We need to clean up the resources after our test
299 it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => {
300 let pool
= new FixedThreadPool(
302 './tests/worker-files/thread/testWorker.js'
304 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
306 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
309 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
312 pool
= new DynamicThreadPool(
315 './tests/worker-files/thread/testWorker.js'
317 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
319 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
322 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
324 // We need to clean up the resources after our test
328 it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => {
329 const pool
= new FixedThreadPool(
331 './tests/worker-files/thread/testWorker.js',
332 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
334 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
336 for (let i
= 0; i
< max
* 2; i
++) {
337 promises
.push(pool
.execute())
339 await Promise
.all(promises
)
340 // We need to clean up the resources after our test
344 it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => {
345 const pool
= new DynamicThreadPool(
348 './tests/worker-files/thread/testWorker.js',
349 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
351 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
353 for (let i
= 0; i
< max
* 2; i
++) {
354 promises
.push(pool
.execute())
356 await Promise
.all(promises
)
357 // We need to clean up the resources after our test
361 it('Verify FAIR_SHARE strategy is taken at pool creation', async () => {
362 const pool
= new FixedThreadPool(
364 './tests/worker-files/thread/testWorker.js',
365 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
367 expect(pool
.opts
.workerChoiceStrategy
).toBe(
368 WorkerChoiceStrategies
.FAIR_SHARE
370 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
372 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
377 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
382 // We need to clean up the resources after our test
386 it('Verify FAIR_SHARE strategy can be set after pool creation', async () => {
387 const pool
= new FixedThreadPool(
389 './tests/worker-files/thread/testWorker.js'
391 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
392 expect(pool
.opts
.workerChoiceStrategy
).toBe(
393 WorkerChoiceStrategies
.FAIR_SHARE
395 // We need to clean up the resources after our test
399 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
400 let pool
= new FixedThreadPool(
402 './tests/worker-files/thread/testWorker.js'
404 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
406 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
409 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
412 pool
= new DynamicThreadPool(
415 './tests/worker-files/thread/testWorker.js'
417 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
419 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
422 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
424 // We need to clean up the resources after our test
428 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
429 const pool
= new FixedThreadPool(
431 './tests/worker-files/thread/testWorker.js',
432 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
434 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
436 for (let i
= 0; i
< max
* 2; i
++) {
437 promises
.push(pool
.execute())
439 await Promise
.all(promises
)
441 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
442 .workerLastVirtualTaskTimestamp
.size
443 ).toBe(pool
.workers
.length
)
444 // We need to clean up the resources after our test
448 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
449 const pool
= new DynamicThreadPool(
452 './tests/worker-files/thread/testWorker.js',
453 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
455 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
457 const maxMultiplier
= 2
458 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
459 promises
.push(pool
.execute())
461 await Promise
.all(promises
)
462 // if (process.platform !== 'win32') {
464 // pool.workerChoiceStrategyContext.workerChoiceStrategy
465 // .workerLastVirtualTaskTimestamp.size
466 // ).toBe(pool.workers.length)
468 // We need to clean up the resources after our test
472 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
473 let pool
= new FixedThreadPool(
475 './tests/worker-files/thread/testWorker.js'
478 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
479 .workerLastVirtualTaskTimestamp
481 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
482 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
484 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
489 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
495 pool
= new DynamicThreadPool(
498 './tests/worker-files/thread/testWorker.js'
501 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
502 .workerLastVirtualTaskTimestamp
504 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
505 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
507 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
512 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(
517 // We need to clean up the resources after our test
521 it('Verify WEIGHTED_ROUND_ROBIN strategy is taken at pool creation', async () => {
522 const pool
= new FixedThreadPool(
524 './tests/worker-files/thread/testWorker.js',
525 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
527 expect(pool
.opts
.workerChoiceStrategy
).toBe(
528 WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
531 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
534 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
536 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.keys()) {
538 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
543 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
548 // We need to clean up the resources after our test
552 it('Verify WEIGHTED_ROUND_ROBIN strategy can be set after pool creation', async () => {
553 const pool
= new FixedThreadPool(
555 './tests/worker-files/thread/testWorker.js'
557 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
558 expect(pool
.opts
.workerChoiceStrategy
).toBe(
559 WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
561 // We need to clean up the resources after our test
565 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
566 let pool
= new FixedThreadPool(
568 './tests/worker-files/thread/testWorker.js'
570 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
572 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
575 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
578 pool
= new DynamicThreadPool(
581 './tests/worker-files/thread/testWorker.js'
583 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
585 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
588 pool
.workerChoiceStrategyContext
.getRequiredStatistics().avgRunTime
590 // We need to clean up the resources after our test
594 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
595 const pool
= new FixedThreadPool(
597 './tests/worker-files/thread/testWorker.js',
598 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
600 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
602 for (let i
= 0; i
< max
* 2; i
++) {
603 promises
.push(pool
.execute())
605 await Promise
.all(promises
)
607 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
609 ).toBe(pool
.workers
.length
)
610 // We need to clean up the resources after our test
614 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
615 const pool
= new DynamicThreadPool(
618 './tests/worker-files/thread/testWorker.js',
619 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
621 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
623 const maxMultiplier
=
624 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
625 .defaultWorkerWeight
* 2
626 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
627 promises
.push(pool
.execute())
629 await Promise
.all(promises
)
630 if (process
.platform
!== 'win32') {
632 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
634 ).toBe(pool
.workers
.length
)
636 // We need to clean up the resources after our test
640 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
641 let pool
= new FixedThreadPool(
643 './tests/worker-files/thread/testWorker.js'
646 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
649 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
652 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
654 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
656 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
659 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
661 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.keys()) {
663 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
669 pool
= new DynamicThreadPool(
672 './tests/worker-files/thread/testWorker.js'
675 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
678 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
681 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
683 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
685 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.currentWorkerId
688 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.defaultWorkerWeight
690 for (const workerKey
of pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.keys()) {
692 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
.workersTaskRunTime
.get(
697 // We need to clean up the resources after our test
701 it('Verify unknown strategies throw error', () => {
704 new DynamicThreadPool(
707 './tests/worker-files/thread/testWorker.js',
708 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
711 new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found")