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
.FAIR_SHARE
).toBe('FAIR_SHARE')
19 expect(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
).toBe(
20 'WEIGHTED_ROUND_ROBIN'
22 expect(WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
).toBe(
23 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'
27 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
28 const pool
= new DynamicThreadPool(
31 './tests/worker-files/thread/testWorker.js'
33 expect(pool
.opts
.workerChoiceStrategy
).toBe(
34 WorkerChoiceStrategies
.ROUND_ROBIN
36 // We need to clean up the resources after our test
40 it('Verify available strategies are taken at pool creation', async () => {
41 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
42 const pool
= new FixedThreadPool(
44 './tests/worker-files/thread/testWorker.js',
45 { workerChoiceStrategy
}
47 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
48 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
55 it('Verify available strategies can be set after pool creation', async () => {
56 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
57 const pool
= new DynamicThreadPool(
60 './tests/worker-files/thread/testWorker.js'
62 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
63 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
64 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
71 it('Verify available strategies default internals at pool creation', async () => {
72 const pool
= new FixedThreadPool(
74 './tests/worker-files/thread/testWorker.js'
76 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
77 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.ROUND_ROBIN
) {
79 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
83 } else if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
85 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
87 ).workersVirtualTaskEndTimestamp
88 ).toBeInstanceOf(Array
)
90 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
92 ).workersVirtualTaskEndTimestamp
.length
95 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
98 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
100 ).currentWorkerNodeId
103 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
105 ).defaultWorkerWeight
108 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
110 ).workerVirtualTaskRunTime
117 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
118 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
119 let pool
= new FixedThreadPool(
121 './tests/worker-files/thread/testWorker.js',
122 { workerChoiceStrategy
}
125 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
140 pool
= new DynamicThreadPool(
143 './tests/worker-files/thread/testWorker.js',
144 { workerChoiceStrategy
}
147 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
161 // We need to clean up the resources after our test
165 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
166 const pool
= new FixedThreadPool(
168 './tests/worker-files/thread/testWorker.js',
169 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
171 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
172 const promises
= new Set()
173 const maxMultiplier
= 2
174 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
175 promises
.add(pool
.execute())
177 await Promise
.all(promises
)
178 for (const workerNode
of pool
.workerNodes
) {
179 expect(workerNode
.workerUsage
).toStrictEqual({
181 executed
: maxMultiplier
,
190 history
: expect
.any(CircularArray
)
196 history
: expect
.any(CircularArray
)
202 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
203 WorkerChoiceStrategies
.ROUND_ROBIN
206 // We need to clean up the resources after our test
210 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
211 const pool
= new DynamicThreadPool(
214 './tests/worker-files/thread/testWorker.js',
215 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
217 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
218 const promises
= new Set()
219 const maxMultiplier
= 2
220 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
221 promises
.add(pool
.execute())
223 await Promise
.all(promises
)
224 for (const workerNode
of pool
.workerNodes
) {
225 expect(workerNode
.workerUsage
).toStrictEqual({
227 executed
: maxMultiplier
,
236 history
: expect
.any(CircularArray
)
242 history
: expect
.any(CircularArray
)
248 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
249 WorkerChoiceStrategies
.ROUND_ROBIN
252 // We need to clean up the resources after our test
256 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
257 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
258 let pool
= new FixedClusterPool(
260 './tests/worker-files/cluster/testWorker.js',
261 { workerChoiceStrategy
}
263 let results
= new Set()
264 for (let i
= 0; i
< max
; i
++) {
265 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
267 expect(results
.size
).toBe(max
)
269 pool
= new FixedThreadPool(
271 './tests/worker-files/thread/testWorker.js',
272 { workerChoiceStrategy
}
275 for (let i
= 0; i
< max
; i
++) {
276 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
278 expect(results
.size
).toBe(max
)
282 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
283 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
284 let pool
= new FixedThreadPool(
286 './tests/worker-files/thread/testWorker.js',
287 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
290 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
294 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
296 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
297 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
301 pool
= new DynamicThreadPool(
304 './tests/worker-files/thread/testWorker.js',
305 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
308 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
312 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
314 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
315 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
318 // We need to clean up the resources after our test
322 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
323 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
324 let pool
= new FixedThreadPool(
326 './tests/worker-files/thread/testWorker.js',
327 { workerChoiceStrategy
}
330 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
345 pool
= new DynamicThreadPool(
348 './tests/worker-files/thread/testWorker.js',
349 { workerChoiceStrategy
}
352 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
366 // We need to clean up the resources after our test
370 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
371 const pool
= new FixedThreadPool(
373 './tests/worker-files/thread/testWorker.js',
374 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
376 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
377 const promises
= new Set()
378 const maxMultiplier
= 2
379 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
380 promises
.add(pool
.execute())
382 await Promise
.all(promises
)
383 for (const workerNode
of pool
.workerNodes
) {
384 expect(workerNode
.workerUsage
).toStrictEqual({
386 executed
: maxMultiplier
,
395 history
: expect
.any(CircularArray
)
401 history
: expect
.any(CircularArray
)
406 // We need to clean up the resources after our test
410 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
411 const pool
= new DynamicThreadPool(
414 './tests/worker-files/thread/testWorker.js',
415 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
417 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
418 const promises
= new Set()
419 const maxMultiplier
= 2
420 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
421 promises
.add(pool
.execute())
423 await Promise
.all(promises
)
424 for (const workerNode
of pool
.workerNodes
) {
425 expect(workerNode
.workerUsage
).toStrictEqual({
427 executed
: maxMultiplier
,
436 history
: expect
.any(CircularArray
)
442 history
: expect
.any(CircularArray
)
448 // We need to clean up the resources after our test
452 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
453 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
454 let pool
= new FixedThreadPool(
456 './tests/worker-files/thread/testWorker.js',
457 { workerChoiceStrategy
}
460 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
475 pool
= new DynamicThreadPool(
478 './tests/worker-files/thread/testWorker.js',
479 { workerChoiceStrategy
}
482 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
496 // We need to clean up the resources after our test
500 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
501 const pool
= new FixedThreadPool(
503 './tests/worker-files/thread/testWorker.js',
504 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
506 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
507 const promises
= new Set()
508 const maxMultiplier
= 2
509 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
510 promises
.add(pool
.execute())
512 await Promise
.all(promises
)
513 for (const workerNode
of pool
.workerNodes
) {
514 expect(workerNode
.workerUsage
).toStrictEqual({
516 executed
: expect
.any(Number
),
522 aggregate
: expect
.any(Number
),
525 history
: expect
.any(CircularArray
)
528 aggregate
: expect
.any(Number
),
531 history
: expect
.any(CircularArray
)
535 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
536 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
539 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThanOrEqual(0)
540 expect(workerNode
.workerUsage
.waitTime
.aggregate
).toBeGreaterThanOrEqual(
544 // We need to clean up the resources after our test
548 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
549 const pool
= new DynamicThreadPool(
552 './tests/worker-files/thread/testWorker.js',
553 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
555 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
556 const promises
= new Set()
557 const maxMultiplier
= 2
558 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
559 promises
.add(pool
.execute())
561 await Promise
.all(promises
)
562 for (const workerNode
of pool
.workerNodes
) {
563 expect(workerNode
.workerUsage
).toStrictEqual({
565 executed
: expect
.any(Number
),
571 aggregate
: expect
.any(Number
),
574 history
: expect
.any(CircularArray
)
577 aggregate
: expect
.any(Number
),
580 history
: expect
.any(CircularArray
)
584 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
585 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
588 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
589 expect(workerNode
.workerUsage
.waitTime
.aggregate
).toBeGreaterThan(0)
591 // We need to clean up the resources after our test
595 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
596 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
597 let pool
= new FixedThreadPool(
599 './tests/worker-files/thread/testWorker.js',
600 { workerChoiceStrategy
}
603 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
618 pool
= new DynamicThreadPool(
621 './tests/worker-files/thread/testWorker.js',
622 { workerChoiceStrategy
}
625 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
639 // We need to clean up the resources after our test
643 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
644 const pool
= new FixedThreadPool(
646 './tests/worker-files/thread/testWorker.js',
647 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
649 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
650 const promises
= new Set()
651 const maxMultiplier
= 2
652 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
653 promises
.add(pool
.execute())
655 await Promise
.all(promises
)
656 for (const workerNode
of pool
.workerNodes
) {
657 expect(workerNode
.workerUsage
).toStrictEqual({
659 executed
: maxMultiplier
,
665 aggregate
: expect
.any(Number
),
666 average
: expect
.any(Number
),
668 history
: expect
.any(CircularArray
)
674 history
: expect
.any(CircularArray
)
678 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
679 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
682 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
683 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
684 ).workersVirtualTaskEndTimestamp
.length
685 ).toBe(pool
.workerNodes
.length
)
686 // We need to clean up the resources after our test
690 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
691 const pool
= new DynamicThreadPool(
694 './tests/worker-files/thread/testWorker.js',
695 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
697 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
698 const promises
= new Set()
699 const maxMultiplier
= 2
700 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
701 promises
.add(pool
.execute())
703 await Promise
.all(promises
)
704 for (const workerNode
of pool
.workerNodes
) {
705 expect(workerNode
.workerUsage
).toStrictEqual({
707 executed
: maxMultiplier
,
713 aggregate
: expect
.any(Number
),
714 average
: expect
.any(Number
),
716 history
: expect
.any(CircularArray
)
722 history
: expect
.any(CircularArray
)
726 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
727 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
730 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
731 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
732 ).workersVirtualTaskEndTimestamp
.length
733 ).toBe(pool
.workerNodes
.length
)
734 // We need to clean up the resources after our test
738 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
739 const pool
= new DynamicThreadPool(
742 './tests/worker-files/thread/testWorker.js',
744 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
745 workerChoiceStrategyOptions
: {
746 runTime
: { median
: true }
750 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
751 const promises
= new Set()
752 const maxMultiplier
= 2
753 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
754 promises
.add(pool
.execute())
756 await Promise
.all(promises
)
757 for (const workerNode
of pool
.workerNodes
) {
758 expect(workerNode
.workerUsage
).toStrictEqual({
760 executed
: maxMultiplier
,
766 aggregate
: expect
.any(Number
),
768 median
: expect
.any(Number
),
769 history
: expect
.any(CircularArray
)
775 history
: expect
.any(CircularArray
)
779 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
780 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
783 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
784 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
785 ).workersVirtualTaskEndTimestamp
.length
786 ).toBe(pool
.workerNodes
.length
)
787 // We need to clean up the resources after our test
791 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
792 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
793 let pool
= new FixedThreadPool(
795 './tests/worker-files/thread/testWorker.js'
798 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
800 ).workersVirtualTaskEndTimestamp
801 ).toBeInstanceOf(Array
)
803 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
805 ).workersVirtualTaskEndTimestamp
.length
807 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
809 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
811 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
813 ).workersVirtualTaskEndTimestamp
.length
815 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
817 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
819 ).workersVirtualTaskEndTimestamp
820 ).toBeInstanceOf(Array
)
822 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
824 ).workersVirtualTaskEndTimestamp
.length
827 pool
= new DynamicThreadPool(
830 './tests/worker-files/thread/testWorker.js'
833 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
835 ).workersVirtualTaskEndTimestamp
836 ).toBeInstanceOf(Array
)
838 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
840 ).workersVirtualTaskEndTimestamp
.length
842 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
844 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
846 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
848 ).workersVirtualTaskEndTimestamp
.length
850 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
852 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
854 ).workersVirtualTaskEndTimestamp
855 ).toBeInstanceOf(Array
)
857 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
859 ).workersVirtualTaskEndTimestamp
.length
861 // We need to clean up the resources after our test
865 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
866 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
867 let pool
= new FixedThreadPool(
869 './tests/worker-files/thread/testWorker.js',
870 { workerChoiceStrategy
}
873 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
888 pool
= new DynamicThreadPool(
891 './tests/worker-files/thread/testWorker.js',
892 { workerChoiceStrategy
}
895 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
909 // We need to clean up the resources after our test
913 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
914 const pool
= new FixedThreadPool(
916 './tests/worker-files/thread/testWorker.js',
917 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
919 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
920 const promises
= new Set()
921 const maxMultiplier
= 2
922 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
923 promises
.add(pool
.execute())
925 await Promise
.all(promises
)
926 for (const workerNode
of pool
.workerNodes
) {
927 expect(workerNode
.workerUsage
).toStrictEqual({
929 executed
: expect
.any(Number
),
935 aggregate
: expect
.any(Number
),
936 average
: expect
.any(Number
),
938 history
: expect
.any(CircularArray
)
944 history
: expect
.any(CircularArray
)
948 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
949 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
952 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThanOrEqual(0)
953 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
956 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
957 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
958 ).defaultWorkerWeight
961 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
962 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
963 ).workerVirtualTaskRunTime
964 ).toBeGreaterThanOrEqual(0)
965 // We need to clean up the resources after our test
969 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
970 const pool
= new DynamicThreadPool(
973 './tests/worker-files/thread/testWorker.js',
974 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
976 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
977 const promises
= new Set()
978 const maxMultiplier
= 2
979 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
980 promises
.add(pool
.execute())
982 await Promise
.all(promises
)
983 for (const workerNode
of pool
.workerNodes
) {
984 expect(workerNode
.workerUsage
).toStrictEqual({
986 executed
: expect
.any(Number
),
992 aggregate
: expect
.any(Number
),
993 average
: expect
.any(Number
),
995 history
: expect
.any(CircularArray
)
1001 history
: expect
.any(CircularArray
)
1005 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1006 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1009 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
1010 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1013 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1014 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1015 ).defaultWorkerWeight
1016 ).toBeGreaterThan(0)
1018 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1019 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1020 ).workerVirtualTaskRunTime
1021 ).toBeGreaterThanOrEqual(0)
1022 // We need to clean up the resources after our test
1023 await pool
.destroy()
1026 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1027 const pool
= new DynamicThreadPool(
1030 './tests/worker-files/thread/testWorker.js',
1032 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1033 workerChoiceStrategyOptions
: {
1034 runTime
: { median
: true }
1038 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1039 const promises
= new Set()
1040 const maxMultiplier
= 2
1041 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1042 promises
.add(pool
.execute())
1044 await Promise
.all(promises
)
1045 for (const workerNode
of pool
.workerNodes
) {
1046 expect(workerNode
.workerUsage
).toStrictEqual({
1048 executed
: expect
.any(Number
),
1054 aggregate
: expect
.any(Number
),
1056 median
: expect
.any(Number
),
1057 history
: expect
.any(CircularArray
)
1063 history
: expect
.any(CircularArray
)
1067 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1068 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1071 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
1072 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1075 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1076 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1077 ).defaultWorkerWeight
1078 ).toBeGreaterThan(0)
1080 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1081 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1082 ).workerVirtualTaskRunTime
1083 ).toBeGreaterThanOrEqual(0)
1084 // We need to clean up the resources after our test
1085 await pool
.destroy()
1088 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1089 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1090 let pool
= new FixedThreadPool(
1092 './tests/worker-files/thread/testWorker.js'
1095 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1096 workerChoiceStrategy
1097 ).currentWorkerNodeId
1100 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1101 workerChoiceStrategy
1102 ).defaultWorkerWeight
1105 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1106 workerChoiceStrategy
1107 ).workerVirtualTaskRunTime
1109 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1111 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1112 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1113 ).currentWorkerNodeId
1116 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1117 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1118 ).defaultWorkerWeight
1119 ).toBeGreaterThan(0)
1121 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1122 workerChoiceStrategy
1123 ).workerVirtualTaskRunTime
1125 await pool
.destroy()
1126 pool
= new DynamicThreadPool(
1129 './tests/worker-files/thread/testWorker.js'
1132 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1133 workerChoiceStrategy
1134 ).currentWorkerNodeId
1137 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1138 workerChoiceStrategy
1139 ).defaultWorkerWeight
1142 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1143 workerChoiceStrategy
1144 ).workerVirtualTaskRunTime
1146 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1148 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1149 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1150 ).currentWorkerNodeId
1153 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1154 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1155 ).defaultWorkerWeight
1156 ).toBeGreaterThan(0)
1158 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1159 workerChoiceStrategy
1160 ).workerVirtualTaskRunTime
1162 // We need to clean up the resources after our test
1163 await pool
.destroy()
1166 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1167 const workerChoiceStrategy
=
1168 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1169 let pool
= new FixedThreadPool(
1171 './tests/worker-files/thread/testWorker.js',
1172 { workerChoiceStrategy
}
1175 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1189 await pool
.destroy()
1190 pool
= new DynamicThreadPool(
1193 './tests/worker-files/thread/testWorker.js',
1194 { workerChoiceStrategy
}
1197 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1211 // We need to clean up the resources after our test
1212 await pool
.destroy()
1215 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1216 const pool
= new FixedThreadPool(
1218 './tests/worker-files/thread/testWorker.js',
1220 workerChoiceStrategy
:
1221 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1224 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1225 const promises
= new Set()
1226 const maxMultiplier
= 2
1227 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1228 promises
.add(pool
.execute())
1230 await Promise
.all(promises
)
1231 for (const workerNode
of pool
.workerNodes
) {
1232 expect(workerNode
.workerUsage
).toStrictEqual({
1234 executed
: maxMultiplier
,
1243 history
: expect
.any(CircularArray
)
1249 history
: expect
.any(CircularArray
)
1255 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1256 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1257 ).defaultWorkerWeight
1258 ).toBeGreaterThan(0)
1260 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1261 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1265 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1266 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1267 ).currentWorkerNodeId
1270 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1271 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1274 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1275 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1276 ).defaultWorkerWeight
1278 // We need to clean up the resources after our test
1279 await pool
.destroy()
1282 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1283 const pool
= new DynamicThreadPool(
1286 './tests/worker-files/thread/testWorker.js',
1288 workerChoiceStrategy
:
1289 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1292 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1293 const promises
= new Set()
1294 const maxMultiplier
= 2
1295 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1296 promises
.add(pool
.execute())
1298 await Promise
.all(promises
)
1299 for (const workerNode
of pool
.workerNodes
) {
1300 expect(workerNode
.workerUsage
).toStrictEqual({
1302 executed
: maxMultiplier
,
1311 history
: expect
.any(CircularArray
)
1317 history
: expect
.any(CircularArray
)
1323 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1324 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1325 ).defaultWorkerWeight
1326 ).toBeGreaterThan(0)
1328 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1329 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1333 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1334 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1335 ).currentWorkerNodeId
1338 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1339 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1342 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1343 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1344 ).defaultWorkerWeight
1346 // We need to clean up the resources after our test
1347 await pool
.destroy()
1350 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1351 const workerChoiceStrategy
=
1352 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1353 let pool
= new FixedThreadPool(
1355 './tests/worker-files/thread/testWorker.js'
1358 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1359 workerChoiceStrategy
1363 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1364 workerChoiceStrategy
1365 ).currentWorkerNodeId
1368 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1369 workerChoiceStrategy
1370 ).defaultWorkerWeight
1373 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1374 workerChoiceStrategy
1377 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1379 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1380 workerChoiceStrategy
1384 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1385 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1386 ).currentWorkerNodeId
1389 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1390 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1391 ).defaultWorkerWeight
1392 ).toBeGreaterThan(0)
1394 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1395 workerChoiceStrategy
1398 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1399 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1400 ).defaultWorkerWeight
1402 await pool
.destroy()
1403 pool
= new DynamicThreadPool(
1406 './tests/worker-files/thread/testWorker.js'
1409 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1410 workerChoiceStrategy
1414 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1415 workerChoiceStrategy
1416 ).currentWorkerNodeId
1419 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1420 workerChoiceStrategy
1421 ).defaultWorkerWeight
1424 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1425 workerChoiceStrategy
1428 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1430 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1431 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1432 ).currentWorkerNodeId
1435 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1436 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1437 ).defaultWorkerWeight
1438 ).toBeGreaterThan(0)
1440 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1441 workerChoiceStrategy
1444 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1445 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1446 ).defaultWorkerWeight
1448 // We need to clean up the resources after our test
1449 await pool
.destroy()
1452 it('Verify unknown strategy throw error', () => {
1455 new DynamicThreadPool(
1458 './tests/worker-files/thread/testWorker.js',
1459 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1461 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")