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()
138 pool
= new DynamicThreadPool(
141 './tests/worker-files/thread/testWorker.js',
142 { workerChoiceStrategy
}
145 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
155 // We need to clean up the resources after our test
159 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
160 const pool
= new FixedThreadPool(
162 './tests/worker-files/thread/testWorker.js',
163 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
165 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
166 const promises
= new Set()
167 const maxMultiplier
= 2
168 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
169 promises
.add(pool
.execute())
171 await Promise
.all(promises
)
172 for (const workerNode
of pool
.workerNodes
) {
173 expect(workerNode
.workerUsage
).toStrictEqual({
175 executed
: maxMultiplier
,
184 history
: expect
.any(CircularArray
)
190 history
: expect
.any(CircularArray
)
196 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
197 WorkerChoiceStrategies
.ROUND_ROBIN
200 // We need to clean up the resources after our test
204 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
205 const pool
= new DynamicThreadPool(
208 './tests/worker-files/thread/testWorker.js',
209 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
211 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
212 const promises
= new Set()
213 const maxMultiplier
= 2
214 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
215 promises
.add(pool
.execute())
217 await Promise
.all(promises
)
218 for (const workerNode
of pool
.workerNodes
) {
219 expect(workerNode
.workerUsage
).toStrictEqual({
221 executed
: maxMultiplier
,
230 history
: expect
.any(CircularArray
)
236 history
: expect
.any(CircularArray
)
242 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
243 WorkerChoiceStrategies
.ROUND_ROBIN
246 // We need to clean up the resources after our test
250 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
251 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
252 let pool
= new FixedClusterPool(
254 './tests/worker-files/cluster/testWorker.js',
255 { workerChoiceStrategy
}
257 let results
= new Set()
258 for (let i
= 0; i
< max
; i
++) {
259 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
261 expect(results
.size
).toBe(max
)
263 pool
= new FixedThreadPool(
265 './tests/worker-files/thread/testWorker.js',
266 { workerChoiceStrategy
}
269 for (let i
= 0; i
< max
; i
++) {
270 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
272 expect(results
.size
).toBe(max
)
276 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
277 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
278 let pool
= new FixedThreadPool(
280 './tests/worker-files/thread/testWorker.js',
281 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
284 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
288 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
290 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
291 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
295 pool
= new DynamicThreadPool(
298 './tests/worker-files/thread/testWorker.js',
299 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
302 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
306 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
308 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
309 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
312 // We need to clean up the resources after our test
316 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
317 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
318 let pool
= new FixedThreadPool(
320 './tests/worker-files/thread/testWorker.js',
321 { workerChoiceStrategy
}
324 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
335 pool
= new DynamicThreadPool(
338 './tests/worker-files/thread/testWorker.js',
339 { workerChoiceStrategy
}
342 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
352 // We need to clean up the resources after our test
356 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
357 const pool
= new FixedThreadPool(
359 './tests/worker-files/thread/testWorker.js',
360 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
362 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
363 const promises
= new Set()
364 const maxMultiplier
= 2
365 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
366 promises
.add(pool
.execute())
368 await Promise
.all(promises
)
369 for (const workerNode
of pool
.workerNodes
) {
370 expect(workerNode
.workerUsage
).toStrictEqual({
372 executed
: maxMultiplier
,
381 history
: expect
.any(CircularArray
)
387 history
: expect
.any(CircularArray
)
392 // We need to clean up the resources after our test
396 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
397 const pool
= new DynamicThreadPool(
400 './tests/worker-files/thread/testWorker.js',
401 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
403 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
404 const promises
= new Set()
405 const maxMultiplier
= 2
406 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
407 promises
.add(pool
.execute())
409 await Promise
.all(promises
)
410 for (const workerNode
of pool
.workerNodes
) {
411 expect(workerNode
.workerUsage
).toStrictEqual({
413 executed
: maxMultiplier
,
422 history
: expect
.any(CircularArray
)
428 history
: expect
.any(CircularArray
)
434 // We need to clean up the resources after our test
438 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
439 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
440 let pool
= new FixedThreadPool(
442 './tests/worker-files/thread/testWorker.js',
443 { workerChoiceStrategy
}
446 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
457 pool
= new DynamicThreadPool(
460 './tests/worker-files/thread/testWorker.js',
461 { workerChoiceStrategy
}
464 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
474 // We need to clean up the resources after our test
478 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
479 const pool
= new FixedThreadPool(
481 './tests/worker-files/thread/testWorker.js',
482 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
484 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
485 const promises
= new Set()
486 const maxMultiplier
= 2
487 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
488 promises
.add(pool
.execute())
490 await Promise
.all(promises
)
491 for (const workerNode
of pool
.workerNodes
) {
492 expect(workerNode
.workerUsage
).toStrictEqual({
494 executed
: expect
.any(Number
),
500 aggregation
: expect
.any(Number
),
503 history
: expect
.any(CircularArray
)
506 aggregation
: expect
.any(Number
),
509 history
: expect
.any(CircularArray
)
513 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
514 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
517 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
521 workerNode
.workerUsage
.waitTime
.aggregation
522 ).toBeGreaterThanOrEqual(0)
524 // We need to clean up the resources after our test
528 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
529 const pool
= new DynamicThreadPool(
532 './tests/worker-files/thread/testWorker.js',
533 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
535 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
536 const promises
= new Set()
537 const maxMultiplier
= 2
538 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
539 promises
.add(pool
.execute())
541 await Promise
.all(promises
)
542 for (const workerNode
of pool
.workerNodes
) {
543 expect(workerNode
.workerUsage
).toStrictEqual({
545 executed
: expect
.any(Number
),
551 aggregation
: expect
.any(Number
),
554 history
: expect
.any(CircularArray
)
557 aggregation
: expect
.any(Number
),
560 history
: expect
.any(CircularArray
)
564 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
565 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
568 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
569 expect(workerNode
.workerUsage
.waitTime
.aggregation
).toBeGreaterThan(0)
571 // We need to clean up the resources after our test
575 it('Verify LEAST_ELU strategy default tasks usage statistics requirements', async () => {
576 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
577 let pool
= new FixedThreadPool(
579 './tests/worker-files/thread/testWorker.js',
580 { workerChoiceStrategy
}
583 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
594 pool
= new DynamicThreadPool(
597 './tests/worker-files/thread/testWorker.js',
598 { workerChoiceStrategy
}
601 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
611 // We need to clean up the resources after our test
615 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
616 const pool
= new FixedThreadPool(
618 './tests/worker-files/thread/testWorker.js',
619 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
621 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
622 const maxMultiplier
= 2
623 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
625 if (i
!== max
* maxMultiplier
- 1) await TestUtils
.sleep(500)
627 for (const workerNode
of pool
.workerNodes
) {
628 const expectedWorkerUsage
= {
630 executed
: expect
.any(Number
),
639 history
: expect
.any(CircularArray
)
645 history
: expect
.any(CircularArray
)
648 if (workerNode
.workerUsage
.elu
=== undefined) {
649 expect(workerNode
.workerUsage
).toStrictEqual({
650 ...expectedWorkerUsage
,
654 expect(workerNode
.workerUsage
).toStrictEqual({
655 ...expectedWorkerUsage
,
657 active
: expect
.any(Number
),
663 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
664 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
668 // We need to clean up the resources after our test
672 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
673 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
674 let pool
= new FixedThreadPool(
676 './tests/worker-files/thread/testWorker.js',
677 { workerChoiceStrategy
}
680 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
691 pool
= new DynamicThreadPool(
694 './tests/worker-files/thread/testWorker.js',
695 { workerChoiceStrategy
}
698 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
708 // We need to clean up the resources after our test
712 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
713 const pool
= new FixedThreadPool(
715 './tests/worker-files/thread/testWorker.js',
716 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
718 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
719 const promises
= new Set()
720 const maxMultiplier
= 2
721 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
722 promises
.add(pool
.execute())
724 await Promise
.all(promises
)
725 for (const workerNode
of pool
.workerNodes
) {
726 expect(workerNode
.workerUsage
).toStrictEqual({
728 executed
: maxMultiplier
,
734 aggregation
: expect
.any(Number
),
735 average
: expect
.any(Number
),
737 history
: expect
.any(CircularArray
)
743 history
: expect
.any(CircularArray
)
747 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
748 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
751 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
752 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
753 ).workersVirtualTaskEndTimestamp
.length
754 ).toBe(pool
.workerNodes
.length
)
755 // We need to clean up the resources after our test
759 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
760 const pool
= new DynamicThreadPool(
763 './tests/worker-files/thread/testWorker.js',
764 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
766 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
767 const promises
= new Set()
768 const maxMultiplier
= 2
769 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
770 promises
.add(pool
.execute())
772 await Promise
.all(promises
)
773 for (const workerNode
of pool
.workerNodes
) {
774 expect(workerNode
.workerUsage
).toStrictEqual({
776 executed
: maxMultiplier
,
782 aggregation
: expect
.any(Number
),
783 average
: expect
.any(Number
),
785 history
: expect
.any(CircularArray
)
791 history
: expect
.any(CircularArray
)
795 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
796 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
799 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
800 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
801 ).workersVirtualTaskEndTimestamp
.length
802 ).toBe(pool
.workerNodes
.length
)
803 // We need to clean up the resources after our test
807 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
808 const pool
= new DynamicThreadPool(
811 './tests/worker-files/thread/testWorker.js',
813 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
814 workerChoiceStrategyOptions
: {
819 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
820 const promises
= new Set()
821 const maxMultiplier
= 2
822 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
823 promises
.add(pool
.execute())
825 await Promise
.all(promises
)
826 for (const workerNode
of pool
.workerNodes
) {
827 expect(workerNode
.workerUsage
).toStrictEqual({
829 executed
: maxMultiplier
,
835 aggregation
: expect
.any(Number
),
837 median
: expect
.any(Number
),
838 history
: expect
.any(CircularArray
)
844 history
: expect
.any(CircularArray
)
848 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
849 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
852 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
853 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
854 ).workersVirtualTaskEndTimestamp
.length
855 ).toBe(pool
.workerNodes
.length
)
856 // We need to clean up the resources after our test
860 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
861 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
862 let pool
= new FixedThreadPool(
864 './tests/worker-files/thread/testWorker.js'
867 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
869 ).workersVirtualTaskEndTimestamp
870 ).toBeInstanceOf(Array
)
872 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
874 ).workersVirtualTaskEndTimestamp
.length
876 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
878 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
880 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
882 ).workersVirtualTaskEndTimestamp
.length
884 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
886 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
888 ).workersVirtualTaskEndTimestamp
889 ).toBeInstanceOf(Array
)
891 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
893 ).workersVirtualTaskEndTimestamp
.length
896 pool
= new DynamicThreadPool(
899 './tests/worker-files/thread/testWorker.js'
902 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
904 ).workersVirtualTaskEndTimestamp
905 ).toBeInstanceOf(Array
)
907 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
909 ).workersVirtualTaskEndTimestamp
.length
911 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
913 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
915 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
917 ).workersVirtualTaskEndTimestamp
.length
919 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
921 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
923 ).workersVirtualTaskEndTimestamp
924 ).toBeInstanceOf(Array
)
926 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
928 ).workersVirtualTaskEndTimestamp
.length
930 // We need to clean up the resources after our test
934 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
935 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
936 let pool
= new FixedThreadPool(
938 './tests/worker-files/thread/testWorker.js',
939 { workerChoiceStrategy
}
942 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
953 pool
= new DynamicThreadPool(
956 './tests/worker-files/thread/testWorker.js',
957 { workerChoiceStrategy
}
960 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
970 // We need to clean up the resources after our test
974 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
975 const pool
= new FixedThreadPool(
977 './tests/worker-files/thread/testWorker.js',
978 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
980 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
981 const promises
= new Set()
982 const maxMultiplier
= 2
983 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
984 promises
.add(pool
.execute())
986 await Promise
.all(promises
)
987 for (const workerNode
of pool
.workerNodes
) {
988 expect(workerNode
.workerUsage
).toStrictEqual({
990 executed
: expect
.any(Number
),
996 aggregation
: expect
.any(Number
),
997 average
: expect
.any(Number
),
999 history
: expect
.any(CircularArray
)
1005 history
: expect
.any(CircularArray
)
1009 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1010 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1013 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
1016 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
1019 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1020 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1021 ).defaultWorkerWeight
1022 ).toBeGreaterThan(0)
1024 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1025 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1026 ).workerVirtualTaskRunTime
1027 ).toBeGreaterThanOrEqual(0)
1028 // We need to clean up the resources after our test
1029 await pool
.destroy()
1032 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1033 const pool
= new DynamicThreadPool(
1036 './tests/worker-files/thread/testWorker.js',
1037 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1039 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1040 const promises
= new Set()
1041 const maxMultiplier
= 2
1042 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1043 promises
.add(pool
.execute())
1045 await Promise
.all(promises
)
1046 for (const workerNode
of pool
.workerNodes
) {
1047 expect(workerNode
.workerUsage
).toStrictEqual({
1049 executed
: expect
.any(Number
),
1055 aggregation
: expect
.any(Number
),
1056 average
: expect
.any(Number
),
1058 history
: expect
.any(CircularArray
)
1064 history
: expect
.any(CircularArray
)
1068 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1069 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1072 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1073 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
1076 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1077 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1078 ).defaultWorkerWeight
1079 ).toBeGreaterThan(0)
1081 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1082 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1083 ).workerVirtualTaskRunTime
1084 ).toBeGreaterThanOrEqual(0)
1085 // We need to clean up the resources after our test
1086 await pool
.destroy()
1089 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1090 const pool
= new DynamicThreadPool(
1093 './tests/worker-files/thread/testWorker.js',
1095 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1096 workerChoiceStrategyOptions
: {
1101 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1102 const promises
= new Set()
1103 const maxMultiplier
= 2
1104 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1105 promises
.add(pool
.execute())
1107 await Promise
.all(promises
)
1108 for (const workerNode
of pool
.workerNodes
) {
1109 expect(workerNode
.workerUsage
).toStrictEqual({
1111 executed
: expect
.any(Number
),
1117 aggregation
: expect
.any(Number
),
1119 median
: expect
.any(Number
),
1120 history
: expect
.any(CircularArray
)
1126 history
: expect
.any(CircularArray
)
1130 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1131 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1134 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1135 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1138 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1139 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1140 ).defaultWorkerWeight
1141 ).toBeGreaterThan(0)
1143 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1144 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1145 ).workerVirtualTaskRunTime
1146 ).toBeGreaterThanOrEqual(0)
1147 // We need to clean up the resources after our test
1148 await pool
.destroy()
1151 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1152 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1153 let pool
= new FixedThreadPool(
1155 './tests/worker-files/thread/testWorker.js'
1158 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1159 workerChoiceStrategy
1160 ).currentWorkerNodeId
1163 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1164 workerChoiceStrategy
1165 ).defaultWorkerWeight
1168 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1169 workerChoiceStrategy
1170 ).workerVirtualTaskRunTime
1172 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1174 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1175 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1176 ).currentWorkerNodeId
1179 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1180 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1181 ).defaultWorkerWeight
1182 ).toBeGreaterThan(0)
1184 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1185 workerChoiceStrategy
1186 ).workerVirtualTaskRunTime
1188 await pool
.destroy()
1189 pool
= new DynamicThreadPool(
1192 './tests/worker-files/thread/testWorker.js'
1195 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1196 workerChoiceStrategy
1197 ).currentWorkerNodeId
1200 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1201 workerChoiceStrategy
1202 ).defaultWorkerWeight
1205 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1206 workerChoiceStrategy
1207 ).workerVirtualTaskRunTime
1209 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1211 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1212 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1213 ).currentWorkerNodeId
1216 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1217 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1218 ).defaultWorkerWeight
1219 ).toBeGreaterThan(0)
1221 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1222 workerChoiceStrategy
1223 ).workerVirtualTaskRunTime
1225 // We need to clean up the resources after our test
1226 await pool
.destroy()
1229 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1230 const workerChoiceStrategy
=
1231 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1232 let pool
= new FixedThreadPool(
1234 './tests/worker-files/thread/testWorker.js',
1235 { workerChoiceStrategy
}
1238 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1248 await pool
.destroy()
1249 pool
= new DynamicThreadPool(
1252 './tests/worker-files/thread/testWorker.js',
1253 { workerChoiceStrategy
}
1256 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1266 // We need to clean up the resources after our test
1267 await pool
.destroy()
1270 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1271 const pool
= new FixedThreadPool(
1273 './tests/worker-files/thread/testWorker.js',
1275 workerChoiceStrategy
:
1276 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1279 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1280 const promises
= new Set()
1281 const maxMultiplier
= 2
1282 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1283 promises
.add(pool
.execute())
1285 await Promise
.all(promises
)
1286 for (const workerNode
of pool
.workerNodes
) {
1287 expect(workerNode
.workerUsage
).toStrictEqual({
1289 executed
: maxMultiplier
,
1298 history
: expect
.any(CircularArray
)
1304 history
: expect
.any(CircularArray
)
1310 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1311 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1312 ).defaultWorkerWeight
1313 ).toBeGreaterThan(0)
1315 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1316 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1320 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1321 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1322 ).currentWorkerNodeId
1325 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1326 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1329 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1330 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1331 ).defaultWorkerWeight
1333 // We need to clean up the resources after our test
1334 await pool
.destroy()
1337 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1338 const pool
= new DynamicThreadPool(
1341 './tests/worker-files/thread/testWorker.js',
1343 workerChoiceStrategy
:
1344 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1347 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1348 const promises
= new Set()
1349 const maxMultiplier
= 2
1350 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1351 promises
.add(pool
.execute())
1353 await Promise
.all(promises
)
1354 for (const workerNode
of pool
.workerNodes
) {
1355 expect(workerNode
.workerUsage
).toStrictEqual({
1357 executed
: maxMultiplier
,
1366 history
: expect
.any(CircularArray
)
1372 history
: expect
.any(CircularArray
)
1378 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1379 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1380 ).defaultWorkerWeight
1381 ).toBeGreaterThan(0)
1383 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1384 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1388 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1389 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1390 ).currentWorkerNodeId
1393 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1394 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1397 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1398 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1399 ).defaultWorkerWeight
1401 // We need to clean up the resources after our test
1402 await pool
.destroy()
1405 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1406 const workerChoiceStrategy
=
1407 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1408 let pool
= new FixedThreadPool(
1410 './tests/worker-files/thread/testWorker.js'
1413 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1414 workerChoiceStrategy
1418 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1419 workerChoiceStrategy
1420 ).currentWorkerNodeId
1423 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1424 workerChoiceStrategy
1425 ).defaultWorkerWeight
1428 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1429 workerChoiceStrategy
1432 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1434 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1435 workerChoiceStrategy
1439 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1440 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1441 ).currentWorkerNodeId
1444 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1445 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1446 ).defaultWorkerWeight
1447 ).toBeGreaterThan(0)
1449 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1450 workerChoiceStrategy
1453 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1454 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1455 ).defaultWorkerWeight
1457 await pool
.destroy()
1458 pool
= new DynamicThreadPool(
1461 './tests/worker-files/thread/testWorker.js'
1464 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1465 workerChoiceStrategy
1469 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1470 workerChoiceStrategy
1471 ).currentWorkerNodeId
1474 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1475 workerChoiceStrategy
1476 ).defaultWorkerWeight
1479 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1480 workerChoiceStrategy
1483 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1485 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1486 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1487 ).currentWorkerNodeId
1490 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1491 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1492 ).defaultWorkerWeight
1493 ).toBeGreaterThan(0)
1495 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1496 workerChoiceStrategy
1499 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1500 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1501 ).defaultWorkerWeight
1503 // We need to clean up the resources after our test
1504 await pool
.destroy()
1507 it('Verify unknown strategy throw error', () => {
1510 new DynamicThreadPool(
1513 './tests/worker-files/thread/testWorker.js',
1514 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1516 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")