1 const { expect
} = require('expect')
3 WorkerChoiceStrategies
,
7 } = require('../../../lib')
8 const { CircularArray
} = require('../../../lib/circular-array')
10 describe('Selection strategies test suite', () => {
14 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
15 expect(WorkerChoiceStrategies
.ROUND_ROBIN
).toBe('ROUND_ROBIN')
16 expect(WorkerChoiceStrategies
.LEAST_USED
).toBe('LEAST_USED')
17 expect(WorkerChoiceStrategies
.LEAST_BUSY
).toBe('LEAST_BUSY')
18 expect(WorkerChoiceStrategies
.FAIR_SHARE
).toBe('FAIR_SHARE')
19 expect(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
).toBe(
20 'WEIGHTED_ROUND_ROBIN'
22 expect(WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
).toBe(
23 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'
27 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
28 const pool
= new DynamicThreadPool(
31 './tests/worker-files/thread/testWorker.js'
33 expect(pool
.opts
.workerChoiceStrategy
).toBe(
34 WorkerChoiceStrategies
.ROUND_ROBIN
36 // We need to clean up the resources after our test
40 it('Verify available strategies are taken at pool creation', async () => {
41 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
42 const pool
= new FixedThreadPool(
44 './tests/worker-files/thread/testWorker.js',
45 { workerChoiceStrategy
}
47 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
48 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
55 it('Verify available strategies can be set after pool creation', async () => {
56 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
57 const pool
= new DynamicThreadPool(
60 './tests/worker-files/thread/testWorker.js'
62 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
63 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
64 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
71 it('Verify available strategies default internals at pool creation', async () => {
72 const pool
= new FixedThreadPool(
74 './tests/worker-files/thread/testWorker.js'
76 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
77 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.ROUND_ROBIN
) {
79 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
83 } else if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
85 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
87 ).workersVirtualTaskEndTimestamp
88 ).toBeInstanceOf(Array
)
90 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
92 ).workersVirtualTaskEndTimestamp
.length
95 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
98 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
100 ).currentWorkerNodeId
103 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
105 ).defaultWorkerWeight
108 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
110 ).workerVirtualTaskRunTime
117 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
118 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
119 let pool
= new FixedThreadPool(
121 './tests/worker-files/thread/testWorker.js',
122 { workerChoiceStrategy
}
125 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
136 pool
= new DynamicThreadPool(
139 './tests/worker-files/thread/testWorker.js',
140 { workerChoiceStrategy
}
143 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
153 // We need to clean up the resources after our test
157 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
158 const pool
= new FixedThreadPool(
160 './tests/worker-files/thread/testWorker.js',
161 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
163 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
164 const promises
= new Set()
165 const maxMultiplier
= 2
166 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
167 promises
.add(pool
.execute())
169 await Promise
.all(promises
)
170 for (const workerNode
of pool
.workerNodes
) {
171 expect(workerNode
.workerUsage
).toStrictEqual({
173 executed
: maxMultiplier
,
182 history
: expect
.any(CircularArray
)
188 history
: expect
.any(CircularArray
)
194 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
195 WorkerChoiceStrategies
.ROUND_ROBIN
198 // We need to clean up the resources after our test
202 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
203 const pool
= new DynamicThreadPool(
206 './tests/worker-files/thread/testWorker.js',
207 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
209 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
210 const promises
= new Set()
211 const maxMultiplier
= 2
212 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
213 promises
.add(pool
.execute())
215 await Promise
.all(promises
)
216 for (const workerNode
of pool
.workerNodes
) {
217 expect(workerNode
.workerUsage
).toStrictEqual({
219 executed
: maxMultiplier
,
228 history
: expect
.any(CircularArray
)
234 history
: expect
.any(CircularArray
)
240 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
241 WorkerChoiceStrategies
.ROUND_ROBIN
244 // We need to clean up the resources after our test
248 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
249 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
250 let pool
= new FixedClusterPool(
252 './tests/worker-files/cluster/testWorker.js',
253 { workerChoiceStrategy
}
255 let results
= new Set()
256 for (let i
= 0; i
< max
; i
++) {
257 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
259 expect(results
.size
).toBe(max
)
261 pool
= new FixedThreadPool(
263 './tests/worker-files/thread/testWorker.js',
264 { workerChoiceStrategy
}
267 for (let i
= 0; i
< max
; i
++) {
268 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
270 expect(results
.size
).toBe(max
)
274 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
275 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
276 let pool
= new FixedThreadPool(
278 './tests/worker-files/thread/testWorker.js',
279 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
282 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
286 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
288 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
289 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
293 pool
= new DynamicThreadPool(
296 './tests/worker-files/thread/testWorker.js',
297 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
300 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
304 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
306 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
307 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
310 // We need to clean up the resources after our test
314 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
315 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
316 let pool
= new FixedThreadPool(
318 './tests/worker-files/thread/testWorker.js',
319 { workerChoiceStrategy
}
322 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
333 pool
= new DynamicThreadPool(
336 './tests/worker-files/thread/testWorker.js',
337 { workerChoiceStrategy
}
340 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
350 // We need to clean up the resources after our test
354 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
355 const pool
= new FixedThreadPool(
357 './tests/worker-files/thread/testWorker.js',
358 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
360 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
361 const promises
= new Set()
362 const maxMultiplier
= 2
363 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
364 promises
.add(pool
.execute())
366 await Promise
.all(promises
)
367 for (const workerNode
of pool
.workerNodes
) {
368 expect(workerNode
.workerUsage
).toStrictEqual({
370 executed
: maxMultiplier
,
379 history
: expect
.any(CircularArray
)
385 history
: expect
.any(CircularArray
)
390 // We need to clean up the resources after our test
394 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
395 const pool
= new DynamicThreadPool(
398 './tests/worker-files/thread/testWorker.js',
399 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
401 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
402 const promises
= new Set()
403 const maxMultiplier
= 2
404 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
405 promises
.add(pool
.execute())
407 await Promise
.all(promises
)
408 for (const workerNode
of pool
.workerNodes
) {
409 expect(workerNode
.workerUsage
).toStrictEqual({
411 executed
: maxMultiplier
,
420 history
: expect
.any(CircularArray
)
426 history
: expect
.any(CircularArray
)
432 // We need to clean up the resources after our test
436 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
437 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
438 let pool
= new FixedThreadPool(
440 './tests/worker-files/thread/testWorker.js',
441 { workerChoiceStrategy
}
444 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
455 pool
= new DynamicThreadPool(
458 './tests/worker-files/thread/testWorker.js',
459 { workerChoiceStrategy
}
462 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
472 // We need to clean up the resources after our test
476 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
477 const pool
= new FixedThreadPool(
479 './tests/worker-files/thread/testWorker.js',
480 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
482 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
483 const promises
= new Set()
484 const maxMultiplier
= 2
485 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
486 promises
.add(pool
.execute())
488 await Promise
.all(promises
)
489 for (const workerNode
of pool
.workerNodes
) {
490 expect(workerNode
.workerUsage
).toStrictEqual({
492 executed
: expect
.any(Number
),
498 aggregation
: expect
.any(Number
),
501 history
: expect
.any(CircularArray
)
504 aggregation
: expect
.any(Number
),
507 history
: expect
.any(CircularArray
)
511 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
512 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
515 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
519 workerNode
.workerUsage
.waitTime
.aggregation
520 ).toBeGreaterThanOrEqual(0)
522 // We need to clean up the resources after our test
526 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
527 const pool
= new DynamicThreadPool(
530 './tests/worker-files/thread/testWorker.js',
531 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
533 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
534 const promises
= new Set()
535 const maxMultiplier
= 2
536 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
537 promises
.add(pool
.execute())
539 await Promise
.all(promises
)
540 for (const workerNode
of pool
.workerNodes
) {
541 expect(workerNode
.workerUsage
).toStrictEqual({
543 executed
: expect
.any(Number
),
549 aggregation
: expect
.any(Number
),
552 history
: expect
.any(CircularArray
)
555 aggregation
: expect
.any(Number
),
558 history
: expect
.any(CircularArray
)
562 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
563 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
566 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
567 expect(workerNode
.workerUsage
.waitTime
.aggregation
).toBeGreaterThan(0)
569 // We need to clean up the resources after our test
573 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
574 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
575 let pool
= new FixedThreadPool(
577 './tests/worker-files/thread/testWorker.js',
578 { workerChoiceStrategy
}
581 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
592 pool
= new DynamicThreadPool(
595 './tests/worker-files/thread/testWorker.js',
596 { workerChoiceStrategy
}
599 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
609 // We need to clean up the resources after our test
613 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
614 const pool
= new FixedThreadPool(
616 './tests/worker-files/thread/testWorker.js',
617 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
619 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
620 const promises
= new Set()
621 const maxMultiplier
= 2
622 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
623 promises
.add(pool
.execute())
625 await Promise
.all(promises
)
626 for (const workerNode
of pool
.workerNodes
) {
627 expect(workerNode
.workerUsage
).toStrictEqual({
629 executed
: maxMultiplier
,
635 aggregation
: expect
.any(Number
),
636 average
: expect
.any(Number
),
638 history
: expect
.any(CircularArray
)
644 history
: expect
.any(CircularArray
)
648 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
649 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
652 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
653 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
654 ).workersVirtualTaskEndTimestamp
.length
655 ).toBe(pool
.workerNodes
.length
)
656 // We need to clean up the resources after our test
660 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
661 const pool
= new DynamicThreadPool(
664 './tests/worker-files/thread/testWorker.js',
665 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
667 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
668 const promises
= new Set()
669 const maxMultiplier
= 2
670 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
671 promises
.add(pool
.execute())
673 await Promise
.all(promises
)
674 for (const workerNode
of pool
.workerNodes
) {
675 expect(workerNode
.workerUsage
).toStrictEqual({
677 executed
: maxMultiplier
,
683 aggregation
: expect
.any(Number
),
684 average
: expect
.any(Number
),
686 history
: expect
.any(CircularArray
)
692 history
: expect
.any(CircularArray
)
696 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
697 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
700 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
701 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
702 ).workersVirtualTaskEndTimestamp
.length
703 ).toBe(pool
.workerNodes
.length
)
704 // We need to clean up the resources after our test
708 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
709 const pool
= new DynamicThreadPool(
712 './tests/worker-files/thread/testWorker.js',
714 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
715 workerChoiceStrategyOptions
: {
720 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
721 const promises
= new Set()
722 const maxMultiplier
= 2
723 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
724 promises
.add(pool
.execute())
726 await Promise
.all(promises
)
727 for (const workerNode
of pool
.workerNodes
) {
728 expect(workerNode
.workerUsage
).toStrictEqual({
730 executed
: maxMultiplier
,
736 aggregation
: expect
.any(Number
),
738 median
: expect
.any(Number
),
739 history
: expect
.any(CircularArray
)
745 history
: expect
.any(CircularArray
)
749 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
750 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
753 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
754 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
755 ).workersVirtualTaskEndTimestamp
.length
756 ).toBe(pool
.workerNodes
.length
)
757 // We need to clean up the resources after our test
761 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
762 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
763 let pool
= new FixedThreadPool(
765 './tests/worker-files/thread/testWorker.js'
768 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
770 ).workersVirtualTaskEndTimestamp
771 ).toBeInstanceOf(Array
)
773 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
775 ).workersVirtualTaskEndTimestamp
.length
777 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
779 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
781 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
783 ).workersVirtualTaskEndTimestamp
.length
785 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
787 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
789 ).workersVirtualTaskEndTimestamp
790 ).toBeInstanceOf(Array
)
792 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
794 ).workersVirtualTaskEndTimestamp
.length
797 pool
= new DynamicThreadPool(
800 './tests/worker-files/thread/testWorker.js'
803 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
805 ).workersVirtualTaskEndTimestamp
806 ).toBeInstanceOf(Array
)
808 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
810 ).workersVirtualTaskEndTimestamp
.length
812 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
814 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
816 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
818 ).workersVirtualTaskEndTimestamp
.length
820 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
822 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
824 ).workersVirtualTaskEndTimestamp
825 ).toBeInstanceOf(Array
)
827 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
829 ).workersVirtualTaskEndTimestamp
.length
831 // We need to clean up the resources after our test
835 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
836 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
837 let pool
= new FixedThreadPool(
839 './tests/worker-files/thread/testWorker.js',
840 { workerChoiceStrategy
}
843 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
854 pool
= new DynamicThreadPool(
857 './tests/worker-files/thread/testWorker.js',
858 { workerChoiceStrategy
}
861 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
871 // We need to clean up the resources after our test
875 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
876 const pool
= new FixedThreadPool(
878 './tests/worker-files/thread/testWorker.js',
879 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
881 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
882 const promises
= new Set()
883 const maxMultiplier
= 2
884 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
885 promises
.add(pool
.execute())
887 await Promise
.all(promises
)
888 for (const workerNode
of pool
.workerNodes
) {
889 expect(workerNode
.workerUsage
).toStrictEqual({
891 executed
: expect
.any(Number
),
897 aggregation
: expect
.any(Number
),
898 average
: expect
.any(Number
),
900 history
: expect
.any(CircularArray
)
906 history
: expect
.any(CircularArray
)
910 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
911 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
914 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
917 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
920 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
921 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
922 ).defaultWorkerWeight
925 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
926 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
927 ).workerVirtualTaskRunTime
928 ).toBeGreaterThanOrEqual(0)
929 // We need to clean up the resources after our test
933 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
934 const pool
= new DynamicThreadPool(
937 './tests/worker-files/thread/testWorker.js',
938 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
940 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
941 const promises
= new Set()
942 const maxMultiplier
= 2
943 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
944 promises
.add(pool
.execute())
946 await Promise
.all(promises
)
947 for (const workerNode
of pool
.workerNodes
) {
948 expect(workerNode
.workerUsage
).toStrictEqual({
950 executed
: expect
.any(Number
),
956 aggregation
: expect
.any(Number
),
957 average
: expect
.any(Number
),
959 history
: expect
.any(CircularArray
)
965 history
: expect
.any(CircularArray
)
969 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
970 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
973 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
974 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
977 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
978 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
979 ).defaultWorkerWeight
982 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
983 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
984 ).workerVirtualTaskRunTime
985 ).toBeGreaterThanOrEqual(0)
986 // We need to clean up the resources after our test
990 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
991 const pool
= new DynamicThreadPool(
994 './tests/worker-files/thread/testWorker.js',
996 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
997 workerChoiceStrategyOptions
: {
1002 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1003 const promises
= new Set()
1004 const maxMultiplier
= 2
1005 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1006 promises
.add(pool
.execute())
1008 await Promise
.all(promises
)
1009 for (const workerNode
of pool
.workerNodes
) {
1010 expect(workerNode
.workerUsage
).toStrictEqual({
1012 executed
: expect
.any(Number
),
1018 aggregation
: expect
.any(Number
),
1020 median
: expect
.any(Number
),
1021 history
: expect
.any(CircularArray
)
1027 history
: expect
.any(CircularArray
)
1031 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1032 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1035 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1036 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1039 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1040 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1041 ).defaultWorkerWeight
1042 ).toBeGreaterThan(0)
1044 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1045 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1046 ).workerVirtualTaskRunTime
1047 ).toBeGreaterThanOrEqual(0)
1048 // We need to clean up the resources after our test
1049 await pool
.destroy()
1052 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1053 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1054 let pool
= new FixedThreadPool(
1056 './tests/worker-files/thread/testWorker.js'
1059 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1060 workerChoiceStrategy
1061 ).currentWorkerNodeId
1064 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1065 workerChoiceStrategy
1066 ).defaultWorkerWeight
1069 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1070 workerChoiceStrategy
1071 ).workerVirtualTaskRunTime
1073 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1075 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1076 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1077 ).currentWorkerNodeId
1080 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1081 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1082 ).defaultWorkerWeight
1083 ).toBeGreaterThan(0)
1085 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1086 workerChoiceStrategy
1087 ).workerVirtualTaskRunTime
1089 await pool
.destroy()
1090 pool
= new DynamicThreadPool(
1093 './tests/worker-files/thread/testWorker.js'
1096 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1097 workerChoiceStrategy
1098 ).currentWorkerNodeId
1101 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1102 workerChoiceStrategy
1103 ).defaultWorkerWeight
1106 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1107 workerChoiceStrategy
1108 ).workerVirtualTaskRunTime
1110 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1112 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1113 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1114 ).currentWorkerNodeId
1117 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1118 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1119 ).defaultWorkerWeight
1120 ).toBeGreaterThan(0)
1122 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1123 workerChoiceStrategy
1124 ).workerVirtualTaskRunTime
1126 // We need to clean up the resources after our test
1127 await pool
.destroy()
1130 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1131 const workerChoiceStrategy
=
1132 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1133 let pool
= new FixedThreadPool(
1135 './tests/worker-files/thread/testWorker.js',
1136 { workerChoiceStrategy
}
1139 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1149 await pool
.destroy()
1150 pool
= new DynamicThreadPool(
1153 './tests/worker-files/thread/testWorker.js',
1154 { workerChoiceStrategy
}
1157 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1167 // We need to clean up the resources after our test
1168 await pool
.destroy()
1171 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1172 const pool
= new FixedThreadPool(
1174 './tests/worker-files/thread/testWorker.js',
1176 workerChoiceStrategy
:
1177 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1180 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1181 const promises
= new Set()
1182 const maxMultiplier
= 2
1183 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1184 promises
.add(pool
.execute())
1186 await Promise
.all(promises
)
1187 for (const workerNode
of pool
.workerNodes
) {
1188 expect(workerNode
.workerUsage
).toStrictEqual({
1190 executed
: maxMultiplier
,
1199 history
: expect
.any(CircularArray
)
1205 history
: expect
.any(CircularArray
)
1211 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1212 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1213 ).defaultWorkerWeight
1214 ).toBeGreaterThan(0)
1216 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1217 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1221 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1222 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1223 ).currentWorkerNodeId
1226 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1227 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1230 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1231 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1232 ).defaultWorkerWeight
1234 // We need to clean up the resources after our test
1235 await pool
.destroy()
1238 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1239 const pool
= new DynamicThreadPool(
1242 './tests/worker-files/thread/testWorker.js',
1244 workerChoiceStrategy
:
1245 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1248 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1249 const promises
= new Set()
1250 const maxMultiplier
= 2
1251 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1252 promises
.add(pool
.execute())
1254 await Promise
.all(promises
)
1255 for (const workerNode
of pool
.workerNodes
) {
1256 expect(workerNode
.workerUsage
).toStrictEqual({
1258 executed
: maxMultiplier
,
1267 history
: expect
.any(CircularArray
)
1273 history
: expect
.any(CircularArray
)
1279 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1280 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1281 ).defaultWorkerWeight
1282 ).toBeGreaterThan(0)
1284 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1285 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1289 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1290 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1291 ).currentWorkerNodeId
1294 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1295 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1298 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1299 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1300 ).defaultWorkerWeight
1302 // We need to clean up the resources after our test
1303 await pool
.destroy()
1306 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1307 const workerChoiceStrategy
=
1308 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1309 let pool
= new FixedThreadPool(
1311 './tests/worker-files/thread/testWorker.js'
1314 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1315 workerChoiceStrategy
1319 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1320 workerChoiceStrategy
1321 ).currentWorkerNodeId
1324 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1325 workerChoiceStrategy
1326 ).defaultWorkerWeight
1329 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1330 workerChoiceStrategy
1333 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1335 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1336 workerChoiceStrategy
1340 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1341 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1342 ).currentWorkerNodeId
1345 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1346 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1347 ).defaultWorkerWeight
1348 ).toBeGreaterThan(0)
1350 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1351 workerChoiceStrategy
1354 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1355 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1356 ).defaultWorkerWeight
1358 await pool
.destroy()
1359 pool
= new DynamicThreadPool(
1362 './tests/worker-files/thread/testWorker.js'
1365 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1366 workerChoiceStrategy
1370 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1371 workerChoiceStrategy
1372 ).currentWorkerNodeId
1375 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1376 workerChoiceStrategy
1377 ).defaultWorkerWeight
1380 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1381 workerChoiceStrategy
1384 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1386 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1387 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1388 ).currentWorkerNodeId
1391 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1392 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1393 ).defaultWorkerWeight
1394 ).toBeGreaterThan(0)
1396 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1397 workerChoiceStrategy
1400 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1401 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1402 ).defaultWorkerWeight
1404 // We need to clean up the resources after our test
1405 await pool
.destroy()
1408 it('Verify unknown strategy throw error', () => {
1411 new DynamicThreadPool(
1414 './tests/worker-files/thread/testWorker.js',
1415 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1417 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")