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
)
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 LEAST_ELU strategy default tasks usage statistics requirements', async () => {
571 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
572 let pool
= new FixedThreadPool(
574 './tests/worker-files/thread/testWorker.js',
575 { workerChoiceStrategy
}
577 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
587 pool
= new DynamicThreadPool(
590 './tests/worker-files/thread/testWorker.js',
591 { workerChoiceStrategy
}
593 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
602 // We need to clean up the resources after our test
606 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
607 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
608 let pool
= new FixedThreadPool(
610 './tests/worker-files/thread/testWorker.js',
611 { workerChoiceStrategy
}
614 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
625 pool
= new DynamicThreadPool(
628 './tests/worker-files/thread/testWorker.js',
629 { workerChoiceStrategy
}
632 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
642 // We need to clean up the resources after our test
646 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
647 const pool
= new FixedThreadPool(
649 './tests/worker-files/thread/testWorker.js',
650 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
652 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
653 const promises
= new Set()
654 const maxMultiplier
= 2
655 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
656 promises
.add(pool
.execute())
658 await Promise
.all(promises
)
659 for (const workerNode
of pool
.workerNodes
) {
660 expect(workerNode
.workerUsage
).toStrictEqual({
662 executed
: maxMultiplier
,
668 aggregation
: expect
.any(Number
),
669 average
: expect
.any(Number
),
671 history
: expect
.any(CircularArray
)
677 history
: expect
.any(CircularArray
)
681 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
682 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
685 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
686 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
687 ).workersVirtualTaskEndTimestamp
.length
688 ).toBe(pool
.workerNodes
.length
)
689 // We need to clean up the resources after our test
693 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
694 const pool
= new DynamicThreadPool(
697 './tests/worker-files/thread/testWorker.js',
698 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
700 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
701 const promises
= new Set()
702 const maxMultiplier
= 2
703 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
704 promises
.add(pool
.execute())
706 await Promise
.all(promises
)
707 for (const workerNode
of pool
.workerNodes
) {
708 expect(workerNode
.workerUsage
).toStrictEqual({
710 executed
: maxMultiplier
,
716 aggregation
: expect
.any(Number
),
717 average
: expect
.any(Number
),
719 history
: expect
.any(CircularArray
)
725 history
: expect
.any(CircularArray
)
729 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
730 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
733 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
734 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
735 ).workersVirtualTaskEndTimestamp
.length
736 ).toBe(pool
.workerNodes
.length
)
737 // We need to clean up the resources after our test
741 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
742 const pool
= new DynamicThreadPool(
745 './tests/worker-files/thread/testWorker.js',
747 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
748 workerChoiceStrategyOptions
: {
753 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
754 const promises
= new Set()
755 const maxMultiplier
= 2
756 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
757 promises
.add(pool
.execute())
759 await Promise
.all(promises
)
760 for (const workerNode
of pool
.workerNodes
) {
761 expect(workerNode
.workerUsage
).toStrictEqual({
763 executed
: maxMultiplier
,
769 aggregation
: expect
.any(Number
),
771 median
: expect
.any(Number
),
772 history
: expect
.any(CircularArray
)
778 history
: expect
.any(CircularArray
)
782 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
783 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
786 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
787 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
788 ).workersVirtualTaskEndTimestamp
.length
789 ).toBe(pool
.workerNodes
.length
)
790 // We need to clean up the resources after our test
794 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
795 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
796 let pool
= new FixedThreadPool(
798 './tests/worker-files/thread/testWorker.js'
801 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
803 ).workersVirtualTaskEndTimestamp
804 ).toBeInstanceOf(Array
)
806 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
808 ).workersVirtualTaskEndTimestamp
.length
810 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
812 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
814 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
816 ).workersVirtualTaskEndTimestamp
.length
818 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
820 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
822 ).workersVirtualTaskEndTimestamp
823 ).toBeInstanceOf(Array
)
825 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
827 ).workersVirtualTaskEndTimestamp
.length
830 pool
= new DynamicThreadPool(
833 './tests/worker-files/thread/testWorker.js'
836 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
838 ).workersVirtualTaskEndTimestamp
839 ).toBeInstanceOf(Array
)
841 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
843 ).workersVirtualTaskEndTimestamp
.length
845 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
847 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
849 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
851 ).workersVirtualTaskEndTimestamp
.length
853 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
855 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
857 ).workersVirtualTaskEndTimestamp
858 ).toBeInstanceOf(Array
)
860 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
862 ).workersVirtualTaskEndTimestamp
.length
864 // We need to clean up the resources after our test
868 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
869 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
870 let pool
= new FixedThreadPool(
872 './tests/worker-files/thread/testWorker.js',
873 { workerChoiceStrategy
}
876 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
887 pool
= new DynamicThreadPool(
890 './tests/worker-files/thread/testWorker.js',
891 { workerChoiceStrategy
}
894 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
904 // We need to clean up the resources after our test
908 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
909 const pool
= new FixedThreadPool(
911 './tests/worker-files/thread/testWorker.js',
912 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
914 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
915 const promises
= new Set()
916 const maxMultiplier
= 2
917 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
918 promises
.add(pool
.execute())
920 await Promise
.all(promises
)
921 for (const workerNode
of pool
.workerNodes
) {
922 expect(workerNode
.workerUsage
).toStrictEqual({
924 executed
: expect
.any(Number
),
930 aggregation
: expect
.any(Number
),
931 average
: expect
.any(Number
),
933 history
: expect
.any(CircularArray
)
939 history
: expect
.any(CircularArray
)
943 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
944 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
947 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
950 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
953 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
954 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
955 ).defaultWorkerWeight
958 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
959 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
960 ).workerVirtualTaskRunTime
961 ).toBeGreaterThanOrEqual(0)
962 // We need to clean up the resources after our test
966 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
967 const pool
= new DynamicThreadPool(
970 './tests/worker-files/thread/testWorker.js',
971 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
973 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
974 const promises
= new Set()
975 const maxMultiplier
= 2
976 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
977 promises
.add(pool
.execute())
979 await Promise
.all(promises
)
980 for (const workerNode
of pool
.workerNodes
) {
981 expect(workerNode
.workerUsage
).toStrictEqual({
983 executed
: expect
.any(Number
),
989 aggregation
: expect
.any(Number
),
990 average
: expect
.any(Number
),
992 history
: expect
.any(CircularArray
)
998 history
: expect
.any(CircularArray
)
1002 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1003 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1006 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1007 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1010 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1011 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1012 ).defaultWorkerWeight
1013 ).toBeGreaterThan(0)
1015 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1016 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1017 ).workerVirtualTaskRunTime
1018 ).toBeGreaterThanOrEqual(0)
1019 // We need to clean up the resources after our test
1020 await pool
.destroy()
1023 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1024 const pool
= new DynamicThreadPool(
1027 './tests/worker-files/thread/testWorker.js',
1029 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1030 workerChoiceStrategyOptions
: {
1035 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1036 const promises
= new Set()
1037 const maxMultiplier
= 2
1038 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1039 promises
.add(pool
.execute())
1041 await Promise
.all(promises
)
1042 for (const workerNode
of pool
.workerNodes
) {
1043 expect(workerNode
.workerUsage
).toStrictEqual({
1045 executed
: expect
.any(Number
),
1051 aggregation
: expect
.any(Number
),
1053 median
: expect
.any(Number
),
1054 history
: expect
.any(CircularArray
)
1060 history
: expect
.any(CircularArray
)
1064 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1065 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1068 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1069 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1072 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1073 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1074 ).defaultWorkerWeight
1075 ).toBeGreaterThan(0)
1077 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1078 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1079 ).workerVirtualTaskRunTime
1080 ).toBeGreaterThanOrEqual(0)
1081 // We need to clean up the resources after our test
1082 await pool
.destroy()
1085 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1086 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1087 let pool
= new FixedThreadPool(
1089 './tests/worker-files/thread/testWorker.js'
1092 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1093 workerChoiceStrategy
1094 ).currentWorkerNodeId
1097 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1098 workerChoiceStrategy
1099 ).defaultWorkerWeight
1102 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1103 workerChoiceStrategy
1104 ).workerVirtualTaskRunTime
1106 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1108 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1109 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1110 ).currentWorkerNodeId
1113 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1114 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1115 ).defaultWorkerWeight
1116 ).toBeGreaterThan(0)
1118 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1119 workerChoiceStrategy
1120 ).workerVirtualTaskRunTime
1122 await pool
.destroy()
1123 pool
= new DynamicThreadPool(
1126 './tests/worker-files/thread/testWorker.js'
1129 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1130 workerChoiceStrategy
1131 ).currentWorkerNodeId
1134 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1135 workerChoiceStrategy
1136 ).defaultWorkerWeight
1139 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1140 workerChoiceStrategy
1141 ).workerVirtualTaskRunTime
1143 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1145 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1146 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1147 ).currentWorkerNodeId
1150 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1151 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1152 ).defaultWorkerWeight
1153 ).toBeGreaterThan(0)
1155 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1156 workerChoiceStrategy
1157 ).workerVirtualTaskRunTime
1159 // We need to clean up the resources after our test
1160 await pool
.destroy()
1163 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1164 const workerChoiceStrategy
=
1165 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1166 let pool
= new FixedThreadPool(
1168 './tests/worker-files/thread/testWorker.js',
1169 { workerChoiceStrategy
}
1172 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1182 await pool
.destroy()
1183 pool
= new DynamicThreadPool(
1186 './tests/worker-files/thread/testWorker.js',
1187 { workerChoiceStrategy
}
1190 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1200 // We need to clean up the resources after our test
1201 await pool
.destroy()
1204 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1205 const pool
= new FixedThreadPool(
1207 './tests/worker-files/thread/testWorker.js',
1209 workerChoiceStrategy
:
1210 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1213 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1214 const promises
= new Set()
1215 const maxMultiplier
= 2
1216 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1217 promises
.add(pool
.execute())
1219 await Promise
.all(promises
)
1220 for (const workerNode
of pool
.workerNodes
) {
1221 expect(workerNode
.workerUsage
).toStrictEqual({
1223 executed
: maxMultiplier
,
1232 history
: expect
.any(CircularArray
)
1238 history
: expect
.any(CircularArray
)
1244 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1245 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1246 ).defaultWorkerWeight
1247 ).toBeGreaterThan(0)
1249 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1250 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1254 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1255 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1256 ).currentWorkerNodeId
1259 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1260 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1263 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1264 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1265 ).defaultWorkerWeight
1267 // We need to clean up the resources after our test
1268 await pool
.destroy()
1271 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1272 const pool
= new DynamicThreadPool(
1275 './tests/worker-files/thread/testWorker.js',
1277 workerChoiceStrategy
:
1278 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1281 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1282 const promises
= new Set()
1283 const maxMultiplier
= 2
1284 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1285 promises
.add(pool
.execute())
1287 await Promise
.all(promises
)
1288 for (const workerNode
of pool
.workerNodes
) {
1289 expect(workerNode
.workerUsage
).toStrictEqual({
1291 executed
: maxMultiplier
,
1300 history
: expect
.any(CircularArray
)
1306 history
: expect
.any(CircularArray
)
1312 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1313 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1314 ).defaultWorkerWeight
1315 ).toBeGreaterThan(0)
1317 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1318 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1322 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1323 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1324 ).currentWorkerNodeId
1327 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1328 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1331 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1332 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1333 ).defaultWorkerWeight
1335 // We need to clean up the resources after our test
1336 await pool
.destroy()
1339 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1340 const workerChoiceStrategy
=
1341 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1342 let pool
= new FixedThreadPool(
1344 './tests/worker-files/thread/testWorker.js'
1347 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1348 workerChoiceStrategy
1352 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1353 workerChoiceStrategy
1354 ).currentWorkerNodeId
1357 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1358 workerChoiceStrategy
1359 ).defaultWorkerWeight
1362 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1363 workerChoiceStrategy
1366 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1368 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1369 workerChoiceStrategy
1373 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1374 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1375 ).currentWorkerNodeId
1378 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1379 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1380 ).defaultWorkerWeight
1381 ).toBeGreaterThan(0)
1383 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1384 workerChoiceStrategy
1387 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1388 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1389 ).defaultWorkerWeight
1391 await pool
.destroy()
1392 pool
= new DynamicThreadPool(
1395 './tests/worker-files/thread/testWorker.js'
1398 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1399 workerChoiceStrategy
1403 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1404 workerChoiceStrategy
1405 ).currentWorkerNodeId
1408 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1409 workerChoiceStrategy
1410 ).defaultWorkerWeight
1413 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1414 workerChoiceStrategy
1417 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1419 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1420 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1421 ).currentWorkerNodeId
1424 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1425 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1426 ).defaultWorkerWeight
1427 ).toBeGreaterThan(0)
1429 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1430 workerChoiceStrategy
1433 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1434 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1435 ).defaultWorkerWeight
1437 // We need to clean up the resources after our test
1438 await pool
.destroy()
1441 it('Verify unknown strategy throw error', () => {
1444 new DynamicThreadPool(
1447 './tests/worker-files/thread/testWorker.js',
1448 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1450 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")