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
}
124 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
134 pool
= new DynamicThreadPool(
137 './tests/worker-files/thread/testWorker.js',
138 { workerChoiceStrategy
}
140 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
149 // We need to clean up the resources after our test
153 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
154 const pool
= new FixedThreadPool(
156 './tests/worker-files/thread/testWorker.js',
157 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
159 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
160 const promises
= new Set()
161 const maxMultiplier
= 2
162 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
163 promises
.add(pool
.execute())
165 await Promise
.all(promises
)
166 for (const workerNode
of pool
.workerNodes
) {
167 expect(workerNode
.workerUsage
).toStrictEqual({
169 executed
: maxMultiplier
,
178 history
: expect
.any(CircularArray
)
184 history
: expect
.any(CircularArray
)
190 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
191 WorkerChoiceStrategies
.ROUND_ROBIN
194 // We need to clean up the resources after our test
198 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
199 const pool
= new DynamicThreadPool(
202 './tests/worker-files/thread/testWorker.js',
203 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
205 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
206 const promises
= new Set()
207 const maxMultiplier
= 2
208 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
209 promises
.add(pool
.execute())
211 await Promise
.all(promises
)
212 for (const workerNode
of pool
.workerNodes
) {
213 expect(workerNode
.workerUsage
).toStrictEqual({
215 executed
: maxMultiplier
,
224 history
: expect
.any(CircularArray
)
230 history
: expect
.any(CircularArray
)
236 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
237 WorkerChoiceStrategies
.ROUND_ROBIN
240 // We need to clean up the resources after our test
244 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
245 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
246 let pool
= new FixedClusterPool(
248 './tests/worker-files/cluster/testWorker.js',
249 { workerChoiceStrategy
}
251 let results
= new Set()
252 for (let i
= 0; i
< max
; i
++) {
253 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
255 expect(results
.size
).toBe(max
)
257 pool
= new FixedThreadPool(
259 './tests/worker-files/thread/testWorker.js',
260 { workerChoiceStrategy
}
263 for (let i
= 0; i
< max
; i
++) {
264 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
266 expect(results
.size
).toBe(max
)
270 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
271 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
272 let pool
= new FixedThreadPool(
274 './tests/worker-files/thread/testWorker.js',
275 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
278 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
282 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
284 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
285 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
289 pool
= new DynamicThreadPool(
292 './tests/worker-files/thread/testWorker.js',
293 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
296 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
300 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
302 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
303 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
306 // We need to clean up the resources after our test
310 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
311 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
312 let pool
= new FixedThreadPool(
314 './tests/worker-files/thread/testWorker.js',
315 { workerChoiceStrategy
}
317 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
327 pool
= new DynamicThreadPool(
330 './tests/worker-files/thread/testWorker.js',
331 { workerChoiceStrategy
}
333 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
342 // We need to clean up the resources after our test
346 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
347 const pool
= new FixedThreadPool(
349 './tests/worker-files/thread/testWorker.js',
350 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
352 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
353 const promises
= new Set()
354 const maxMultiplier
= 2
355 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
356 promises
.add(pool
.execute())
358 await Promise
.all(promises
)
359 for (const workerNode
of pool
.workerNodes
) {
360 expect(workerNode
.workerUsage
).toStrictEqual({
362 executed
: maxMultiplier
,
371 history
: expect
.any(CircularArray
)
377 history
: expect
.any(CircularArray
)
382 // We need to clean up the resources after our test
386 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
387 const pool
= new DynamicThreadPool(
390 './tests/worker-files/thread/testWorker.js',
391 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
393 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
394 const promises
= new Set()
395 const maxMultiplier
= 2
396 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
397 promises
.add(pool
.execute())
399 await Promise
.all(promises
)
400 for (const workerNode
of pool
.workerNodes
) {
401 expect(workerNode
.workerUsage
).toStrictEqual({
403 executed
: maxMultiplier
,
412 history
: expect
.any(CircularArray
)
418 history
: expect
.any(CircularArray
)
424 // We need to clean up the resources after our test
428 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
429 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
430 let pool
= new FixedThreadPool(
432 './tests/worker-files/thread/testWorker.js',
433 { workerChoiceStrategy
}
435 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
445 pool
= new DynamicThreadPool(
448 './tests/worker-files/thread/testWorker.js',
449 { workerChoiceStrategy
}
451 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
460 // We need to clean up the resources after our test
464 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
465 const pool
= new FixedThreadPool(
467 './tests/worker-files/thread/testWorker.js',
468 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
470 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
471 const promises
= new Set()
472 const maxMultiplier
= 2
473 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
474 promises
.add(pool
.execute())
476 await Promise
.all(promises
)
477 for (const workerNode
of pool
.workerNodes
) {
478 expect(workerNode
.workerUsage
).toStrictEqual({
480 executed
: expect
.any(Number
),
486 aggregation
: expect
.any(Number
),
489 history
: expect
.any(CircularArray
)
495 history
: expect
.any(CircularArray
)
499 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
500 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
503 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
507 // We need to clean up the resources after our test
511 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
512 const pool
= new DynamicThreadPool(
515 './tests/worker-files/thread/testWorker.js',
516 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
518 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
519 const promises
= new Set()
520 const maxMultiplier
= 2
521 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
522 promises
.add(pool
.execute())
524 await Promise
.all(promises
)
525 for (const workerNode
of pool
.workerNodes
) {
526 expect(workerNode
.workerUsage
).toStrictEqual({
528 executed
: expect
.any(Number
),
534 aggregation
: expect
.any(Number
),
537 history
: expect
.any(CircularArray
)
543 history
: expect
.any(CircularArray
)
547 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
548 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
551 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
553 // We need to clean up the resources after our test
557 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
558 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
559 let pool
= new FixedThreadPool(
561 './tests/worker-files/thread/testWorker.js',
562 { workerChoiceStrategy
}
564 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
574 pool
= new DynamicThreadPool(
577 './tests/worker-files/thread/testWorker.js',
578 { workerChoiceStrategy
}
580 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
589 // We need to clean up the resources after our test
593 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
594 const pool
= new FixedThreadPool(
596 './tests/worker-files/thread/testWorker.js',
597 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
599 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
600 const promises
= new Set()
601 const maxMultiplier
= 2
602 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
603 promises
.add(pool
.execute())
605 await Promise
.all(promises
)
606 for (const workerNode
of pool
.workerNodes
) {
607 expect(workerNode
.workerUsage
).toStrictEqual({
609 executed
: maxMultiplier
,
615 aggregation
: expect
.any(Number
),
616 average
: expect
.any(Number
),
618 history
: expect
.any(CircularArray
)
624 history
: expect
.any(CircularArray
)
628 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
629 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
632 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
633 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
634 ).workersVirtualTaskEndTimestamp
.length
635 ).toBe(pool
.workerNodes
.length
)
636 // We need to clean up the resources after our test
640 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
641 const pool
= new DynamicThreadPool(
644 './tests/worker-files/thread/testWorker.js',
645 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
647 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
648 const promises
= new Set()
649 const maxMultiplier
= 2
650 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
651 promises
.add(pool
.execute())
653 await Promise
.all(promises
)
654 for (const workerNode
of pool
.workerNodes
) {
655 expect(workerNode
.workerUsage
).toStrictEqual({
657 executed
: maxMultiplier
,
663 aggregation
: expect
.any(Number
),
664 average
: expect
.any(Number
),
666 history
: expect
.any(CircularArray
)
672 history
: expect
.any(CircularArray
)
676 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
677 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
680 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
681 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
682 ).workersVirtualTaskEndTimestamp
.length
683 ).toBe(pool
.workerNodes
.length
)
684 // We need to clean up the resources after our test
688 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
689 const pool
= new DynamicThreadPool(
692 './tests/worker-files/thread/testWorker.js',
694 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
695 workerChoiceStrategyOptions
: {
700 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
701 const promises
= new Set()
702 const maxMultiplier
= 2
703 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
704 promises
.add(pool
.execute())
706 await Promise
.all(promises
)
707 for (const workerNode
of pool
.workerNodes
) {
708 expect(workerNode
.workerUsage
).toStrictEqual({
710 executed
: maxMultiplier
,
716 aggregation
: expect
.any(Number
),
718 median
: expect
.any(Number
),
719 history
: expect
.any(CircularArray
)
725 history
: expect
.any(CircularArray
)
729 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
730 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
733 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
734 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
735 ).workersVirtualTaskEndTimestamp
.length
736 ).toBe(pool
.workerNodes
.length
)
737 // We need to clean up the resources after our test
741 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
742 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
743 let pool
= new FixedThreadPool(
745 './tests/worker-files/thread/testWorker.js'
748 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
750 ).workersVirtualTaskEndTimestamp
751 ).toBeInstanceOf(Array
)
753 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
755 ).workersVirtualTaskEndTimestamp
.length
757 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
759 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
761 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
763 ).workersVirtualTaskEndTimestamp
.length
765 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
767 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
769 ).workersVirtualTaskEndTimestamp
770 ).toBeInstanceOf(Array
)
772 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
774 ).workersVirtualTaskEndTimestamp
.length
777 pool
= new DynamicThreadPool(
780 './tests/worker-files/thread/testWorker.js'
783 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
785 ).workersVirtualTaskEndTimestamp
786 ).toBeInstanceOf(Array
)
788 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
790 ).workersVirtualTaskEndTimestamp
.length
792 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
794 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
796 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
798 ).workersVirtualTaskEndTimestamp
.length
800 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
802 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
804 ).workersVirtualTaskEndTimestamp
805 ).toBeInstanceOf(Array
)
807 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
809 ).workersVirtualTaskEndTimestamp
.length
811 // We need to clean up the resources after our test
815 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
816 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
817 let pool
= new FixedThreadPool(
819 './tests/worker-files/thread/testWorker.js',
820 { workerChoiceStrategy
}
822 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
832 pool
= new DynamicThreadPool(
835 './tests/worker-files/thread/testWorker.js',
836 { workerChoiceStrategy
}
838 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
847 // We need to clean up the resources after our test
851 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
852 const pool
= new FixedThreadPool(
854 './tests/worker-files/thread/testWorker.js',
855 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
857 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
858 const promises
= new Set()
859 const maxMultiplier
= 2
860 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
861 promises
.add(pool
.execute())
863 await Promise
.all(promises
)
864 for (const workerNode
of pool
.workerNodes
) {
865 expect(workerNode
.workerUsage
).toStrictEqual({
867 executed
: expect
.any(Number
),
873 aggregation
: expect
.any(Number
),
874 average
: expect
.any(Number
),
876 history
: expect
.any(CircularArray
)
882 history
: expect
.any(CircularArray
)
886 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
887 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
890 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThanOrEqual(
893 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThanOrEqual(0)
896 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
897 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
898 ).defaultWorkerWeight
901 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
902 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
903 ).workerVirtualTaskRunTime
904 ).toBeGreaterThanOrEqual(0)
905 // We need to clean up the resources after our test
909 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
910 const pool
= new DynamicThreadPool(
913 './tests/worker-files/thread/testWorker.js',
914 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
916 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
917 const promises
= new Set()
918 const maxMultiplier
= 2
919 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
920 promises
.add(pool
.execute())
922 await Promise
.all(promises
)
923 for (const workerNode
of pool
.workerNodes
) {
924 expect(workerNode
.workerUsage
).toStrictEqual({
926 executed
: expect
.any(Number
),
932 aggregation
: expect
.any(Number
),
933 average
: expect
.any(Number
),
935 history
: expect
.any(CircularArray
)
941 history
: expect
.any(CircularArray
)
945 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
946 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
949 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
950 expect(workerNode
.workerUsage
.runTime
.average
).toBeGreaterThan(0)
953 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
954 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
955 ).defaultWorkerWeight
958 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
959 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
960 ).workerVirtualTaskRunTime
961 ).toBeGreaterThanOrEqual(0)
962 // We need to clean up the resources after our test
966 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
967 const pool
= new DynamicThreadPool(
970 './tests/worker-files/thread/testWorker.js',
972 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
973 workerChoiceStrategyOptions
: {
978 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
979 const promises
= new Set()
980 const maxMultiplier
= 2
981 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
982 promises
.add(pool
.execute())
984 await Promise
.all(promises
)
985 for (const workerNode
of pool
.workerNodes
) {
986 expect(workerNode
.workerUsage
).toStrictEqual({
988 executed
: expect
.any(Number
),
994 aggregation
: expect
.any(Number
),
996 median
: expect
.any(Number
),
997 history
: expect
.any(CircularArray
)
1003 history
: expect
.any(CircularArray
)
1007 expect(workerNode
.workerUsage
.tasks
.executed
).toBeGreaterThan(0)
1008 expect(workerNode
.workerUsage
.tasks
.executed
).toBeLessThanOrEqual(
1011 expect(workerNode
.workerUsage
.runTime
.aggregation
).toBeGreaterThan(0)
1012 expect(workerNode
.workerUsage
.runTime
.median
).toBeGreaterThan(0)
1015 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1016 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1017 ).defaultWorkerWeight
1018 ).toBeGreaterThan(0)
1020 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1021 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1022 ).workerVirtualTaskRunTime
1023 ).toBeGreaterThanOrEqual(0)
1024 // We need to clean up the resources after our test
1025 await pool
.destroy()
1028 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1029 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1030 let pool
= new FixedThreadPool(
1032 './tests/worker-files/thread/testWorker.js'
1035 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1036 workerChoiceStrategy
1037 ).currentWorkerNodeId
1040 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1041 workerChoiceStrategy
1042 ).defaultWorkerWeight
1045 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1046 workerChoiceStrategy
1047 ).workerVirtualTaskRunTime
1049 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1051 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1052 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1053 ).currentWorkerNodeId
1056 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1057 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1058 ).defaultWorkerWeight
1059 ).toBeGreaterThan(0)
1061 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1062 workerChoiceStrategy
1063 ).workerVirtualTaskRunTime
1065 await pool
.destroy()
1066 pool
= new DynamicThreadPool(
1069 './tests/worker-files/thread/testWorker.js'
1072 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1073 workerChoiceStrategy
1074 ).currentWorkerNodeId
1077 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1078 workerChoiceStrategy
1079 ).defaultWorkerWeight
1082 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1083 workerChoiceStrategy
1084 ).workerVirtualTaskRunTime
1086 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1088 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1089 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1090 ).currentWorkerNodeId
1093 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1094 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1095 ).defaultWorkerWeight
1096 ).toBeGreaterThan(0)
1098 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1099 workerChoiceStrategy
1100 ).workerVirtualTaskRunTime
1102 // We need to clean up the resources after our test
1103 await pool
.destroy()
1106 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1107 const workerChoiceStrategy
=
1108 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1109 let pool
= new FixedThreadPool(
1111 './tests/worker-files/thread/testWorker.js',
1112 { workerChoiceStrategy
}
1114 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
1123 await pool
.destroy()
1124 pool
= new DynamicThreadPool(
1127 './tests/worker-files/thread/testWorker.js',
1128 { workerChoiceStrategy
}
1130 expect(pool
.workerChoiceStrategyContext
.getTaskStatistics()).toStrictEqual({
1139 // We need to clean up the resources after our test
1140 await pool
.destroy()
1143 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1144 const pool
= new FixedThreadPool(
1146 './tests/worker-files/thread/testWorker.js',
1148 workerChoiceStrategy
:
1149 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1152 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1153 const promises
= new Set()
1154 const maxMultiplier
= 2
1155 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1156 promises
.add(pool
.execute())
1158 await Promise
.all(promises
)
1159 for (const workerNode
of pool
.workerNodes
) {
1160 expect(workerNode
.workerUsage
).toStrictEqual({
1162 executed
: maxMultiplier
,
1171 history
: expect
.any(CircularArray
)
1177 history
: expect
.any(CircularArray
)
1183 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1184 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1185 ).defaultWorkerWeight
1186 ).toBeGreaterThan(0)
1188 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1189 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1193 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1194 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1195 ).currentWorkerNodeId
1198 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1199 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1202 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1203 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1204 ).defaultWorkerWeight
1206 // We need to clean up the resources after our test
1207 await pool
.destroy()
1210 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1211 const pool
= new DynamicThreadPool(
1214 './tests/worker-files/thread/testWorker.js',
1216 workerChoiceStrategy
:
1217 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1220 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1221 const promises
= new Set()
1222 const maxMultiplier
= 2
1223 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1224 promises
.add(pool
.execute())
1226 await Promise
.all(promises
)
1227 for (const workerNode
of pool
.workerNodes
) {
1228 expect(workerNode
.workerUsage
).toStrictEqual({
1230 executed
: maxMultiplier
,
1239 history
: expect
.any(CircularArray
)
1245 history
: expect
.any(CircularArray
)
1251 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1252 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1253 ).defaultWorkerWeight
1254 ).toBeGreaterThan(0)
1256 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1257 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1261 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1262 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1263 ).currentWorkerNodeId
1266 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1267 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1270 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1271 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1272 ).defaultWorkerWeight
1274 // We need to clean up the resources after our test
1275 await pool
.destroy()
1278 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1279 const workerChoiceStrategy
=
1280 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1281 let pool
= new FixedThreadPool(
1283 './tests/worker-files/thread/testWorker.js'
1286 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1287 workerChoiceStrategy
1291 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1292 workerChoiceStrategy
1293 ).currentWorkerNodeId
1296 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1297 workerChoiceStrategy
1298 ).defaultWorkerWeight
1301 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1302 workerChoiceStrategy
1305 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1307 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1308 workerChoiceStrategy
1312 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1313 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1314 ).currentWorkerNodeId
1317 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1318 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1319 ).defaultWorkerWeight
1320 ).toBeGreaterThan(0)
1322 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1323 workerChoiceStrategy
1326 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1327 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1328 ).defaultWorkerWeight
1330 await pool
.destroy()
1331 pool
= new DynamicThreadPool(
1334 './tests/worker-files/thread/testWorker.js'
1337 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1338 workerChoiceStrategy
1342 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1343 workerChoiceStrategy
1344 ).currentWorkerNodeId
1347 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1348 workerChoiceStrategy
1349 ).defaultWorkerWeight
1352 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1353 workerChoiceStrategy
1356 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1358 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1359 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1360 ).currentWorkerNodeId
1363 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1364 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1365 ).defaultWorkerWeight
1366 ).toBeGreaterThan(0)
1368 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1369 workerChoiceStrategy
1372 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1373 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1374 ).defaultWorkerWeight
1376 // We need to clean up the resources after our test
1377 await pool
.destroy()
1380 it('Verify unknown strategy throw error', () => {
1383 new DynamicThreadPool(
1386 './tests/worker-files/thread/testWorker.js',
1387 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
1389 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")