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
}
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 default tasks usage statistics requirements', async () => {
611 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
612 let pool
= new FixedThreadPool(
614 './tests/worker-files/thread/testWorker.js',
615 { workerChoiceStrategy
}
618 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
629 pool
= new DynamicThreadPool(
632 './tests/worker-files/thread/testWorker.js',
633 { workerChoiceStrategy
}
636 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
646 // We need to clean up the resources after our test
650 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
651 const pool
= new FixedThreadPool(
653 './tests/worker-files/thread/testWorker.js',
654 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
656 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
657 const promises
= new Set()
658 const maxMultiplier
= 2
659 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
660 promises
.add(pool
.execute())
662 await Promise
.all(promises
)
663 for (const workerNode
of pool
.workerNodes
) {
664 expect(workerNode
.workerUsage
).toStrictEqual({
666 executed
: maxMultiplier
,
672 aggregation
: expect
.any(Number
),
673 average
: expect
.any(Number
),
675 history
: expect
.any(CircularArray
)
681 history
: expect
.any(CircularArray
)
685 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
686 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
689 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
690 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
691 ).workersVirtualTaskEndTimestamp
.length
692 ).toBe(pool
.workerNodes
.length
)
693 // We need to clean up the resources after our test
697 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
698 const pool
= new DynamicThreadPool(
701 './tests/worker-files/thread/testWorker.js',
702 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
704 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
705 const promises
= new Set()
706 const maxMultiplier
= 2
707 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
708 promises
.add(pool
.execute())
710 await Promise
.all(promises
)
711 for (const workerNode
of pool
.workerNodes
) {
712 expect(workerNode
.workerUsage
).toStrictEqual({
714 executed
: maxMultiplier
,
720 aggregation
: expect
.any(Number
),
721 average
: expect
.any(Number
),
723 history
: expect
.any(CircularArray
)
729 history
: expect
.any(CircularArray
)
733 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
734 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
737 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
738 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
739 ).workersVirtualTaskEndTimestamp
.length
740 ).toBe(pool
.workerNodes
.length
)
741 // We need to clean up the resources after our test
745 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
746 const pool
= new DynamicThreadPool(
749 './tests/worker-files/thread/testWorker.js',
751 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
752 workerChoiceStrategyOptions
: {
757 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
758 const promises
= new Set()
759 const maxMultiplier
= 2
760 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
761 promises
.add(pool
.execute())
763 await Promise
.all(promises
)
764 for (const workerNode
of pool
.workerNodes
) {
765 expect(workerNode
.workerUsage
).toStrictEqual({
767 executed
: maxMultiplier
,
773 aggregation
: expect
.any(Number
),
775 median
: expect
.any(Number
),
776 history
: expect
.any(CircularArray
)
782 history
: expect
.any(CircularArray
)
786 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
787 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
790 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
791 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
792 ).workersVirtualTaskEndTimestamp
.length
793 ).toBe(pool
.workerNodes
.length
)
794 // We need to clean up the resources after our test
798 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
799 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
800 let pool
= new FixedThreadPool(
802 './tests/worker-files/thread/testWorker.js'
805 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
807 ).workersVirtualTaskEndTimestamp
808 ).toBeInstanceOf(Array
)
810 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
812 ).workersVirtualTaskEndTimestamp
.length
814 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
816 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
818 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
820 ).workersVirtualTaskEndTimestamp
.length
822 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
824 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
826 ).workersVirtualTaskEndTimestamp
827 ).toBeInstanceOf(Array
)
829 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
831 ).workersVirtualTaskEndTimestamp
.length
834 pool
= new DynamicThreadPool(
837 './tests/worker-files/thread/testWorker.js'
840 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
842 ).workersVirtualTaskEndTimestamp
843 ).toBeInstanceOf(Array
)
845 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
847 ).workersVirtualTaskEndTimestamp
.length
849 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
851 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
853 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
855 ).workersVirtualTaskEndTimestamp
.length
857 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
859 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
861 ).workersVirtualTaskEndTimestamp
862 ).toBeInstanceOf(Array
)
864 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
866 ).workersVirtualTaskEndTimestamp
.length
868 // We need to clean up the resources after our test
872 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
873 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
874 let pool
= new FixedThreadPool(
876 './tests/worker-files/thread/testWorker.js',
877 { workerChoiceStrategy
}
880 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
891 pool
= new DynamicThreadPool(
894 './tests/worker-files/thread/testWorker.js',
895 { workerChoiceStrategy
}
898 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
908 // We need to clean up the resources after our test
912 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
913 const pool
= new FixedThreadPool(
915 './tests/worker-files/thread/testWorker.js',
916 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
918 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
919 const promises
= new Set()
920 const maxMultiplier
= 2
921 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
922 promises
.add(pool
.execute())
924 await Promise
.all(promises
)
925 for (const workerNode
of pool
.workerNodes
) {
926 expect(workerNode
.workerUsage
).toStrictEqual({
928 executed
: expect
.any(Number
),
934 aggregation
: expect
.any(Number
),
935 average
: expect
.any(Number
),
937 history
: expect
.any(CircularArray
)
943 history
: expect
.any(CircularArray
)
947 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
948 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
951 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
954 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
957 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
958 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
959 ).defaultWorkerWeight
962 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
963 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
964 ).workerVirtualTaskRunTime
965 ).toBeGreaterThanOrEqual(0)
966 // We need to clean up the resources after our test
970 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
971 const pool
= new DynamicThreadPool(
974 './tests/worker-files/thread/testWorker.js',
975 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
977 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
978 const promises
= new Set()
979 const maxMultiplier
= 2
980 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
981 promises
.add(pool
.execute())
983 await Promise
.all(promises
)
984 for (const workerNode
of pool
.workerNodes
) {
985 expect(workerNode
.workerUsage
).toStrictEqual({
987 executed
: expect
.any(Number
),
993 aggregation
: expect
.any(Number
),
994 average
: expect
.any(Number
),
996 history
: expect
.any(CircularArray
)
1002 history
: expect
.any(CircularArray
)
1006 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1007 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1010 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1011 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1014 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1015 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1016 ).defaultWorkerWeight
1017 ).toBeGreaterThan(0)
1019 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1020 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1021 ).workerVirtualTaskRunTime
1022 ).toBeGreaterThanOrEqual(0)
1023 // We need to clean up the resources after our test
1024 await pool
.destroy()
1027 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1028 const pool
= new DynamicThreadPool(
1031 './tests/worker-files/thread/testWorker.js',
1033 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1034 workerChoiceStrategyOptions
: {
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
),
1057 median
: 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
.median
).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 internals are resets after setting it', async () => {
1090 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1091 let pool
= new FixedThreadPool(
1093 './tests/worker-files/thread/testWorker.js'
1096 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1097 workerChoiceStrategy
1098 ).currentWorkerNodeId
1101 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1102 workerChoiceStrategy
1103 ).defaultWorkerWeight
1106 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1107 workerChoiceStrategy
1108 ).workerVirtualTaskRunTime
1110 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1112 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1113 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1114 ).currentWorkerNodeId
1117 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1118 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1119 ).defaultWorkerWeight
1120 ).toBeGreaterThan(0)
1122 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1123 workerChoiceStrategy
1124 ).workerVirtualTaskRunTime
1126 await pool
.destroy()
1127 pool
= new DynamicThreadPool(
1130 './tests/worker-files/thread/testWorker.js'
1133 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1134 workerChoiceStrategy
1135 ).currentWorkerNodeId
1138 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1139 workerChoiceStrategy
1140 ).defaultWorkerWeight
1143 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1144 workerChoiceStrategy
1145 ).workerVirtualTaskRunTime
1147 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1149 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1150 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1151 ).currentWorkerNodeId
1154 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1155 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1156 ).defaultWorkerWeight
1157 ).toBeGreaterThan(0)
1159 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1160 workerChoiceStrategy
1161 ).workerVirtualTaskRunTime
1163 // We need to clean up the resources after our test
1164 await pool
.destroy()
1167 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1168 const workerChoiceStrategy
=
1169 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1170 let pool
= new FixedThreadPool(
1172 './tests/worker-files/thread/testWorker.js',
1173 { workerChoiceStrategy
}
1176 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1186 await pool
.destroy()
1187 pool
= new DynamicThreadPool(
1190 './tests/worker-files/thread/testWorker.js',
1191 { workerChoiceStrategy
}
1194 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1204 // We need to clean up the resources after our test
1205 await pool
.destroy()
1208 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1209 const pool
= new FixedThreadPool(
1211 './tests/worker-files/thread/testWorker.js',
1213 workerChoiceStrategy
:
1214 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1217 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1218 const promises
= new Set()
1219 const maxMultiplier
= 2
1220 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1221 promises
.add(pool
.execute())
1223 await Promise
.all(promises
)
1224 for (const workerNode
of pool
.workerNodes
) {
1225 expect(workerNode
.workerUsage
).toStrictEqual({
1227 executed
: maxMultiplier
,
1236 history
: expect
.any(CircularArray
)
1242 history
: expect
.any(CircularArray
)
1248 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1249 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1250 ).defaultWorkerWeight
1251 ).toBeGreaterThan(0)
1253 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1254 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1258 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1259 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1260 ).currentWorkerNodeId
1263 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1264 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1267 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1268 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1269 ).defaultWorkerWeight
1271 // We need to clean up the resources after our test
1272 await pool
.destroy()
1275 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1276 const pool
= new DynamicThreadPool(
1279 './tests/worker-files/thread/testWorker.js',
1281 workerChoiceStrategy
:
1282 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1285 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1286 const promises
= new Set()
1287 const maxMultiplier
= 2
1288 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1289 promises
.add(pool
.execute())
1291 await Promise
.all(promises
)
1292 for (const workerNode
of pool
.workerNodes
) {
1293 expect(workerNode
.workerUsage
).toStrictEqual({
1295 executed
: maxMultiplier
,
1304 history
: expect
.any(CircularArray
)
1310 history
: expect
.any(CircularArray
)
1316 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1317 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1318 ).defaultWorkerWeight
1319 ).toBeGreaterThan(0)
1321 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1322 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1326 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1327 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1328 ).currentWorkerNodeId
1331 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1332 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1335 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1336 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1337 ).defaultWorkerWeight
1339 // We need to clean up the resources after our test
1340 await pool
.destroy()
1343 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1344 const workerChoiceStrategy
=
1345 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1346 let pool
= new FixedThreadPool(
1348 './tests/worker-files/thread/testWorker.js'
1351 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1352 workerChoiceStrategy
1356 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1357 workerChoiceStrategy
1358 ).currentWorkerNodeId
1361 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1362 workerChoiceStrategy
1363 ).defaultWorkerWeight
1366 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1367 workerChoiceStrategy
1370 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1372 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1373 workerChoiceStrategy
1377 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1378 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1379 ).currentWorkerNodeId
1382 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1383 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1384 ).defaultWorkerWeight
1385 ).toBeGreaterThan(0)
1387 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1388 workerChoiceStrategy
1391 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1392 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1393 ).defaultWorkerWeight
1395 await pool
.destroy()
1396 pool
= new DynamicThreadPool(
1399 './tests/worker-files/thread/testWorker.js'
1402 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1403 workerChoiceStrategy
1407 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1408 workerChoiceStrategy
1409 ).currentWorkerNodeId
1412 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1413 workerChoiceStrategy
1414 ).defaultWorkerWeight
1417 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1418 workerChoiceStrategy
1421 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1423 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1424 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1425 ).currentWorkerNodeId
1428 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1429 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1430 ).defaultWorkerWeight
1431 ).toBeGreaterThan(0)
1433 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1434 workerChoiceStrategy
1437 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1438 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1439 ).defaultWorkerWeight
1441 // We need to clean up the resources after our test
1442 await pool
.destroy()
1445 it('Verify unknown strategy throw error', () => {
1448 new DynamicThreadPool(
1451 './tests/worker-files/thread/testWorker.js',
1452 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1454 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")