1 const { expect
} = require('expect')
3 WorkerChoiceStrategies
,
7 } = require('../../../lib')
8 const { CircularArray
} = require('../../../lib/circular-array')
10 describe('Selection strategies test suite', () => {
14 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
15 expect(WorkerChoiceStrategies
.ROUND_ROBIN
).toBe('ROUND_ROBIN')
16 expect(WorkerChoiceStrategies
.LEAST_USED
).toBe('LEAST_USED')
17 expect(WorkerChoiceStrategies
.LEAST_BUSY
).toBe('LEAST_BUSY')
18 expect(WorkerChoiceStrategies
.LEAST_ELU
).toBe('LEAST_ELU')
19 expect(WorkerChoiceStrategies
.FAIR_SHARE
).toBe('FAIR_SHARE')
20 expect(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
).toBe(
21 'WEIGHTED_ROUND_ROBIN'
23 expect(WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
).toBe(
24 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'
28 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
29 const pool
= new DynamicThreadPool(
32 './tests/worker-files/thread/testWorker.js'
34 expect(pool
.opts
.workerChoiceStrategy
).toBe(
35 WorkerChoiceStrategies
.ROUND_ROBIN
37 // We need to clean up the resources after our test
41 it('Verify available strategies are taken at pool creation', async () => {
42 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
43 const pool
= new FixedThreadPool(
45 './tests/worker-files/thread/testWorker.js',
46 { workerChoiceStrategy
}
48 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
49 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
56 it('Verify available strategies can be set after pool creation', async () => {
57 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
58 const pool
= new DynamicThreadPool(
61 './tests/worker-files/thread/testWorker.js'
63 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
64 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
65 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
72 it('Verify available strategies default internals at pool creation', async () => {
73 const pool
= new FixedThreadPool(
75 './tests/worker-files/thread/testWorker.js'
77 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
78 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.ROUND_ROBIN
) {
80 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
84 } else if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
86 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
88 ).workersVirtualTaskEndTimestamp
89 ).toBeInstanceOf(Array
)
91 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
93 ).workersVirtualTaskEndTimestamp
.length
96 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
99 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
101 ).currentWorkerNodeId
104 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
106 ).defaultWorkerWeight
109 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
111 ).workerVirtualTaskRunTime
118 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
119 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
120 let pool
= new FixedThreadPool(
122 './tests/worker-files/thread/testWorker.js',
123 { workerChoiceStrategy
}
126 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
137 pool
= new DynamicThreadPool(
140 './tests/worker-files/thread/testWorker.js',
141 { workerChoiceStrategy
}
144 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
154 // We need to clean up the resources after our test
158 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
159 const pool
= new FixedThreadPool(
161 './tests/worker-files/thread/testWorker.js',
162 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
164 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
165 const promises
= new Set()
166 const maxMultiplier
= 2
167 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
168 promises
.add(pool
.execute())
170 await Promise
.all(promises
)
171 for (const workerNode
of pool
.workerNodes
) {
172 expect(workerNode
.workerUsage
).toStrictEqual({
174 executed
: maxMultiplier
,
183 history
: expect
.any(CircularArray
)
189 history
: expect
.any(CircularArray
)
195 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
196 WorkerChoiceStrategies
.ROUND_ROBIN
199 // We need to clean up the resources after our test
203 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
204 const pool
= new DynamicThreadPool(
207 './tests/worker-files/thread/testWorker.js',
208 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
210 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
211 const promises
= new Set()
212 const maxMultiplier
= 2
213 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
214 promises
.add(pool
.execute())
216 await Promise
.all(promises
)
217 for (const workerNode
of pool
.workerNodes
) {
218 expect(workerNode
.workerUsage
).toStrictEqual({
220 executed
: maxMultiplier
,
229 history
: expect
.any(CircularArray
)
235 history
: expect
.any(CircularArray
)
241 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
242 WorkerChoiceStrategies
.ROUND_ROBIN
245 // We need to clean up the resources after our test
249 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
250 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
251 let pool
= new FixedClusterPool(
253 './tests/worker-files/cluster/testWorker.js',
254 { workerChoiceStrategy
}
256 let results
= new Set()
257 for (let i
= 0; i
< max
; i
++) {
258 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
260 expect(results
.size
).toBe(max
)
262 pool
= new FixedThreadPool(
264 './tests/worker-files/thread/testWorker.js',
265 { workerChoiceStrategy
}
268 for (let i
= 0; i
< max
; i
++) {
269 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
271 expect(results
.size
).toBe(max
)
275 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
276 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
277 let pool
= new FixedThreadPool(
279 './tests/worker-files/thread/testWorker.js',
280 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
283 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
287 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
289 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
290 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
294 pool
= new DynamicThreadPool(
297 './tests/worker-files/thread/testWorker.js',
298 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
301 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
305 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
307 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
308 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
311 // We need to clean up the resources after our test
315 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
316 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
317 let pool
= new FixedThreadPool(
319 './tests/worker-files/thread/testWorker.js',
320 { workerChoiceStrategy
}
323 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
334 pool
= new DynamicThreadPool(
337 './tests/worker-files/thread/testWorker.js',
338 { workerChoiceStrategy
}
341 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
351 // We need to clean up the resources after our test
355 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
356 const pool
= new FixedThreadPool(
358 './tests/worker-files/thread/testWorker.js',
359 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
361 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
362 const promises
= new Set()
363 const maxMultiplier
= 2
364 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
365 promises
.add(pool
.execute())
367 await Promise
.all(promises
)
368 for (const workerNode
of pool
.workerNodes
) {
369 expect(workerNode
.workerUsage
).toStrictEqual({
371 executed
: maxMultiplier
,
380 history
: expect
.any(CircularArray
)
386 history
: expect
.any(CircularArray
)
391 // We need to clean up the resources after our test
395 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
396 const pool
= new DynamicThreadPool(
399 './tests/worker-files/thread/testWorker.js',
400 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
402 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
403 const promises
= new Set()
404 const maxMultiplier
= 2
405 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
406 promises
.add(pool
.execute())
408 await Promise
.all(promises
)
409 for (const workerNode
of pool
.workerNodes
) {
410 expect(workerNode
.workerUsage
).toStrictEqual({
412 executed
: maxMultiplier
,
421 history
: expect
.any(CircularArray
)
427 history
: expect
.any(CircularArray
)
433 // We need to clean up the resources after our test
437 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
438 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
439 let pool
= new FixedThreadPool(
441 './tests/worker-files/thread/testWorker.js',
442 { workerChoiceStrategy
}
445 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
456 pool
= new DynamicThreadPool(
459 './tests/worker-files/thread/testWorker.js',
460 { workerChoiceStrategy
}
463 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
473 // We need to clean up the resources after our test
477 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
478 const pool
= new FixedThreadPool(
480 './tests/worker-files/thread/testWorker.js',
481 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
483 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
484 const promises
= new Set()
485 const maxMultiplier
= 2
486 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
487 promises
.add(pool
.execute())
489 await Promise
.all(promises
)
490 for (const workerNode
of pool
.workerNodes
) {
491 expect(workerNode
.workerUsage
).toStrictEqual({
493 executed
: expect
.any(Number
),
499 aggregation
: expect
.any(Number
),
502 history
: expect
.any(CircularArray
)
505 aggregation
: expect
.any(Number
),
508 history
: expect
.any(CircularArray
)
512 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
513 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
516 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
520 workerNode
.workerUsage
.waitTime
.aggregation
521 ).toBeGreaterThanOrEqual(0)
523 // We need to clean up the resources after our test
527 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
528 const pool
= new DynamicThreadPool(
531 './tests/worker-files/thread/testWorker.js',
532 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
534 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
535 const promises
= new Set()
536 const maxMultiplier
= 2
537 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
538 promises
.add(pool
.execute())
540 await Promise
.all(promises
)
541 for (const workerNode
of pool
.workerNodes
) {
542 expect(workerNode
.workerUsage
).toStrictEqual({
544 executed
: expect
.any(Number
),
550 aggregation
: expect
.any(Number
),
553 history
: expect
.any(CircularArray
)
556 aggregation
: expect
.any(Number
),
559 history
: expect
.any(CircularArray
)
563 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
564 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
567 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
568 expect(workerNode
.workerUsage
.waitTime
.aggregation
).toBeGreaterThan(0)
570 // We need to clean up the resources after our test
574 it('Verify LEAST_ELU strategy default tasks usage statistics requirements', async () => {
575 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
576 let pool
= new FixedThreadPool(
578 './tests/worker-files/thread/testWorker.js',
579 { workerChoiceStrategy
}
582 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
593 pool
= new DynamicThreadPool(
596 './tests/worker-files/thread/testWorker.js',
597 { workerChoiceStrategy
}
600 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
610 // We need to clean up the resources after our test
614 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
615 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
616 let pool
= new FixedThreadPool(
618 './tests/worker-files/thread/testWorker.js',
619 { workerChoiceStrategy
}
622 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
633 pool
= new DynamicThreadPool(
636 './tests/worker-files/thread/testWorker.js',
637 { workerChoiceStrategy
}
640 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
650 // We need to clean up the resources after our test
654 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
655 const pool
= new FixedThreadPool(
657 './tests/worker-files/thread/testWorker.js',
658 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
660 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
661 const promises
= new Set()
662 const maxMultiplier
= 2
663 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
664 promises
.add(pool
.execute())
666 await Promise
.all(promises
)
667 for (const workerNode
of pool
.workerNodes
) {
668 expect(workerNode
.workerUsage
).toStrictEqual({
670 executed
: maxMultiplier
,
676 aggregation
: expect
.any(Number
),
677 average
: expect
.any(Number
),
679 history
: expect
.any(CircularArray
)
685 history
: expect
.any(CircularArray
)
689 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
690 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
693 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
694 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
695 ).workersVirtualTaskEndTimestamp
.length
696 ).toBe(pool
.workerNodes
.length
)
697 // We need to clean up the resources after our test
701 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
702 const pool
= new DynamicThreadPool(
705 './tests/worker-files/thread/testWorker.js',
706 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
708 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
709 const promises
= new Set()
710 const maxMultiplier
= 2
711 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
712 promises
.add(pool
.execute())
714 await Promise
.all(promises
)
715 for (const workerNode
of pool
.workerNodes
) {
716 expect(workerNode
.workerUsage
).toStrictEqual({
718 executed
: maxMultiplier
,
724 aggregation
: expect
.any(Number
),
725 average
: expect
.any(Number
),
727 history
: expect
.any(CircularArray
)
733 history
: expect
.any(CircularArray
)
737 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
738 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
741 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
742 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
743 ).workersVirtualTaskEndTimestamp
.length
744 ).toBe(pool
.workerNodes
.length
)
745 // We need to clean up the resources after our test
749 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
750 const pool
= new DynamicThreadPool(
753 './tests/worker-files/thread/testWorker.js',
755 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
756 workerChoiceStrategyOptions
: {
761 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
762 const promises
= new Set()
763 const maxMultiplier
= 2
764 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
765 promises
.add(pool
.execute())
767 await Promise
.all(promises
)
768 for (const workerNode
of pool
.workerNodes
) {
769 expect(workerNode
.workerUsage
).toStrictEqual({
771 executed
: maxMultiplier
,
777 aggregation
: expect
.any(Number
),
779 median
: expect
.any(Number
),
780 history
: expect
.any(CircularArray
)
786 history
: expect
.any(CircularArray
)
790 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
791 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
794 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
795 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
796 ).workersVirtualTaskEndTimestamp
.length
797 ).toBe(pool
.workerNodes
.length
)
798 // We need to clean up the resources after our test
802 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
803 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
804 let pool
= new FixedThreadPool(
806 './tests/worker-files/thread/testWorker.js'
809 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
811 ).workersVirtualTaskEndTimestamp
812 ).toBeInstanceOf(Array
)
814 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
816 ).workersVirtualTaskEndTimestamp
.length
818 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
820 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
822 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
824 ).workersVirtualTaskEndTimestamp
.length
826 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
828 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
830 ).workersVirtualTaskEndTimestamp
831 ).toBeInstanceOf(Array
)
833 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
835 ).workersVirtualTaskEndTimestamp
.length
838 pool
= new DynamicThreadPool(
841 './tests/worker-files/thread/testWorker.js'
844 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
846 ).workersVirtualTaskEndTimestamp
847 ).toBeInstanceOf(Array
)
849 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
851 ).workersVirtualTaskEndTimestamp
.length
853 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
855 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
857 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
859 ).workersVirtualTaskEndTimestamp
.length
861 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
863 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
865 ).workersVirtualTaskEndTimestamp
866 ).toBeInstanceOf(Array
)
868 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
870 ).workersVirtualTaskEndTimestamp
.length
872 // We need to clean up the resources after our test
876 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
877 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
878 let pool
= new FixedThreadPool(
880 './tests/worker-files/thread/testWorker.js',
881 { workerChoiceStrategy
}
884 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
895 pool
= new DynamicThreadPool(
898 './tests/worker-files/thread/testWorker.js',
899 { workerChoiceStrategy
}
902 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
912 // We need to clean up the resources after our test
916 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
917 const pool
= new FixedThreadPool(
919 './tests/worker-files/thread/testWorker.js',
920 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
922 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
923 const promises
= new Set()
924 const maxMultiplier
= 2
925 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
926 promises
.add(pool
.execute())
928 await Promise
.all(promises
)
929 for (const workerNode
of pool
.workerNodes
) {
930 expect(workerNode
.workerUsage
).toStrictEqual({
932 executed
: expect
.any(Number
),
938 aggregation
: expect
.any(Number
),
939 average
: expect
.any(Number
),
941 history
: expect
.any(CircularArray
)
947 history
: expect
.any(CircularArray
)
951 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
952 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
955 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
958 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
961 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
962 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
963 ).defaultWorkerWeight
966 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
967 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
968 ).workerVirtualTaskRunTime
969 ).toBeGreaterThanOrEqual(0)
970 // We need to clean up the resources after our test
974 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
975 const pool
= new DynamicThreadPool(
978 './tests/worker-files/thread/testWorker.js',
979 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
981 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
982 const promises
= new Set()
983 const maxMultiplier
= 2
984 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
985 promises
.add(pool
.execute())
987 await Promise
.all(promises
)
988 for (const workerNode
of pool
.workerNodes
) {
989 expect(workerNode
.workerUsage
).toStrictEqual({
991 executed
: expect
.any(Number
),
997 aggregation
: expect
.any(Number
),
998 average
: expect
.any(Number
),
1000 history
: expect
.any(CircularArray
)
1006 history
: expect
.any(CircularArray
)
1010 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1011 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1014 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1015 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1018 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1019 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1020 ).defaultWorkerWeight
1021 ).toBeGreaterThan(0)
1023 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1024 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1025 ).workerVirtualTaskRunTime
1026 ).toBeGreaterThanOrEqual(0)
1027 // We need to clean up the resources after our test
1028 await pool
.destroy()
1031 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1032 const pool
= new DynamicThreadPool(
1035 './tests/worker-files/thread/testWorker.js',
1037 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1038 workerChoiceStrategyOptions
: {
1043 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1044 const promises
= new Set()
1045 const maxMultiplier
= 2
1046 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1047 promises
.add(pool
.execute())
1049 await Promise
.all(promises
)
1050 for (const workerNode
of pool
.workerNodes
) {
1051 expect(workerNode
.workerUsage
).toStrictEqual({
1053 executed
: expect
.any(Number
),
1059 aggregation
: expect
.any(Number
),
1061 median
: expect
.any(Number
),
1062 history
: expect
.any(CircularArray
)
1068 history
: expect
.any(CircularArray
)
1072 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1073 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1076 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1077 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1080 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1081 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1082 ).defaultWorkerWeight
1083 ).toBeGreaterThan(0)
1085 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1086 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1087 ).workerVirtualTaskRunTime
1088 ).toBeGreaterThanOrEqual(0)
1089 // We need to clean up the resources after our test
1090 await pool
.destroy()
1093 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1094 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1095 let pool
= new FixedThreadPool(
1097 './tests/worker-files/thread/testWorker.js'
1100 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1101 workerChoiceStrategy
1102 ).currentWorkerNodeId
1105 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1106 workerChoiceStrategy
1107 ).defaultWorkerWeight
1110 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1111 workerChoiceStrategy
1112 ).workerVirtualTaskRunTime
1114 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1116 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1117 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1118 ).currentWorkerNodeId
1121 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1122 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1123 ).defaultWorkerWeight
1124 ).toBeGreaterThan(0)
1126 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1127 workerChoiceStrategy
1128 ).workerVirtualTaskRunTime
1130 await pool
.destroy()
1131 pool
= new DynamicThreadPool(
1134 './tests/worker-files/thread/testWorker.js'
1137 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1138 workerChoiceStrategy
1139 ).currentWorkerNodeId
1142 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1143 workerChoiceStrategy
1144 ).defaultWorkerWeight
1147 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1148 workerChoiceStrategy
1149 ).workerVirtualTaskRunTime
1151 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1153 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1154 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1155 ).currentWorkerNodeId
1158 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1159 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1160 ).defaultWorkerWeight
1161 ).toBeGreaterThan(0)
1163 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1164 workerChoiceStrategy
1165 ).workerVirtualTaskRunTime
1167 // We need to clean up the resources after our test
1168 await pool
.destroy()
1171 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1172 const workerChoiceStrategy
=
1173 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1174 let pool
= new FixedThreadPool(
1176 './tests/worker-files/thread/testWorker.js',
1177 { workerChoiceStrategy
}
1180 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1190 await pool
.destroy()
1191 pool
= new DynamicThreadPool(
1194 './tests/worker-files/thread/testWorker.js',
1195 { workerChoiceStrategy
}
1198 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1208 // We need to clean up the resources after our test
1209 await pool
.destroy()
1212 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1213 const pool
= new FixedThreadPool(
1215 './tests/worker-files/thread/testWorker.js',
1217 workerChoiceStrategy
:
1218 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1221 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1222 const promises
= new Set()
1223 const maxMultiplier
= 2
1224 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1225 promises
.add(pool
.execute())
1227 await Promise
.all(promises
)
1228 for (const workerNode
of pool
.workerNodes
) {
1229 expect(workerNode
.workerUsage
).toStrictEqual({
1231 executed
: maxMultiplier
,
1240 history
: expect
.any(CircularArray
)
1246 history
: expect
.any(CircularArray
)
1252 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1253 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1254 ).defaultWorkerWeight
1255 ).toBeGreaterThan(0)
1257 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1258 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1262 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1263 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1264 ).currentWorkerNodeId
1267 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1268 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1271 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1272 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1273 ).defaultWorkerWeight
1275 // We need to clean up the resources after our test
1276 await pool
.destroy()
1279 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1280 const pool
= new DynamicThreadPool(
1283 './tests/worker-files/thread/testWorker.js',
1285 workerChoiceStrategy
:
1286 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1289 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1290 const promises
= new Set()
1291 const maxMultiplier
= 2
1292 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1293 promises
.add(pool
.execute())
1295 await Promise
.all(promises
)
1296 for (const workerNode
of pool
.workerNodes
) {
1297 expect(workerNode
.workerUsage
).toStrictEqual({
1299 executed
: maxMultiplier
,
1308 history
: expect
.any(CircularArray
)
1314 history
: expect
.any(CircularArray
)
1320 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1321 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1322 ).defaultWorkerWeight
1323 ).toBeGreaterThan(0)
1325 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1326 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1330 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1331 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1332 ).currentWorkerNodeId
1335 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1336 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1339 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1340 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1341 ).defaultWorkerWeight
1343 // We need to clean up the resources after our test
1344 await pool
.destroy()
1347 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1348 const workerChoiceStrategy
=
1349 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1350 let pool
= new FixedThreadPool(
1352 './tests/worker-files/thread/testWorker.js'
1355 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1356 workerChoiceStrategy
1360 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1361 workerChoiceStrategy
1362 ).currentWorkerNodeId
1365 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1366 workerChoiceStrategy
1367 ).defaultWorkerWeight
1370 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1371 workerChoiceStrategy
1374 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1376 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1377 workerChoiceStrategy
1381 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1382 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1383 ).currentWorkerNodeId
1386 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1387 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1388 ).defaultWorkerWeight
1389 ).toBeGreaterThan(0)
1391 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1392 workerChoiceStrategy
1395 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1396 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1397 ).defaultWorkerWeight
1399 await pool
.destroy()
1400 pool
= new DynamicThreadPool(
1403 './tests/worker-files/thread/testWorker.js'
1406 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1407 workerChoiceStrategy
1411 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1412 workerChoiceStrategy
1413 ).currentWorkerNodeId
1416 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1417 workerChoiceStrategy
1418 ).defaultWorkerWeight
1421 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1422 workerChoiceStrategy
1425 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1427 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1428 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1429 ).currentWorkerNodeId
1432 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1433 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1434 ).defaultWorkerWeight
1435 ).toBeGreaterThan(0)
1437 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1438 workerChoiceStrategy
1441 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1442 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1443 ).defaultWorkerWeight
1445 // We need to clean up the resources after our test
1446 await pool
.destroy()
1449 it('Verify unknown strategy throw error', () => {
1452 new DynamicThreadPool(
1455 './tests/worker-files/thread/testWorker.js',
1456 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1458 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")