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
.getWorkerChoiceStrategy().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
= new DynamicThreadPool(
79 './tests/worker-files/thread/testWorker.js'
81 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
83 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
85 // We need to clean up the resources after our test
89 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
90 const pool
= new FixedThreadPool(
92 './tests/worker-files/thread/testWorker.js',
93 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
95 expect(pool
.opts
.workerChoiceStrategy
).toBe(
96 WorkerChoiceStrategies
.ROUND_ROBIN
98 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
100 for (let i
= 0; i
< max
* 2; i
++) {
101 promises
.push(pool
.execute())
103 await Promise
.all(promises
)
104 // We need to clean up the resources after our test
108 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
109 const pool
= new DynamicThreadPool(
112 './tests/worker-files/thread/testWorker.js',
113 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
115 expect(pool
.opts
.workerChoiceStrategy
).toBe(
116 WorkerChoiceStrategies
.ROUND_ROBIN
118 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
120 for (let i
= 0; i
< max
* 2; i
++) {
121 promises
.push(pool
.execute())
123 await Promise
.all(promises
)
124 // We need to clean up the resources after our test
128 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
129 let pool
= new FixedClusterPool(
131 './tests/worker-files/cluster/testWorker.js'
133 let results
= new Set()
134 for (let i
= 0; i
< max
; i
++) {
135 results
.add(pool
.chooseWorker()[1].id
)
137 expect(results
.size
).toBe(max
)
139 pool
= new FixedThreadPool(max
, './tests/worker-files/thread/testWorker.js')
141 for (let i
= 0; i
< max
; i
++) {
142 results
.add(pool
.chooseWorker()[1].threadId
)
144 expect(results
.size
).toBe(max
)
148 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
149 let pool
= new FixedThreadPool(
151 './tests/worker-files/thread/testWorker.js',
152 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
155 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy().nextWorkerId
157 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
159 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy().nextWorkerId
162 pool
= new DynamicThreadPool(
165 './tests/worker-files/thread/testWorker.js',
166 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
169 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
170 .workerChoiceStrategy
.nextWorkerId
172 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.ROUND_ROBIN
)
174 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
175 .workerChoiceStrategy
.nextWorkerId
177 // We need to clean up the resources after our test
181 it('Verify LESS_USED strategy is taken at pool creation', async () => {
182 const pool
= new FixedThreadPool(
184 './tests/worker-files/thread/testWorker.js',
185 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
187 expect(pool
.opts
.workerChoiceStrategy
).toBe(
188 WorkerChoiceStrategies
.LESS_USED
190 // We need to clean up the resources after our test
194 it('Verify LESS_USED strategy can be set after pool creation', async () => {
195 const pool
= new FixedThreadPool(
197 './tests/worker-files/thread/testWorker.js'
199 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
200 expect(pool
.opts
.workerChoiceStrategy
).toBe(
201 WorkerChoiceStrategies
.LESS_USED
203 // We need to clean up the resources after our test
207 it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => {
208 let pool
= new FixedThreadPool(
210 './tests/worker-files/thread/testWorker.js'
212 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
214 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
217 pool
= new DynamicThreadPool(
220 './tests/worker-files/thread/testWorker.js'
222 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_USED
)
224 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
226 // We need to clean up the resources after our test
230 it('Verify LESS_USED strategy can be run in a fixed pool', async () => {
231 const pool
= new FixedThreadPool(
233 './tests/worker-files/thread/testWorker.js',
234 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
236 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
238 for (let i
= 0; i
< max
* 2; i
++) {
239 promises
.push(pool
.execute())
241 await Promise
.all(promises
)
242 // We need to clean up the resources after our test
246 it('Verify LESS_USED strategy can be run in a dynamic pool', async () => {
247 const pool
= new DynamicThreadPool(
250 './tests/worker-files/thread/testWorker.js',
251 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_USED
}
253 // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose`
255 for (let i
= 0; i
< max
* 2; i
++) {
256 promises
.push(pool
.execute())
258 await Promise
.all(promises
)
259 // We need to clean up the resources after our test
263 it('Verify LESS_BUSY strategy is taken at pool creation', async () => {
264 const pool
= new FixedThreadPool(
266 './tests/worker-files/thread/testWorker.js',
267 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
269 expect(pool
.opts
.workerChoiceStrategy
).toBe(
270 WorkerChoiceStrategies
.LESS_BUSY
272 // We need to clean up the resources after our test
276 it('Verify LESS_BUSY strategy can be set after pool creation', async () => {
277 const pool
= new FixedThreadPool(
279 './tests/worker-files/thread/testWorker.js'
281 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
282 expect(pool
.opts
.workerChoiceStrategy
).toBe(
283 WorkerChoiceStrategies
.LESS_BUSY
285 // We need to clean up the resources after our test
289 it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => {
290 let pool
= new FixedThreadPool(
292 './tests/worker-files/thread/testWorker.js'
294 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
296 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
299 pool
= new DynamicThreadPool(
302 './tests/worker-files/thread/testWorker.js'
304 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.LESS_BUSY
)
306 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
308 // We need to clean up the resources after our test
312 it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => {
313 const pool
= new FixedThreadPool(
315 './tests/worker-files/thread/testWorker.js',
316 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
318 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
320 for (let i
= 0; i
< max
* 2; i
++) {
321 promises
.push(pool
.execute())
323 await Promise
.all(promises
)
324 // We need to clean up the resources after our test
328 it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => {
329 const pool
= new DynamicThreadPool(
332 './tests/worker-files/thread/testWorker.js',
333 { workerChoiceStrategy
: WorkerChoiceStrategies
.LESS_BUSY
}
335 // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose`
337 for (let i
= 0; i
< max
* 2; i
++) {
338 promises
.push(pool
.execute())
340 await Promise
.all(promises
)
341 // We need to clean up the resources after our test
345 it('Verify FAIR_SHARE strategy is taken at pool creation', async () => {
346 const pool
= new FixedThreadPool(
348 './tests/worker-files/thread/testWorker.js',
349 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
351 expect(pool
.opts
.workerChoiceStrategy
).toBe(
352 WorkerChoiceStrategies
.FAIR_SHARE
354 for (const workerKey
of pool
.workerChoiceStrategyContext
355 .getWorkerChoiceStrategy()
356 .workerLastVirtualTaskTimestamp
.keys()) {
358 pool
.workerChoiceStrategyContext
359 .getWorkerChoiceStrategy()
360 .workerLastVirtualTaskTimestamp
.get(workerKey
).start
363 pool
.workerChoiceStrategyContext
364 .getWorkerChoiceStrategy()
365 .workerLastVirtualTaskTimestamp
.get(workerKey
).end
368 // We need to clean up the resources after our test
372 it('Verify FAIR_SHARE strategy can be set after pool creation', async () => {
373 const pool
= new FixedThreadPool(
375 './tests/worker-files/thread/testWorker.js'
377 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
378 expect(pool
.opts
.workerChoiceStrategy
).toBe(
379 WorkerChoiceStrategies
.FAIR_SHARE
381 // We need to clean up the resources after our test
385 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
386 let pool
= new FixedThreadPool(
388 './tests/worker-files/thread/testWorker.js'
390 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
392 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
395 pool
= new DynamicThreadPool(
398 './tests/worker-files/thread/testWorker.js'
400 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
402 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
404 // We need to clean up the resources after our test
408 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
409 const pool
= new FixedThreadPool(
411 './tests/worker-files/thread/testWorker.js',
412 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
414 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
416 for (let i
= 0; i
< max
* 2; i
++) {
417 promises
.push(pool
.execute())
419 await Promise
.all(promises
)
421 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
422 .workerLastVirtualTaskTimestamp
.size
423 ).toBe(pool
.workers
.length
)
424 // We need to clean up the resources after our test
428 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
429 const pool
= new DynamicThreadPool(
432 './tests/worker-files/thread/testWorker.js',
433 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
435 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
437 for (let i
= 0; i
< max
* 2; i
++) {
438 promises
.push(pool
.execute())
440 await Promise
.all(promises
)
442 // pool.workerChoiceStrategyContext.getWorkerChoiceStrategy()
443 // .workerChoiceStrategy.workerLastVirtualTaskTimestamp.size
444 // ).toBe(pool.workers.length)
445 // We need to clean up the resources after our test
449 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
450 let pool
= new FixedThreadPool(
452 './tests/worker-files/thread/testWorker.js'
455 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
456 .workerLastVirtualTaskTimestamp
458 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
459 for (const workerKey
of pool
.workerChoiceStrategyContext
460 .getWorkerChoiceStrategy()
461 .workerLastVirtualTaskTimestamp
.keys()) {
463 pool
.workerChoiceStrategyContext
464 .getWorkerChoiceStrategy()
465 .workerLastVirtualTaskTimestamp
.get(workerKey
).start
468 pool
.workerChoiceStrategyContext
469 .getWorkerChoiceStrategy()
470 .workerLastVirtualTaskTimestamp
.get(workerKey
).end
474 pool
= new DynamicThreadPool(
477 './tests/worker-files/thread/testWorker.js'
480 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
481 .workerChoiceStrategy
.workerLastVirtualTaskTimestamp
483 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.FAIR_SHARE
)
484 for (const workerKey
of pool
.workerChoiceStrategyContext
485 .getWorkerChoiceStrategy()
486 .workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.keys()) {
488 pool
.workerChoiceStrategyContext
489 .getWorkerChoiceStrategy()
490 .workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(workerKey
)
494 pool
.workerChoiceStrategyContext
495 .getWorkerChoiceStrategy()
496 .workerChoiceStrategy
.workerLastVirtualTaskTimestamp
.get(workerKey
)
500 // We need to clean up the resources after our test
504 it('Verify WEIGHTED_ROUND_ROBIN strategy is taken at pool creation', async () => {
505 const pool
= new FixedThreadPool(
507 './tests/worker-files/thread/testWorker.js',
508 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
510 expect(pool
.opts
.workerChoiceStrategy
).toBe(
511 WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
514 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy().currentWorkerId
517 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
520 for (const workerKey
of pool
.workerChoiceStrategyContext
521 .getWorkerChoiceStrategy()
522 .workersTaskRunTime
.keys()) {
524 pool
.workerChoiceStrategyContext
525 .getWorkerChoiceStrategy()
526 .workersTaskRunTime
.get(workerKey
).weight
529 pool
.workerChoiceStrategyContext
530 .getWorkerChoiceStrategy()
531 .workersTaskRunTime
.get(workerKey
).runTime
534 // We need to clean up the resources after our test
538 it('Verify WEIGHTED_ROUND_ROBIN strategy can be set after pool creation', async () => {
539 const pool
= new FixedThreadPool(
541 './tests/worker-files/thread/testWorker.js'
543 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
544 expect(pool
.opts
.workerChoiceStrategy
).toBe(
545 WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
547 // We need to clean up the resources after our test
551 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
552 let pool
= new FixedThreadPool(
554 './tests/worker-files/thread/testWorker.js'
556 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
558 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
561 pool
= new DynamicThreadPool(
564 './tests/worker-files/thread/testWorker.js'
566 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
568 pool
.workerChoiceStrategyContext
.getRequiredStatistics().runTime
570 // We need to clean up the resources after our test
574 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
575 const pool
= new FixedThreadPool(
577 './tests/worker-files/thread/testWorker.js',
578 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
580 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
582 for (let i
= 0; i
< max
* 2; i
++) {
583 promises
.push(pool
.execute())
585 await Promise
.all(promises
)
587 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
588 .workersTaskRunTime
.size
589 ).toBe(pool
.workers
.length
)
590 // We need to clean up the resources after our test
594 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
595 const pool
= new DynamicThreadPool(
598 './tests/worker-files/thread/testWorker.js',
599 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
601 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
603 for (let i
= 0; i
< max
* 2; i
++) {
604 promises
.push(pool
.execute())
606 await Promise
.all(promises
)
608 // pool.workerChoiceStrategyContext.getWorkerChoiceStrategy()
609 // .workerChoiceStrategy.workersTaskRunTime.size
610 // ).toBe(pool.workers.length)
611 // We need to clean up the resources after our test
615 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
616 let pool
= new FixedThreadPool(
618 './tests/worker-files/thread/testWorker.js'
621 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy().currentWorkerId
624 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
628 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
631 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
633 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy().currentWorkerId
636 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
639 for (const workerKey
of pool
.workerChoiceStrategyContext
640 .getWorkerChoiceStrategy()
641 .workersTaskRunTime
.keys()) {
643 pool
.workerChoiceStrategyContext
644 .getWorkerChoiceStrategy()
645 .workersTaskRunTime
.get(workerKey
).runTime
649 pool
= new DynamicThreadPool(
652 './tests/worker-files/thread/testWorker.js'
655 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
656 .workerChoiceStrategy
.currentWorkerId
659 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
660 .workerChoiceStrategy
.defaultWorkerWeight
663 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
664 .workerChoiceStrategy
.workersTaskRunTime
666 pool
.setWorkerChoiceStrategy(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
)
668 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
669 .workerChoiceStrategy
.currentWorkerId
672 pool
.workerChoiceStrategyContext
.getWorkerChoiceStrategy()
673 .workerChoiceStrategy
.defaultWorkerWeight
675 for (const workerKey
of pool
.workerChoiceStrategyContext
676 .getWorkerChoiceStrategy()
677 .workerChoiceStrategy
.workersTaskRunTime
.keys()) {
679 pool
.workerChoiceStrategyContext
680 .getWorkerChoiceStrategy()
681 .workerChoiceStrategy
.workersTaskRunTime
.get(workerKey
).runTime
684 // We need to clean up the resources after our test
688 it('Verify unknown strategies throw error', () => {
691 new DynamicThreadPool(
694 './tests/worker-files/thread/testWorker.js',
695 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
698 new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found")