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_ELU
).toBe('LEAST_ELU')
18 expect(WorkerChoiceStrategies
.LEAST_BUSY
).toBe('LEAST_BUSY')
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
)
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 // We need to clean up the resources after our test
524 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
525 const pool
= new DynamicThreadPool(
528 './tests/worker-files/thread/testWorker.js',
529 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
531 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
532 const promises
= new Set()
533 const maxMultiplier
= 2
534 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
535 promises
.add(pool
.execute())
537 await Promise
.all(promises
)
538 for (const workerNode
of pool
.workerNodes
) {
539 expect(workerNode
.workerUsage
).toStrictEqual({
541 executed
: expect
.any(Number
),
547 aggregation
: expect
.any(Number
),
550 history
: expect
.any(CircularArray
)
556 history
: expect
.any(CircularArray
)
560 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
561 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
564 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
566 // We need to clean up the resources after our test
570 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
571 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
572 let pool
= new FixedThreadPool(
574 './tests/worker-files/thread/testWorker.js',
575 { workerChoiceStrategy
}
578 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
589 pool
= new DynamicThreadPool(
592 './tests/worker-files/thread/testWorker.js',
593 { workerChoiceStrategy
}
596 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
606 // We need to clean up the resources after our test
610 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
611 const pool
= new FixedThreadPool(
613 './tests/worker-files/thread/testWorker.js',
614 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
616 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
617 const promises
= new Set()
618 const maxMultiplier
= 2
619 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
620 promises
.add(pool
.execute())
622 await Promise
.all(promises
)
623 for (const workerNode
of pool
.workerNodes
) {
624 expect(workerNode
.workerUsage
).toStrictEqual({
626 executed
: maxMultiplier
,
632 aggregation
: expect
.any(Number
),
633 average
: expect
.any(Number
),
635 history
: expect
.any(CircularArray
)
641 history
: expect
.any(CircularArray
)
645 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
646 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
649 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
650 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
651 ).workersVirtualTaskEndTimestamp
.length
652 ).toBe(pool
.workerNodes
.length
)
653 // We need to clean up the resources after our test
657 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
658 const pool
= new DynamicThreadPool(
661 './tests/worker-files/thread/testWorker.js',
662 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
664 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
665 const promises
= new Set()
666 const maxMultiplier
= 2
667 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
668 promises
.add(pool
.execute())
670 await Promise
.all(promises
)
671 for (const workerNode
of pool
.workerNodes
) {
672 expect(workerNode
.workerUsage
).toStrictEqual({
674 executed
: maxMultiplier
,
680 aggregation
: expect
.any(Number
),
681 average
: expect
.any(Number
),
683 history
: expect
.any(CircularArray
)
689 history
: expect
.any(CircularArray
)
693 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
694 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
697 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
698 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
699 ).workersVirtualTaskEndTimestamp
.length
700 ).toBe(pool
.workerNodes
.length
)
701 // We need to clean up the resources after our test
705 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
706 const pool
= new DynamicThreadPool(
709 './tests/worker-files/thread/testWorker.js',
711 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
712 workerChoiceStrategyOptions
: {
717 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
718 const promises
= new Set()
719 const maxMultiplier
= 2
720 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
721 promises
.add(pool
.execute())
723 await Promise
.all(promises
)
724 for (const workerNode
of pool
.workerNodes
) {
725 expect(workerNode
.workerUsage
).toStrictEqual({
727 executed
: maxMultiplier
,
733 aggregation
: expect
.any(Number
),
735 median
: expect
.any(Number
),
736 history
: expect
.any(CircularArray
)
742 history
: expect
.any(CircularArray
)
746 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
747 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
750 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
751 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
752 ).workersVirtualTaskEndTimestamp
.length
753 ).toBe(pool
.workerNodes
.length
)
754 // We need to clean up the resources after our test
758 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
759 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
760 let pool
= new FixedThreadPool(
762 './tests/worker-files/thread/testWorker.js'
765 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
767 ).workersVirtualTaskEndTimestamp
768 ).toBeInstanceOf(Array
)
770 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
772 ).workersVirtualTaskEndTimestamp
.length
774 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
776 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
778 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
780 ).workersVirtualTaskEndTimestamp
.length
782 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
784 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
786 ).workersVirtualTaskEndTimestamp
787 ).toBeInstanceOf(Array
)
789 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
791 ).workersVirtualTaskEndTimestamp
.length
794 pool
= new DynamicThreadPool(
797 './tests/worker-files/thread/testWorker.js'
800 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
802 ).workersVirtualTaskEndTimestamp
803 ).toBeInstanceOf(Array
)
805 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
807 ).workersVirtualTaskEndTimestamp
.length
809 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
811 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
813 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
815 ).workersVirtualTaskEndTimestamp
.length
817 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
819 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
821 ).workersVirtualTaskEndTimestamp
822 ).toBeInstanceOf(Array
)
824 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
826 ).workersVirtualTaskEndTimestamp
.length
828 // We need to clean up the resources after our test
832 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
833 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
834 let pool
= new FixedThreadPool(
836 './tests/worker-files/thread/testWorker.js',
837 { workerChoiceStrategy
}
840 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
851 pool
= new DynamicThreadPool(
854 './tests/worker-files/thread/testWorker.js',
855 { workerChoiceStrategy
}
858 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
868 // We need to clean up the resources after our test
872 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
873 const pool
= new FixedThreadPool(
875 './tests/worker-files/thread/testWorker.js',
876 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
878 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
879 const promises
= new Set()
880 const maxMultiplier
= 2
881 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
882 promises
.add(pool
.execute())
884 await Promise
.all(promises
)
885 for (const workerNode
of pool
.workerNodes
) {
886 expect(workerNode
.workerUsage
).toStrictEqual({
888 executed
: expect
.any(Number
),
894 aggregation
: expect
.any(Number
),
895 average
: expect
.any(Number
),
897 history
: expect
.any(CircularArray
)
903 history
: expect
.any(CircularArray
)
907 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
908 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
911 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
914 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
917 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
918 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
919 ).defaultWorkerWeight
922 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
923 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
924 ).workerVirtualTaskRunTime
925 ).toBeGreaterThanOrEqual(0)
926 // We need to clean up the resources after our test
930 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
931 const pool
= new DynamicThreadPool(
934 './tests/worker-files/thread/testWorker.js',
935 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
937 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
938 const promises
= new Set()
939 const maxMultiplier
= 2
940 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
941 promises
.add(pool
.execute())
943 await Promise
.all(promises
)
944 for (const workerNode
of pool
.workerNodes
) {
945 expect(workerNode
.workerUsage
).toStrictEqual({
947 executed
: expect
.any(Number
),
953 aggregation
: expect
.any(Number
),
954 average
: expect
.any(Number
),
956 history
: expect
.any(CircularArray
)
962 history
: expect
.any(CircularArray
)
966 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
967 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
970 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
971 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
974 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
975 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
976 ).defaultWorkerWeight
979 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
980 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
981 ).workerVirtualTaskRunTime
982 ).toBeGreaterThanOrEqual(0)
983 // We need to clean up the resources after our test
987 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
988 const pool
= new DynamicThreadPool(
991 './tests/worker-files/thread/testWorker.js',
993 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
994 workerChoiceStrategyOptions
: {
999 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1000 const promises
= new Set()
1001 const maxMultiplier
= 2
1002 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1003 promises
.add(pool
.execute())
1005 await Promise
.all(promises
)
1006 for (const workerNode
of pool
.workerNodes
) {
1007 expect(workerNode
.workerUsage
).toStrictEqual({
1009 executed
: expect
.any(Number
),
1015 aggregation
: expect
.any(Number
),
1017 median
: expect
.any(Number
),
1018 history
: expect
.any(CircularArray
)
1024 history
: expect
.any(CircularArray
)
1028 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1029 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1032 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1033 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1036 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1037 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1038 ).defaultWorkerWeight
1039 ).toBeGreaterThan(0)
1041 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1042 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1043 ).workerVirtualTaskRunTime
1044 ).toBeGreaterThanOrEqual(0)
1045 // We need to clean up the resources after our test
1046 await pool
.destroy()
1049 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1050 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1051 let pool
= new FixedThreadPool(
1053 './tests/worker-files/thread/testWorker.js'
1056 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1057 workerChoiceStrategy
1058 ).currentWorkerNodeId
1061 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1062 workerChoiceStrategy
1063 ).defaultWorkerWeight
1066 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1067 workerChoiceStrategy
1068 ).workerVirtualTaskRunTime
1070 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1072 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1073 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1074 ).currentWorkerNodeId
1077 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1078 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1079 ).defaultWorkerWeight
1080 ).toBeGreaterThan(0)
1082 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1083 workerChoiceStrategy
1084 ).workerVirtualTaskRunTime
1086 await pool
.destroy()
1087 pool
= new DynamicThreadPool(
1090 './tests/worker-files/thread/testWorker.js'
1093 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1094 workerChoiceStrategy
1095 ).currentWorkerNodeId
1098 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1099 workerChoiceStrategy
1100 ).defaultWorkerWeight
1103 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1104 workerChoiceStrategy
1105 ).workerVirtualTaskRunTime
1107 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1109 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1110 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1111 ).currentWorkerNodeId
1114 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1115 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1116 ).defaultWorkerWeight
1117 ).toBeGreaterThan(0)
1119 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1120 workerChoiceStrategy
1121 ).workerVirtualTaskRunTime
1123 // We need to clean up the resources after our test
1124 await pool
.destroy()
1127 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1128 const workerChoiceStrategy
=
1129 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1130 let pool
= new FixedThreadPool(
1132 './tests/worker-files/thread/testWorker.js',
1133 { workerChoiceStrategy
}
1136 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1146 await pool
.destroy()
1147 pool
= new DynamicThreadPool(
1150 './tests/worker-files/thread/testWorker.js',
1151 { workerChoiceStrategy
}
1154 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1164 // We need to clean up the resources after our test
1165 await pool
.destroy()
1168 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1169 const pool
= new FixedThreadPool(
1171 './tests/worker-files/thread/testWorker.js',
1173 workerChoiceStrategy
:
1174 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1177 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1178 const promises
= new Set()
1179 const maxMultiplier
= 2
1180 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1181 promises
.add(pool
.execute())
1183 await Promise
.all(promises
)
1184 for (const workerNode
of pool
.workerNodes
) {
1185 expect(workerNode
.workerUsage
).toStrictEqual({
1187 executed
: maxMultiplier
,
1196 history
: expect
.any(CircularArray
)
1202 history
: expect
.any(CircularArray
)
1208 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1209 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1210 ).defaultWorkerWeight
1211 ).toBeGreaterThan(0)
1213 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1214 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1218 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1219 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1220 ).currentWorkerNodeId
1223 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1224 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1227 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1228 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1229 ).defaultWorkerWeight
1231 // We need to clean up the resources after our test
1232 await pool
.destroy()
1235 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1236 const pool
= new DynamicThreadPool(
1239 './tests/worker-files/thread/testWorker.js',
1241 workerChoiceStrategy
:
1242 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1245 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1246 const promises
= new Set()
1247 const maxMultiplier
= 2
1248 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1249 promises
.add(pool
.execute())
1251 await Promise
.all(promises
)
1252 for (const workerNode
of pool
.workerNodes
) {
1253 expect(workerNode
.workerUsage
).toStrictEqual({
1255 executed
: maxMultiplier
,
1264 history
: expect
.any(CircularArray
)
1270 history
: expect
.any(CircularArray
)
1276 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1277 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1278 ).defaultWorkerWeight
1279 ).toBeGreaterThan(0)
1281 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1282 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1286 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1287 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1288 ).currentWorkerNodeId
1291 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1292 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1295 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1296 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1297 ).defaultWorkerWeight
1299 // We need to clean up the resources after our test
1300 await pool
.destroy()
1303 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1304 const workerChoiceStrategy
=
1305 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1306 let pool
= new FixedThreadPool(
1308 './tests/worker-files/thread/testWorker.js'
1311 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1312 workerChoiceStrategy
1316 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1317 workerChoiceStrategy
1318 ).currentWorkerNodeId
1321 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1322 workerChoiceStrategy
1323 ).defaultWorkerWeight
1326 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1327 workerChoiceStrategy
1330 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1332 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1333 workerChoiceStrategy
1337 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1338 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1339 ).currentWorkerNodeId
1342 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1343 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1344 ).defaultWorkerWeight
1345 ).toBeGreaterThan(0)
1347 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1348 workerChoiceStrategy
1351 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1352 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1353 ).defaultWorkerWeight
1355 await pool
.destroy()
1356 pool
= new DynamicThreadPool(
1359 './tests/worker-files/thread/testWorker.js'
1362 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1363 workerChoiceStrategy
1367 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1368 workerChoiceStrategy
1369 ).currentWorkerNodeId
1372 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1373 workerChoiceStrategy
1374 ).defaultWorkerWeight
1377 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1378 workerChoiceStrategy
1381 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1383 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1384 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1385 ).currentWorkerNodeId
1388 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1389 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1390 ).defaultWorkerWeight
1391 ).toBeGreaterThan(0)
1393 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1394 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 unknown strategy throw error', () => {
1408 new DynamicThreadPool(
1411 './tests/worker-files/thread/testWorker.js',
1412 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1414 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")