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
.LEAST_ELU
).toBe('LEAST_ELU')
19 expect(WorkerChoiceStrategies
.FAIR_SHARE
).toBe('FAIR_SHARE')
20 expect(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
).toBe(
21 'WEIGHTED_ROUND_ROBIN'
23 expect(WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
).toBe(
24 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'
28 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
29 const pool
= new DynamicThreadPool(
32 './tests/worker-files/thread/testWorker.js'
34 expect(pool
.opts
.workerChoiceStrategy
).toBe(
35 WorkerChoiceStrategies
.ROUND_ROBIN
37 // We need to clean up the resources after our test
41 it('Verify available strategies are taken at pool creation', async () => {
42 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
43 const pool
= new FixedThreadPool(
45 './tests/worker-files/thread/testWorker.js',
46 { workerChoiceStrategy
}
48 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
49 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
56 it('Verify available strategies can be set after pool creation', async () => {
57 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
58 const pool
= new DynamicThreadPool(
61 './tests/worker-files/thread/testWorker.js'
63 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
64 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
65 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
72 it('Verify available strategies default internals at pool creation', async () => {
73 const pool
= new FixedThreadPool(
75 './tests/worker-files/thread/testWorker.js'
77 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
78 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.ROUND_ROBIN
) {
80 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
84 } else if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
86 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
88 ).workersVirtualTaskEndTimestamp
89 ).toBeInstanceOf(Array
)
91 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
93 ).workersVirtualTaskEndTimestamp
.length
96 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
99 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
101 ).currentWorkerNodeId
104 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
106 ).defaultWorkerWeight
109 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
111 ).workerVirtualTaskRunTime
118 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
119 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
120 let pool
= new FixedThreadPool(
122 './tests/worker-files/thread/testWorker.js',
123 { workerChoiceStrategy
}
126 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
137 pool
= new DynamicThreadPool(
140 './tests/worker-files/thread/testWorker.js',
141 { workerChoiceStrategy
}
144 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
154 // We need to clean up the resources after our test
158 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
159 const pool
= new FixedThreadPool(
161 './tests/worker-files/thread/testWorker.js',
162 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
164 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
165 const promises
= new Set()
166 const maxMultiplier
= 2
167 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
168 promises
.add(pool
.execute())
170 await Promise
.all(promises
)
171 for (const workerNode
of pool
.workerNodes
) {
172 expect(workerNode
.workerUsage
).toStrictEqual({
174 executed
: maxMultiplier
,
183 history
: expect
.any(CircularArray
)
189 history
: expect
.any(CircularArray
)
195 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
196 WorkerChoiceStrategies
.ROUND_ROBIN
199 // We need to clean up the resources after our test
203 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
204 const pool
= new DynamicThreadPool(
207 './tests/worker-files/thread/testWorker.js',
208 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
210 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
211 const promises
= new Set()
212 const maxMultiplier
= 2
213 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
214 promises
.add(pool
.execute())
216 await Promise
.all(promises
)
217 for (const workerNode
of pool
.workerNodes
) {
218 expect(workerNode
.workerUsage
).toStrictEqual({
220 executed
: maxMultiplier
,
229 history
: expect
.any(CircularArray
)
235 history
: expect
.any(CircularArray
)
241 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
242 WorkerChoiceStrategies
.ROUND_ROBIN
245 // We need to clean up the resources after our test
249 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
250 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
251 let pool
= new FixedClusterPool(
253 './tests/worker-files/cluster/testWorker.js',
254 { workerChoiceStrategy
}
256 let results
= new Set()
257 for (let i
= 0; i
< max
; i
++) {
258 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
260 expect(results
.size
).toBe(max
)
262 pool
= new FixedThreadPool(
264 './tests/worker-files/thread/testWorker.js',
265 { workerChoiceStrategy
}
268 for (let i
= 0; i
< max
; i
++) {
269 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
271 expect(results
.size
).toBe(max
)
275 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
276 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
277 let pool
= new FixedThreadPool(
279 './tests/worker-files/thread/testWorker.js',
280 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
283 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
287 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
289 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
290 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
294 pool
= new DynamicThreadPool(
297 './tests/worker-files/thread/testWorker.js',
298 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
301 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
305 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
307 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
308 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
311 // We need to clean up the resources after our test
315 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
316 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
317 let pool
= new FixedThreadPool(
319 './tests/worker-files/thread/testWorker.js',
320 { workerChoiceStrategy
}
323 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
334 pool
= new DynamicThreadPool(
337 './tests/worker-files/thread/testWorker.js',
338 { workerChoiceStrategy
}
341 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
351 // We need to clean up the resources after our test
355 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
356 const pool
= new FixedThreadPool(
358 './tests/worker-files/thread/testWorker.js',
359 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
361 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
362 const promises
= new Set()
363 const maxMultiplier
= 2
364 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
365 promises
.add(pool
.execute())
367 await Promise
.all(promises
)
368 for (const workerNode
of pool
.workerNodes
) {
369 expect(workerNode
.workerUsage
).toStrictEqual({
371 executed
: maxMultiplier
,
380 history
: expect
.any(CircularArray
)
386 history
: expect
.any(CircularArray
)
391 // We need to clean up the resources after our test
395 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
396 const pool
= new DynamicThreadPool(
399 './tests/worker-files/thread/testWorker.js',
400 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
402 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
403 const promises
= new Set()
404 const maxMultiplier
= 2
405 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
406 promises
.add(pool
.execute())
408 await Promise
.all(promises
)
409 for (const workerNode
of pool
.workerNodes
) {
410 expect(workerNode
.workerUsage
).toStrictEqual({
412 executed
: maxMultiplier
,
421 history
: expect
.any(CircularArray
)
427 history
: expect
.any(CircularArray
)
433 // We need to clean up the resources after our test
437 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
438 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
439 let pool
= new FixedThreadPool(
441 './tests/worker-files/thread/testWorker.js',
442 { workerChoiceStrategy
}
445 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
456 pool
= new DynamicThreadPool(
459 './tests/worker-files/thread/testWorker.js',
460 { workerChoiceStrategy
}
463 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
473 // We need to clean up the resources after our test
477 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
478 const pool
= new FixedThreadPool(
480 './tests/worker-files/thread/testWorker.js',
481 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
483 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
484 const promises
= new Set()
485 const maxMultiplier
= 2
486 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
487 promises
.add(pool
.execute())
489 await Promise
.all(promises
)
490 for (const workerNode
of pool
.workerNodes
) {
491 expect(workerNode
.workerUsage
).toStrictEqual({
493 executed
: expect
.any(Number
),
499 aggregation
: expect
.any(Number
),
502 history
: expect
.any(CircularArray
)
505 aggregation
: expect
.any(Number
),
508 history
: expect
.any(CircularArray
)
512 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
513 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
516 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
520 workerNode
.workerUsage
.waitTime
.aggregation
521 ).toBeGreaterThanOrEqual(0)
523 // We need to clean up the resources after our test
527 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
528 const pool
= new DynamicThreadPool(
531 './tests/worker-files/thread/testWorker.js',
532 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
534 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
535 const promises
= new Set()
536 const maxMultiplier
= 2
537 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
538 promises
.add(pool
.execute())
540 await Promise
.all(promises
)
541 for (const workerNode
of pool
.workerNodes
) {
542 expect(workerNode
.workerUsage
).toStrictEqual({
544 executed
: expect
.any(Number
),
550 aggregation
: expect
.any(Number
),
553 history
: expect
.any(CircularArray
)
556 aggregation
: expect
.any(Number
),
559 history
: expect
.any(CircularArray
)
563 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
564 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
567 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
568 expect(workerNode
.workerUsage
.waitTime
.aggregation
).toBeGreaterThan(0)
570 // We need to clean up the resources after our test
574 it('Verify LEAST_ELU strategy default tasks usage statistics requirements', async () => {
575 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
576 let pool
= new FixedThreadPool(
578 './tests/worker-files/thread/testWorker.js',
579 { workerChoiceStrategy
}
582 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
593 pool
= new DynamicThreadPool(
596 './tests/worker-files/thread/testWorker.js',
597 { workerChoiceStrategy
}
600 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
610 // We need to clean up the resources after our test
614 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
615 const pool
= new FixedThreadPool(
617 './tests/worker-files/thread/testWorker.js',
618 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
620 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
621 const promises
= new Set()
622 const maxMultiplier
= 2
623 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
624 promises
.add(pool
.execute())
626 await Promise
.all(promises
)
627 for (const workerNode
of pool
.workerNodes
) {
628 const expectedWorkerUsage
= {
630 executed
: expect
.any(Number
),
639 history
: expect
.any(CircularArray
)
645 history
: expect
.any(CircularArray
)
648 if (workerNode
.workerUsage
.elu
=== undefined) {
649 expect(workerNode
.workerUsage
).toStrictEqual({
650 ...expectedWorkerUsage
,
654 expect(workerNode
.workerUsage
).toStrictEqual({
655 ...expectedWorkerUsage
,
657 active
: expect
.any(Number
),
663 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
664 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
668 // We need to clean up the resources after our test
672 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
673 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
674 let pool
= new FixedThreadPool(
676 './tests/worker-files/thread/testWorker.js',
677 { workerChoiceStrategy
}
680 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
691 pool
= new DynamicThreadPool(
694 './tests/worker-files/thread/testWorker.js',
695 { workerChoiceStrategy
}
698 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
708 // We need to clean up the resources after our test
712 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
713 const pool
= new FixedThreadPool(
715 './tests/worker-files/thread/testWorker.js',
716 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
718 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
719 const promises
= new Set()
720 const maxMultiplier
= 2
721 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
722 promises
.add(pool
.execute())
724 await Promise
.all(promises
)
725 for (const workerNode
of pool
.workerNodes
) {
726 expect(workerNode
.workerUsage
).toStrictEqual({
728 executed
: maxMultiplier
,
734 aggregation
: expect
.any(Number
),
735 average
: expect
.any(Number
),
737 history
: expect
.any(CircularArray
)
743 history
: expect
.any(CircularArray
)
747 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
748 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
751 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
752 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
753 ).workersVirtualTaskEndTimestamp
.length
754 ).toBe(pool
.workerNodes
.length
)
755 // We need to clean up the resources after our test
759 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
760 const pool
= new DynamicThreadPool(
763 './tests/worker-files/thread/testWorker.js',
764 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
766 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
767 const promises
= new Set()
768 const maxMultiplier
= 2
769 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
770 promises
.add(pool
.execute())
772 await Promise
.all(promises
)
773 for (const workerNode
of pool
.workerNodes
) {
774 expect(workerNode
.workerUsage
).toStrictEqual({
776 executed
: maxMultiplier
,
782 aggregation
: expect
.any(Number
),
783 average
: expect
.any(Number
),
785 history
: expect
.any(CircularArray
)
791 history
: expect
.any(CircularArray
)
795 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
796 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
799 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
800 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
801 ).workersVirtualTaskEndTimestamp
.length
802 ).toBe(pool
.workerNodes
.length
)
803 // We need to clean up the resources after our test
807 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
808 const pool
= new DynamicThreadPool(
811 './tests/worker-files/thread/testWorker.js',
813 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
814 workerChoiceStrategyOptions
: {
819 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
820 const promises
= new Set()
821 const maxMultiplier
= 2
822 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
823 promises
.add(pool
.execute())
825 await Promise
.all(promises
)
826 for (const workerNode
of pool
.workerNodes
) {
827 expect(workerNode
.workerUsage
).toStrictEqual({
829 executed
: maxMultiplier
,
835 aggregation
: expect
.any(Number
),
837 median
: expect
.any(Number
),
838 history
: expect
.any(CircularArray
)
844 history
: expect
.any(CircularArray
)
848 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
849 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
852 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
853 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
854 ).workersVirtualTaskEndTimestamp
.length
855 ).toBe(pool
.workerNodes
.length
)
856 // We need to clean up the resources after our test
860 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
861 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
862 let pool
= new FixedThreadPool(
864 './tests/worker-files/thread/testWorker.js'
867 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
869 ).workersVirtualTaskEndTimestamp
870 ).toBeInstanceOf(Array
)
872 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
874 ).workersVirtualTaskEndTimestamp
.length
876 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
878 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
880 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
882 ).workersVirtualTaskEndTimestamp
.length
884 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
886 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
888 ).workersVirtualTaskEndTimestamp
889 ).toBeInstanceOf(Array
)
891 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
893 ).workersVirtualTaskEndTimestamp
.length
896 pool
= new DynamicThreadPool(
899 './tests/worker-files/thread/testWorker.js'
902 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
904 ).workersVirtualTaskEndTimestamp
905 ).toBeInstanceOf(Array
)
907 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
909 ).workersVirtualTaskEndTimestamp
.length
911 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
913 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
915 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
917 ).workersVirtualTaskEndTimestamp
.length
919 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
921 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
923 ).workersVirtualTaskEndTimestamp
924 ).toBeInstanceOf(Array
)
926 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
928 ).workersVirtualTaskEndTimestamp
.length
930 // We need to clean up the resources after our test
934 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
935 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
936 let pool
= new FixedThreadPool(
938 './tests/worker-files/thread/testWorker.js',
939 { workerChoiceStrategy
}
942 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
953 pool
= new DynamicThreadPool(
956 './tests/worker-files/thread/testWorker.js',
957 { workerChoiceStrategy
}
960 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
970 // We need to clean up the resources after our test
974 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
975 const pool
= new FixedThreadPool(
977 './tests/worker-files/thread/testWorker.js',
978 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
980 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
981 const promises
= new Set()
982 const maxMultiplier
= 2
983 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
984 promises
.add(pool
.execute())
986 await Promise
.all(promises
)
987 for (const workerNode
of pool
.workerNodes
) {
988 expect(workerNode
.workerUsage
).toStrictEqual({
990 executed
: expect
.any(Number
),
996 aggregation
: expect
.any(Number
),
997 average
: expect
.any(Number
),
999 history
: expect
.any(CircularArray
)
1005 history
: expect
.any(CircularArray
)
1009 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1010 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1013 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
1016 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
1019 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1020 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1021 ).defaultWorkerWeight
1022 ).toBeGreaterThan(0)
1024 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1025 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1026 ).workerVirtualTaskRunTime
1027 ).toBeGreaterThanOrEqual(0)
1028 // We need to clean up the resources after our test
1029 await pool
.destroy()
1032 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1033 const pool
= new DynamicThreadPool(
1036 './tests/worker-files/thread/testWorker.js',
1037 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1039 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1040 const promises
= new Set()
1041 const maxMultiplier
= 2
1042 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1043 promises
.add(pool
.execute())
1045 await Promise
.all(promises
)
1046 for (const workerNode
of pool
.workerNodes
) {
1047 expect(workerNode
.workerUsage
).toStrictEqual({
1049 executed
: expect
.any(Number
),
1055 aggregation
: expect
.any(Number
),
1056 average
: expect
.any(Number
),
1058 history
: expect
.any(CircularArray
)
1064 history
: expect
.any(CircularArray
)
1068 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1069 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1072 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1073 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1076 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1077 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1078 ).defaultWorkerWeight
1079 ).toBeGreaterThan(0)
1081 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1082 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1083 ).workerVirtualTaskRunTime
1084 ).toBeGreaterThanOrEqual(0)
1085 // We need to clean up the resources after our test
1086 await pool
.destroy()
1089 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1090 const pool
= new DynamicThreadPool(
1093 './tests/worker-files/thread/testWorker.js',
1095 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1096 workerChoiceStrategyOptions
: {
1101 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1102 const promises
= new Set()
1103 const maxMultiplier
= 2
1104 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1105 promises
.add(pool
.execute())
1107 await Promise
.all(promises
)
1108 for (const workerNode
of pool
.workerNodes
) {
1109 expect(workerNode
.workerUsage
).toStrictEqual({
1111 executed
: expect
.any(Number
),
1117 aggregation
: expect
.any(Number
),
1119 median
: expect
.any(Number
),
1120 history
: expect
.any(CircularArray
)
1126 history
: expect
.any(CircularArray
)
1130 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1131 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1134 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1135 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1138 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1139 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1140 ).defaultWorkerWeight
1141 ).toBeGreaterThan(0)
1143 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1144 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1145 ).workerVirtualTaskRunTime
1146 ).toBeGreaterThanOrEqual(0)
1147 // We need to clean up the resources after our test
1148 await pool
.destroy()
1151 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1152 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1153 let pool
= new FixedThreadPool(
1155 './tests/worker-files/thread/testWorker.js'
1158 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1159 workerChoiceStrategy
1160 ).currentWorkerNodeId
1163 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1164 workerChoiceStrategy
1165 ).defaultWorkerWeight
1168 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1169 workerChoiceStrategy
1170 ).workerVirtualTaskRunTime
1172 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1174 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1175 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1176 ).currentWorkerNodeId
1179 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1180 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1181 ).defaultWorkerWeight
1182 ).toBeGreaterThan(0)
1184 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1185 workerChoiceStrategy
1186 ).workerVirtualTaskRunTime
1188 await pool
.destroy()
1189 pool
= new DynamicThreadPool(
1192 './tests/worker-files/thread/testWorker.js'
1195 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1196 workerChoiceStrategy
1197 ).currentWorkerNodeId
1200 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1201 workerChoiceStrategy
1202 ).defaultWorkerWeight
1205 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1206 workerChoiceStrategy
1207 ).workerVirtualTaskRunTime
1209 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1211 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1212 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1213 ).currentWorkerNodeId
1216 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1217 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1218 ).defaultWorkerWeight
1219 ).toBeGreaterThan(0)
1221 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1222 workerChoiceStrategy
1223 ).workerVirtualTaskRunTime
1225 // We need to clean up the resources after our test
1226 await pool
.destroy()
1229 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1230 const workerChoiceStrategy
=
1231 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1232 let pool
= new FixedThreadPool(
1234 './tests/worker-files/thread/testWorker.js',
1235 { workerChoiceStrategy
}
1238 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1248 await pool
.destroy()
1249 pool
= new DynamicThreadPool(
1252 './tests/worker-files/thread/testWorker.js',
1253 { workerChoiceStrategy
}
1256 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1266 // We need to clean up the resources after our test
1267 await pool
.destroy()
1270 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1271 const pool
= new FixedThreadPool(
1273 './tests/worker-files/thread/testWorker.js',
1275 workerChoiceStrategy
:
1276 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1279 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1280 const promises
= new Set()
1281 const maxMultiplier
= 2
1282 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1283 promises
.add(pool
.execute())
1285 await Promise
.all(promises
)
1286 for (const workerNode
of pool
.workerNodes
) {
1287 expect(workerNode
.workerUsage
).toStrictEqual({
1289 executed
: maxMultiplier
,
1298 history
: expect
.any(CircularArray
)
1304 history
: expect
.any(CircularArray
)
1310 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1311 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1312 ).defaultWorkerWeight
1313 ).toBeGreaterThan(0)
1315 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1316 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1320 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1321 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1322 ).currentWorkerNodeId
1325 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1326 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1329 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1330 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1331 ).defaultWorkerWeight
1333 // We need to clean up the resources after our test
1334 await pool
.destroy()
1337 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1338 const pool
= new DynamicThreadPool(
1341 './tests/worker-files/thread/testWorker.js',
1343 workerChoiceStrategy
:
1344 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1347 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1348 const promises
= new Set()
1349 const maxMultiplier
= 2
1350 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1351 promises
.add(pool
.execute())
1353 await Promise
.all(promises
)
1354 for (const workerNode
of pool
.workerNodes
) {
1355 expect(workerNode
.workerUsage
).toStrictEqual({
1357 executed
: maxMultiplier
,
1366 history
: expect
.any(CircularArray
)
1372 history
: expect
.any(CircularArray
)
1378 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1379 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1380 ).defaultWorkerWeight
1381 ).toBeGreaterThan(0)
1383 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1384 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1388 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1389 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1390 ).currentWorkerNodeId
1393 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1394 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1397 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1398 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1399 ).defaultWorkerWeight
1401 // We need to clean up the resources after our test
1402 await pool
.destroy()
1405 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1406 const workerChoiceStrategy
=
1407 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1408 let pool
= new FixedThreadPool(
1410 './tests/worker-files/thread/testWorker.js'
1413 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1414 workerChoiceStrategy
1418 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1419 workerChoiceStrategy
1420 ).currentWorkerNodeId
1423 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1424 workerChoiceStrategy
1425 ).defaultWorkerWeight
1428 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1429 workerChoiceStrategy
1432 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1434 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1435 workerChoiceStrategy
1439 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1440 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1441 ).currentWorkerNodeId
1444 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1445 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1446 ).defaultWorkerWeight
1447 ).toBeGreaterThan(0)
1449 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1450 workerChoiceStrategy
1453 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1454 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1455 ).defaultWorkerWeight
1457 await pool
.destroy()
1458 pool
= new DynamicThreadPool(
1461 './tests/worker-files/thread/testWorker.js'
1464 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1465 workerChoiceStrategy
1469 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1470 workerChoiceStrategy
1471 ).currentWorkerNodeId
1474 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1475 workerChoiceStrategy
1476 ).defaultWorkerWeight
1479 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1480 workerChoiceStrategy
1483 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1485 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1486 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1487 ).currentWorkerNodeId
1490 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1491 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1492 ).defaultWorkerWeight
1493 ).toBeGreaterThan(0)
1495 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1496 workerChoiceStrategy
1499 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1500 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1501 ).defaultWorkerWeight
1503 // We need to clean up the resources after our test
1504 await pool
.destroy()
1507 it('Verify unknown strategy throw error', () => {
1510 new DynamicThreadPool(
1513 './tests/worker-files/thread/testWorker.js',
1514 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1516 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")