1 const { expect
} = require('expect')
3 WorkerChoiceStrategies
,
7 } = require('../../../lib')
8 const { CircularArray
} = require('../../../lib/circular-array')
9 const TestUtils
= require('../../test-utils')
11 describe('Selection strategies test suite', () => {
15 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
16 expect(WorkerChoiceStrategies
.ROUND_ROBIN
).toBe('ROUND_ROBIN')
17 expect(WorkerChoiceStrategies
.LEAST_USED
).toBe('LEAST_USED')
18 expect(WorkerChoiceStrategies
.LEAST_BUSY
).toBe('LEAST_BUSY')
19 expect(WorkerChoiceStrategies
.LEAST_ELU
).toBe('LEAST_ELU')
20 expect(WorkerChoiceStrategies
.FAIR_SHARE
).toBe('FAIR_SHARE')
21 expect(WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
).toBe(
22 'WEIGHTED_ROUND_ROBIN'
24 expect(WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
).toBe(
25 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'
29 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
30 const pool
= new DynamicThreadPool(
33 './tests/worker-files/thread/testWorker.js'
35 expect(pool
.opts
.workerChoiceStrategy
).toBe(
36 WorkerChoiceStrategies
.ROUND_ROBIN
38 // We need to clean up the resources after our test
42 it('Verify available strategies are taken at pool creation', async () => {
43 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
44 const pool
= new FixedThreadPool(
46 './tests/worker-files/thread/testWorker.js',
47 { workerChoiceStrategy
}
49 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
50 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
57 it('Verify available strategies can be set after pool creation', async () => {
58 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
59 const pool
= new DynamicThreadPool(
62 './tests/worker-files/thread/testWorker.js'
64 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
65 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
66 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
73 it('Verify available strategies default internals at pool creation', async () => {
74 const pool
= new FixedThreadPool(
76 './tests/worker-files/thread/testWorker.js'
78 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
79 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.ROUND_ROBIN
) {
81 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
85 } else if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
87 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
89 ).workersVirtualTaskEndTimestamp
90 ).toBeInstanceOf(Array
)
92 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
94 ).workersVirtualTaskEndTimestamp
.length
97 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
100 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
102 ).currentWorkerNodeId
105 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
107 ).defaultWorkerWeight
110 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
112 ).workerVirtualTaskRunTime
119 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
120 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
121 let pool
= new FixedThreadPool(
123 './tests/worker-files/thread/testWorker.js',
124 { workerChoiceStrategy
}
127 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
142 pool
= new DynamicThreadPool(
145 './tests/worker-files/thread/testWorker.js',
146 { workerChoiceStrategy
}
149 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
163 // We need to clean up the resources after our test
167 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
168 const pool
= new FixedThreadPool(
170 './tests/worker-files/thread/testWorker.js',
171 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
173 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
174 const promises
= new Set()
175 const maxMultiplier
= 2
176 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
177 promises
.add(pool
.execute())
179 await Promise
.all(promises
)
180 for (const workerNode
of pool
.workerNodes
) {
181 expect(workerNode
.workerUsage
).toStrictEqual({
183 executed
: maxMultiplier
,
192 history
: expect
.any(CircularArray
)
198 history
: expect
.any(CircularArray
)
204 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
205 WorkerChoiceStrategies
.ROUND_ROBIN
208 // We need to clean up the resources after our test
212 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
213 const pool
= new DynamicThreadPool(
216 './tests/worker-files/thread/testWorker.js',
217 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
219 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
220 const promises
= new Set()
221 const maxMultiplier
= 2
222 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
223 promises
.add(pool
.execute())
225 await Promise
.all(promises
)
226 for (const workerNode
of pool
.workerNodes
) {
227 expect(workerNode
.workerUsage
).toStrictEqual({
229 executed
: maxMultiplier
,
238 history
: expect
.any(CircularArray
)
244 history
: expect
.any(CircularArray
)
250 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
251 WorkerChoiceStrategies
.ROUND_ROBIN
254 // We need to clean up the resources after our test
258 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
259 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
260 let pool
= new FixedClusterPool(
262 './tests/worker-files/cluster/testWorker.js',
263 { workerChoiceStrategy
}
265 let results
= new Set()
266 for (let i
= 0; i
< max
; i
++) {
267 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
269 expect(results
.size
).toBe(max
)
271 pool
= new FixedThreadPool(
273 './tests/worker-files/thread/testWorker.js',
274 { workerChoiceStrategy
}
277 for (let i
= 0; i
< max
; i
++) {
278 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
280 expect(results
.size
).toBe(max
)
284 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
285 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
286 let pool
= new FixedThreadPool(
288 './tests/worker-files/thread/testWorker.js',
289 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
292 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
296 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
298 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
299 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
303 pool
= new DynamicThreadPool(
306 './tests/worker-files/thread/testWorker.js',
307 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
310 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
314 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
316 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
317 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
320 // We need to clean up the resources after our test
324 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
325 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
326 let pool
= new FixedThreadPool(
328 './tests/worker-files/thread/testWorker.js',
329 { workerChoiceStrategy
}
332 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
347 pool
= new DynamicThreadPool(
350 './tests/worker-files/thread/testWorker.js',
351 { workerChoiceStrategy
}
354 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
368 // We need to clean up the resources after our test
372 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
373 const pool
= new FixedThreadPool(
375 './tests/worker-files/thread/testWorker.js',
376 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
378 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
379 const promises
= new Set()
380 const maxMultiplier
= 2
381 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
382 promises
.add(pool
.execute())
384 await Promise
.all(promises
)
385 for (const workerNode
of pool
.workerNodes
) {
386 expect(workerNode
.workerUsage
).toStrictEqual({
388 executed
: maxMultiplier
,
397 history
: expect
.any(CircularArray
)
403 history
: expect
.any(CircularArray
)
408 // We need to clean up the resources after our test
412 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
413 const pool
= new DynamicThreadPool(
416 './tests/worker-files/thread/testWorker.js',
417 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
419 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
420 const promises
= new Set()
421 const maxMultiplier
= 2
422 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
423 promises
.add(pool
.execute())
425 await Promise
.all(promises
)
426 for (const workerNode
of pool
.workerNodes
) {
427 expect(workerNode
.workerUsage
).toStrictEqual({
429 executed
: maxMultiplier
,
438 history
: expect
.any(CircularArray
)
444 history
: expect
.any(CircularArray
)
450 // We need to clean up the resources after our test
454 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
455 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
456 let pool
= new FixedThreadPool(
458 './tests/worker-files/thread/testWorker.js',
459 { workerChoiceStrategy
}
462 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
477 pool
= new DynamicThreadPool(
480 './tests/worker-files/thread/testWorker.js',
481 { workerChoiceStrategy
}
484 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
498 // We need to clean up the resources after our test
502 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
503 const pool
= new FixedThreadPool(
505 './tests/worker-files/thread/testWorker.js',
506 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
508 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
509 const promises
= new Set()
510 const maxMultiplier
= 2
511 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
512 promises
.add(pool
.execute())
514 await Promise
.all(promises
)
515 for (const workerNode
of pool
.workerNodes
) {
516 expect(workerNode
.workerUsage
).toStrictEqual({
518 executed
: expect
.any(Number
),
524 aggregate
: expect
.any(Number
),
527 history
: expect
.any(CircularArray
)
530 aggregate
: expect
.any(Number
),
533 history
: expect
.any(CircularArray
)
537 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
538 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
541 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThanOrEqual(0)
542 expect(workerNode
.workerUsage
.waitTime
.aggregate
).toBeGreaterThanOrEqual(
546 // We need to clean up the resources after our test
550 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
551 const pool
= new DynamicThreadPool(
554 './tests/worker-files/thread/testWorker.js',
555 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
557 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
558 const promises
= new Set()
559 const maxMultiplier
= 2
560 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
561 promises
.add(pool
.execute())
563 await Promise
.all(promises
)
564 for (const workerNode
of pool
.workerNodes
) {
565 expect(workerNode
.workerUsage
).toStrictEqual({
567 executed
: expect
.any(Number
),
573 aggregate
: expect
.any(Number
),
576 history
: expect
.any(CircularArray
)
579 aggregate
: expect
.any(Number
),
582 history
: expect
.any(CircularArray
)
586 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
587 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
590 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
591 expect(workerNode
.workerUsage
.waitTime
.aggregate
).toBeGreaterThan(0)
593 // We need to clean up the resources after our test
597 it('Verify LEAST_ELU strategy default tasks usage statistics requirements', async () => {
598 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
599 let pool
= new FixedThreadPool(
601 './tests/worker-files/thread/testWorker.js',
602 { workerChoiceStrategy
}
605 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
616 pool
= new DynamicThreadPool(
619 './tests/worker-files/thread/testWorker.js',
620 { workerChoiceStrategy
}
623 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
633 // We need to clean up the resources after our test
637 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
638 const pool
= new FixedThreadPool(
640 './tests/worker-files/thread/testWorker.js',
641 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
643 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
644 const maxMultiplier
= 2
645 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
647 if (i
!== max
* maxMultiplier
- 1) await TestUtils
.sleep(500)
649 for (const workerNode
of pool
.workerNodes
) {
650 const expectedWorkerUsage
= {
652 executed
: expect
.any(Number
),
661 history
: expect
.any(CircularArray
)
667 history
: expect
.any(CircularArray
)
670 if (workerNode
.workerUsage
.elu
=== undefined) {
671 expect(workerNode
.workerUsage
).toStrictEqual({
672 ...expectedWorkerUsage
,
676 expect(workerNode
.workerUsage
).toStrictEqual({
677 ...expectedWorkerUsage
,
679 active
: expect
.any(Number
),
685 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
686 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
690 // We need to clean up the resources after our test
694 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
695 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
696 let pool
= new FixedThreadPool(
698 './tests/worker-files/thread/testWorker.js',
699 { workerChoiceStrategy
}
702 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
717 pool
= new DynamicThreadPool(
720 './tests/worker-files/thread/testWorker.js',
721 { workerChoiceStrategy
}
724 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
738 // We need to clean up the resources after our test
742 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
743 const pool
= new FixedThreadPool(
745 './tests/worker-files/thread/testWorker.js',
746 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
748 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
749 const promises
= new Set()
750 const maxMultiplier
= 2
751 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
752 promises
.add(pool
.execute())
754 await Promise
.all(promises
)
755 for (const workerNode
of pool
.workerNodes
) {
756 expect(workerNode
.workerUsage
).toStrictEqual({
758 executed
: maxMultiplier
,
764 aggregate
: expect
.any(Number
),
765 average
: expect
.any(Number
),
767 history
: expect
.any(CircularArray
)
773 history
: expect
.any(CircularArray
)
777 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
778 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
781 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
782 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
783 ).workersVirtualTaskEndTimestamp
.length
784 ).toBe(pool
.workerNodes
.length
)
785 // We need to clean up the resources after our test
789 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
790 const pool
= new DynamicThreadPool(
793 './tests/worker-files/thread/testWorker.js',
794 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
796 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
797 const promises
= new Set()
798 const maxMultiplier
= 2
799 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
800 promises
.add(pool
.execute())
802 await Promise
.all(promises
)
803 for (const workerNode
of pool
.workerNodes
) {
804 expect(workerNode
.workerUsage
).toStrictEqual({
806 executed
: maxMultiplier
,
812 aggregate
: expect
.any(Number
),
813 average
: expect
.any(Number
),
815 history
: expect
.any(CircularArray
)
821 history
: expect
.any(CircularArray
)
825 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
826 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
829 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
830 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
831 ).workersVirtualTaskEndTimestamp
.length
832 ).toBe(pool
.workerNodes
.length
)
833 // We need to clean up the resources after our test
837 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
838 const pool
= new DynamicThreadPool(
841 './tests/worker-files/thread/testWorker.js',
843 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
844 workerChoiceStrategyOptions
: {
845 runTime
: { median
: true }
849 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
850 const promises
= new Set()
851 const maxMultiplier
= 2
852 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
853 promises
.add(pool
.execute())
855 await Promise
.all(promises
)
856 for (const workerNode
of pool
.workerNodes
) {
857 expect(workerNode
.workerUsage
).toStrictEqual({
859 executed
: maxMultiplier
,
865 aggregate
: expect
.any(Number
),
867 median
: expect
.any(Number
),
868 history
: expect
.any(CircularArray
)
874 history
: expect
.any(CircularArray
)
878 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
879 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
882 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
883 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
884 ).workersVirtualTaskEndTimestamp
.length
885 ).toBe(pool
.workerNodes
.length
)
886 // We need to clean up the resources after our test
890 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
891 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
892 let pool
= new FixedThreadPool(
894 './tests/worker-files/thread/testWorker.js'
897 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
899 ).workersVirtualTaskEndTimestamp
900 ).toBeInstanceOf(Array
)
902 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
904 ).workersVirtualTaskEndTimestamp
.length
906 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
908 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
910 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
912 ).workersVirtualTaskEndTimestamp
.length
914 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
916 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
918 ).workersVirtualTaskEndTimestamp
919 ).toBeInstanceOf(Array
)
921 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
923 ).workersVirtualTaskEndTimestamp
.length
926 pool
= new DynamicThreadPool(
929 './tests/worker-files/thread/testWorker.js'
932 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
934 ).workersVirtualTaskEndTimestamp
935 ).toBeInstanceOf(Array
)
937 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
939 ).workersVirtualTaskEndTimestamp
.length
941 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
943 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
945 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
947 ).workersVirtualTaskEndTimestamp
.length
949 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
951 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
953 ).workersVirtualTaskEndTimestamp
954 ).toBeInstanceOf(Array
)
956 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
958 ).workersVirtualTaskEndTimestamp
.length
960 // We need to clean up the resources after our test
964 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
965 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
966 let pool
= new FixedThreadPool(
968 './tests/worker-files/thread/testWorker.js',
969 { workerChoiceStrategy
}
972 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
987 pool
= new DynamicThreadPool(
990 './tests/worker-files/thread/testWorker.js',
991 { workerChoiceStrategy
}
994 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1008 // We need to clean up the resources after our test
1009 await pool
.destroy()
1012 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1013 const pool
= new FixedThreadPool(
1015 './tests/worker-files/thread/testWorker.js',
1016 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1018 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1019 const promises
= new Set()
1020 const maxMultiplier
= 2
1021 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1022 promises
.add(pool
.execute())
1024 await Promise
.all(promises
)
1025 for (const workerNode
of pool
.workerNodes
) {
1026 expect(workerNode
.workerUsage
).toStrictEqual({
1028 executed
: expect
.any(Number
),
1034 aggregate
: expect
.any(Number
),
1035 average
: expect
.any(Number
),
1037 history
: expect
.any(CircularArray
)
1043 history
: expect
.any(CircularArray
)
1047 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1048 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1051 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThanOrEqual(0)
1052 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
1055 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1056 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1057 ).defaultWorkerWeight
1058 ).toBeGreaterThan(0)
1060 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1061 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1062 ).workerVirtualTaskRunTime
1063 ).toBeGreaterThanOrEqual(0)
1064 // We need to clean up the resources after our test
1065 await pool
.destroy()
1068 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1069 const pool
= new DynamicThreadPool(
1072 './tests/worker-files/thread/testWorker.js',
1073 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1075 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1076 const promises
= new Set()
1077 const maxMultiplier
= 2
1078 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1079 promises
.add(pool
.execute())
1081 await Promise
.all(promises
)
1082 for (const workerNode
of pool
.workerNodes
) {
1083 expect(workerNode
.workerUsage
).toStrictEqual({
1085 executed
: expect
.any(Number
),
1091 aggregate
: expect
.any(Number
),
1092 average
: expect
.any(Number
),
1094 history
: expect
.any(CircularArray
)
1100 history
: expect
.any(CircularArray
)
1104 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1105 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1108 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
1109 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1112 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1113 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1114 ).defaultWorkerWeight
1115 ).toBeGreaterThan(0)
1117 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1118 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1119 ).workerVirtualTaskRunTime
1120 ).toBeGreaterThanOrEqual(0)
1121 // We need to clean up the resources after our test
1122 await pool
.destroy()
1125 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1126 const pool
= new DynamicThreadPool(
1129 './tests/worker-files/thread/testWorker.js',
1131 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1132 workerChoiceStrategyOptions
: {
1133 runTime
: { median
: true }
1137 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1138 const promises
= new Set()
1139 const maxMultiplier
= 2
1140 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1141 promises
.add(pool
.execute())
1143 await Promise
.all(promises
)
1144 for (const workerNode
of pool
.workerNodes
) {
1145 expect(workerNode
.workerUsage
).toStrictEqual({
1147 executed
: expect
.any(Number
),
1153 aggregate
: expect
.any(Number
),
1155 median
: expect
.any(Number
),
1156 history
: expect
.any(CircularArray
)
1162 history
: expect
.any(CircularArray
)
1166 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1167 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1170 expect(workerNode
.workerUsage
.runTime
.aggregate
).toBeGreaterThan(0)
1171 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1174 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1175 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1176 ).defaultWorkerWeight
1177 ).toBeGreaterThan(0)
1179 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1180 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1181 ).workerVirtualTaskRunTime
1182 ).toBeGreaterThanOrEqual(0)
1183 // We need to clean up the resources after our test
1184 await pool
.destroy()
1187 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1188 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1189 let pool
= new FixedThreadPool(
1191 './tests/worker-files/thread/testWorker.js'
1194 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1195 workerChoiceStrategy
1196 ).currentWorkerNodeId
1199 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1200 workerChoiceStrategy
1201 ).defaultWorkerWeight
1204 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1205 workerChoiceStrategy
1206 ).workerVirtualTaskRunTime
1208 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1210 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1211 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1212 ).currentWorkerNodeId
1215 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1216 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1217 ).defaultWorkerWeight
1218 ).toBeGreaterThan(0)
1220 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1221 workerChoiceStrategy
1222 ).workerVirtualTaskRunTime
1224 await pool
.destroy()
1225 pool
= new DynamicThreadPool(
1228 './tests/worker-files/thread/testWorker.js'
1231 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1232 workerChoiceStrategy
1233 ).currentWorkerNodeId
1236 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1237 workerChoiceStrategy
1238 ).defaultWorkerWeight
1241 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1242 workerChoiceStrategy
1243 ).workerVirtualTaskRunTime
1245 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1247 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1248 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1249 ).currentWorkerNodeId
1252 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1253 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1254 ).defaultWorkerWeight
1255 ).toBeGreaterThan(0)
1257 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1258 workerChoiceStrategy
1259 ).workerVirtualTaskRunTime
1261 // We need to clean up the resources after our test
1262 await pool
.destroy()
1265 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1266 const workerChoiceStrategy
=
1267 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1268 let pool
= new FixedThreadPool(
1270 './tests/worker-files/thread/testWorker.js',
1271 { workerChoiceStrategy
}
1274 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1288 await pool
.destroy()
1289 pool
= new DynamicThreadPool(
1292 './tests/worker-files/thread/testWorker.js',
1293 { workerChoiceStrategy
}
1296 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1310 // We need to clean up the resources after our test
1311 await pool
.destroy()
1314 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1315 const pool
= new FixedThreadPool(
1317 './tests/worker-files/thread/testWorker.js',
1319 workerChoiceStrategy
:
1320 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1323 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1324 const promises
= new Set()
1325 const maxMultiplier
= 2
1326 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1327 promises
.add(pool
.execute())
1329 await Promise
.all(promises
)
1330 for (const workerNode
of pool
.workerNodes
) {
1331 expect(workerNode
.workerUsage
).toStrictEqual({
1333 executed
: maxMultiplier
,
1342 history
: expect
.any(CircularArray
)
1348 history
: expect
.any(CircularArray
)
1354 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1355 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1356 ).defaultWorkerWeight
1357 ).toBeGreaterThan(0)
1359 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1360 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1364 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1365 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1366 ).currentWorkerNodeId
1369 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1370 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1373 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1374 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1375 ).defaultWorkerWeight
1377 // We need to clean up the resources after our test
1378 await pool
.destroy()
1381 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1382 const pool
= new DynamicThreadPool(
1385 './tests/worker-files/thread/testWorker.js',
1387 workerChoiceStrategy
:
1388 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1391 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1392 const promises
= new Set()
1393 const maxMultiplier
= 2
1394 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1395 promises
.add(pool
.execute())
1397 await Promise
.all(promises
)
1398 for (const workerNode
of pool
.workerNodes
) {
1399 expect(workerNode
.workerUsage
).toStrictEqual({
1401 executed
: maxMultiplier
,
1410 history
: expect
.any(CircularArray
)
1416 history
: expect
.any(CircularArray
)
1422 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1423 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1424 ).defaultWorkerWeight
1425 ).toBeGreaterThan(0)
1427 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1428 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1432 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1433 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1434 ).currentWorkerNodeId
1437 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1438 pool
.workerChoiceStrategyContext
.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 INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1450 const workerChoiceStrategy
=
1451 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1452 let pool
= new FixedThreadPool(
1454 './tests/worker-files/thread/testWorker.js'
1457 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1458 workerChoiceStrategy
1462 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1463 workerChoiceStrategy
1464 ).currentWorkerNodeId
1467 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1468 workerChoiceStrategy
1469 ).defaultWorkerWeight
1472 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1473 workerChoiceStrategy
1476 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1478 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1479 workerChoiceStrategy
1483 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1484 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1485 ).currentWorkerNodeId
1488 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1489 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1490 ).defaultWorkerWeight
1491 ).toBeGreaterThan(0)
1493 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1494 workerChoiceStrategy
1497 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1498 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1499 ).defaultWorkerWeight
1501 await pool
.destroy()
1502 pool
= new DynamicThreadPool(
1505 './tests/worker-files/thread/testWorker.js'
1508 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1509 workerChoiceStrategy
1513 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1514 workerChoiceStrategy
1515 ).currentWorkerNodeId
1518 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1519 workerChoiceStrategy
1520 ).defaultWorkerWeight
1523 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1524 workerChoiceStrategy
1527 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1529 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1530 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1531 ).currentWorkerNodeId
1534 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1535 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1536 ).defaultWorkerWeight
1537 ).toBeGreaterThan(0)
1539 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1540 workerChoiceStrategy
1543 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1544 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1545 ).defaultWorkerWeight
1547 // We need to clean up the resources after our test
1548 await pool
.destroy()
1551 it('Verify unknown strategy throw error', () => {
1554 new DynamicThreadPool(
1557 './tests/worker-files/thread/testWorker.js',
1558 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1560 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")