1 const { expect
} = require('expect')
8 } = require('../../../lib')
9 const { CircularArray
} = require('../../../lib/circular-array')
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(
69 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
71 runTime
: { median
: false },
72 waitTime
: { median
: false },
73 elu
: { median
: false }
75 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
77 runTime
: { median
: false },
78 waitTime
: { median
: false },
79 elu
: { median
: false }
83 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
84 const pool
= new DynamicClusterPool(
87 './tests/worker-files/cluster/testWorker.js'
89 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
, { retries
: 3 })
90 expect(pool
.opts
.workerChoiceStrategy
).toBe(workerChoiceStrategy
)
91 expect(pool
.workerChoiceStrategyContext
.workerChoiceStrategy
).toBe(
94 expect(pool
.opts
.workerChoiceStrategyOptions
).toStrictEqual({
96 runTime
: { median
: false },
97 waitTime
: { median
: false },
98 elu
: { median
: false }
100 expect(pool
.workerChoiceStrategyContext
.opts
).toStrictEqual({
102 runTime
: { median
: false },
103 waitTime
: { median
: false },
104 elu
: { median
: false }
110 it('Verify available strategies default internals at pool creation', async () => {
111 const pool
= new FixedThreadPool(
113 './tests/worker-files/thread/testWorker.js'
115 for (const workerChoiceStrategy
of Object
.values(WorkerChoiceStrategies
)) {
117 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
122 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
124 ).previousWorkerNodeKey
126 if (workerChoiceStrategy
=== WorkerChoiceStrategies
.FAIR_SHARE
) {
128 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
130 ).workersVirtualTaskEndTimestamp
131 ).toBeInstanceOf(Array
)
133 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
135 ).workersVirtualTaskEndTimestamp
.length
138 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
141 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
143 ).defaultWorkerWeight
146 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
148 ).workerVirtualTaskRunTime
151 workerChoiceStrategy
===
152 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
155 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
157 ).defaultWorkerWeight
160 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
162 ).workerVirtualTaskRunTime
165 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
170 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
175 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
179 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
181 ).defaultWorkerWeight
188 it('Verify ROUND_ROBIN strategy default policy', async () => {
189 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
190 let pool
= new FixedThreadPool(
192 './tests/worker-files/thread/testWorker.js',
193 { workerChoiceStrategy
}
195 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
196 dynamicWorkerUsage
: false,
197 dynamicWorkerReady
: true
200 pool
= new DynamicThreadPool(
203 './tests/worker-files/thread/testWorker.js',
204 { workerChoiceStrategy
}
206 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
207 dynamicWorkerUsage
: false,
208 dynamicWorkerReady
: true
210 // We need to clean up the resources after our test
214 it('Verify ROUND_ROBIN strategy default tasks statistics requirements', async () => {
215 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
216 let pool
= new FixedThreadPool(
218 './tests/worker-files/thread/testWorker.js',
219 { workerChoiceStrategy
}
222 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
241 pool
= new DynamicThreadPool(
244 './tests/worker-files/thread/testWorker.js',
245 { workerChoiceStrategy
}
248 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
266 // We need to clean up the resources after our test
270 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
271 const pool
= new FixedThreadPool(
273 './tests/worker-files/thread/testWorker.js',
274 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
276 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
277 const promises
= new Set()
278 const maxMultiplier
= 2
279 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
280 promises
.add(pool
.execute())
282 await Promise
.all(promises
)
283 for (const workerNode
of pool
.workerNodes
) {
284 expect(workerNode
.usage
).toStrictEqual({
286 executed
: maxMultiplier
,
294 history
: new CircularArray()
297 history
: new CircularArray()
301 history
: new CircularArray()
304 history
: new CircularArray()
310 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
311 WorkerChoiceStrategies
.ROUND_ROBIN
314 // We need to clean up the resources after our test
318 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
319 const pool
= new DynamicThreadPool(
322 './tests/worker-files/thread/testWorker.js',
323 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
325 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
326 const promises
= new Set()
327 const maxMultiplier
= 2
328 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
329 promises
.add(pool
.execute())
331 await Promise
.all(promises
)
332 for (const workerNode
of pool
.workerNodes
) {
333 expect(workerNode
.usage
).toStrictEqual({
335 executed
: expect
.any(Number
),
343 history
: new CircularArray()
346 history
: new CircularArray()
350 history
: new CircularArray()
353 history
: new CircularArray()
357 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
358 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
363 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
364 WorkerChoiceStrategies
.ROUND_ROBIN
367 // We need to clean up the resources after our test
371 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
372 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
373 let pool
= new FixedClusterPool(
375 './tests/worker-files/cluster/testWorker.js',
376 { workerChoiceStrategy
}
378 let results
= new Set()
379 for (let i
= 0; i
< max
; i
++) {
380 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
382 expect(results
.size
).toBe(max
)
384 pool
= new FixedThreadPool(
386 './tests/worker-files/thread/testWorker.js',
387 { workerChoiceStrategy
}
390 for (let i
= 0; i
< max
; i
++) {
391 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
393 expect(results
.size
).toBe(max
)
397 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
398 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
399 let pool
= new FixedThreadPool(
401 './tests/worker-files/thread/testWorker.js',
402 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
405 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
409 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
411 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
412 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
416 pool
= new DynamicThreadPool(
419 './tests/worker-files/thread/testWorker.js',
420 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
423 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
427 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
429 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
430 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
433 // We need to clean up the resources after our test
437 it('Verify LEAST_USED strategy default policy', async () => {
438 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
439 let pool
= new FixedThreadPool(
441 './tests/worker-files/thread/testWorker.js',
442 { workerChoiceStrategy
}
444 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
445 dynamicWorkerUsage
: false,
446 dynamicWorkerReady
: true
449 pool
= new DynamicThreadPool(
452 './tests/worker-files/thread/testWorker.js',
453 { workerChoiceStrategy
}
455 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
456 dynamicWorkerUsage
: false,
457 dynamicWorkerReady
: true
459 // We need to clean up the resources after our test
463 it('Verify LEAST_USED strategy default tasks statistics requirements', async () => {
464 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
465 let pool
= new FixedThreadPool(
467 './tests/worker-files/thread/testWorker.js',
468 { workerChoiceStrategy
}
471 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
490 pool
= new DynamicThreadPool(
493 './tests/worker-files/thread/testWorker.js',
494 { workerChoiceStrategy
}
497 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
515 // We need to clean up the resources after our test
519 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
520 const pool
= new FixedThreadPool(
522 './tests/worker-files/thread/testWorker.js',
523 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
525 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
526 const promises
= new Set()
527 const maxMultiplier
= 2
528 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
529 promises
.add(pool
.execute())
531 await Promise
.all(promises
)
532 for (const workerNode
of pool
.workerNodes
) {
533 expect(workerNode
.usage
).toStrictEqual({
535 executed
: expect
.any(Number
),
543 history
: new CircularArray()
546 history
: new CircularArray()
550 history
: new CircularArray()
553 history
: new CircularArray()
557 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
558 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
562 // We need to clean up the resources after our test
566 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
567 const pool
= new DynamicThreadPool(
570 './tests/worker-files/thread/testWorker.js',
571 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
573 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
574 const promises
= new Set()
575 const maxMultiplier
= 2
576 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
577 promises
.add(pool
.execute())
579 await Promise
.all(promises
)
580 for (const workerNode
of pool
.workerNodes
) {
581 expect(workerNode
.usage
).toStrictEqual({
583 executed
: expect
.any(Number
),
591 history
: new CircularArray()
594 history
: new CircularArray()
598 history
: new CircularArray()
601 history
: new CircularArray()
605 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
606 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
610 // We need to clean up the resources after our test
614 it('Verify LEAST_BUSY strategy default policy', async () => {
615 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
616 let pool
= new FixedThreadPool(
618 './tests/worker-files/thread/testWorker.js',
619 { workerChoiceStrategy
}
621 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
622 dynamicWorkerUsage
: false,
623 dynamicWorkerReady
: true
626 pool
= new DynamicThreadPool(
629 './tests/worker-files/thread/testWorker.js',
630 { workerChoiceStrategy
}
632 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
633 dynamicWorkerUsage
: false,
634 dynamicWorkerReady
: true
636 // We need to clean up the resources after our test
640 it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => {
641 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
642 let pool
= new FixedThreadPool(
644 './tests/worker-files/thread/testWorker.js',
645 { workerChoiceStrategy
}
648 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
667 pool
= new DynamicThreadPool(
670 './tests/worker-files/thread/testWorker.js',
671 { workerChoiceStrategy
}
674 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
692 // We need to clean up the resources after our test
696 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
697 const pool
= new FixedThreadPool(
699 './tests/worker-files/thread/testWorker.js',
700 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
702 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
703 const promises
= new Set()
704 const maxMultiplier
= 2
705 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
706 promises
.add(pool
.execute())
708 await Promise
.all(promises
)
709 for (const workerNode
of pool
.workerNodes
) {
710 expect(workerNode
.usage
).toStrictEqual({
712 executed
: expect
.any(Number
),
719 runTime
: expect
.objectContaining({
720 history
: expect
.any(CircularArray
)
722 waitTime
: expect
.objectContaining({
723 history
: expect
.any(CircularArray
)
727 history
: new CircularArray()
730 history
: new CircularArray()
734 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
735 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
738 if (workerNode
.usage
.runTime
.aggregate
== null) {
739 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
741 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
743 if (workerNode
.usage
.waitTime
.aggregate
== null) {
744 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
746 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
749 // We need to clean up the resources after our test
753 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
754 const pool
= new DynamicThreadPool(
757 './tests/worker-files/thread/testWorker.js',
758 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
760 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
761 const promises
= new Set()
762 const maxMultiplier
= 2
763 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
764 promises
.add(pool
.execute())
766 await Promise
.all(promises
)
767 for (const workerNode
of pool
.workerNodes
) {
768 expect(workerNode
.usage
).toStrictEqual({
770 executed
: expect
.any(Number
),
777 runTime
: expect
.objectContaining({
778 history
: expect
.any(CircularArray
)
780 waitTime
: expect
.objectContaining({
781 history
: expect
.any(CircularArray
)
785 history
: new CircularArray()
788 history
: new CircularArray()
792 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
793 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
796 if (workerNode
.usage
.runTime
.aggregate
== null) {
797 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
799 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
801 if (workerNode
.usage
.waitTime
.aggregate
== null) {
802 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
804 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
807 // We need to clean up the resources after our test
811 it('Verify LEAST_ELU strategy default policy', async () => {
812 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
813 let pool
= new FixedThreadPool(
815 './tests/worker-files/thread/testWorker.js',
816 { workerChoiceStrategy
}
818 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
819 dynamicWorkerUsage
: false,
820 dynamicWorkerReady
: true
823 pool
= new DynamicThreadPool(
826 './tests/worker-files/thread/testWorker.js',
827 { workerChoiceStrategy
}
829 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
830 dynamicWorkerUsage
: false,
831 dynamicWorkerReady
: true
833 // We need to clean up the resources after our test
837 it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => {
838 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
839 let pool
= new FixedThreadPool(
841 './tests/worker-files/thread/testWorker.js',
842 { workerChoiceStrategy
}
845 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
864 pool
= new DynamicThreadPool(
867 './tests/worker-files/thread/testWorker.js',
868 { workerChoiceStrategy
}
871 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
889 // We need to clean up the resources after our test
893 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
894 const pool
= new FixedThreadPool(
896 './tests/worker-files/thread/testWorker.js',
897 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
899 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
900 const promises
= new Set()
901 const maxMultiplier
= 2
902 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
903 promises
.add(pool
.execute())
905 await Promise
.all(promises
)
906 for (const workerNode
of pool
.workerNodes
) {
907 expect(workerNode
.usage
).toStrictEqual({
909 executed
: expect
.any(Number
),
917 history
: new CircularArray()
920 history
: new CircularArray()
922 elu
: expect
.objectContaining({
923 idle
: expect
.objectContaining({
924 history
: expect
.any(CircularArray
)
926 active
: expect
.objectContaining({
927 history
: expect
.any(CircularArray
)
931 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
932 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
935 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
936 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
938 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
940 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
941 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
943 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
945 if (workerNode
.usage
.elu
.utilization
== null) {
946 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
948 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
949 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
952 // We need to clean up the resources after our test
956 it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => {
957 const pool
= new DynamicThreadPool(
960 './tests/worker-files/thread/testWorker.js',
961 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
963 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
964 const promises
= new Set()
965 const maxMultiplier
= 2
966 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
967 promises
.add(pool
.execute())
969 await Promise
.all(promises
)
970 for (const workerNode
of pool
.workerNodes
) {
971 expect(workerNode
.usage
).toStrictEqual({
973 executed
: expect
.any(Number
),
981 history
: new CircularArray()
984 history
: new CircularArray()
986 elu
: expect
.objectContaining({
987 idle
: expect
.objectContaining({
988 history
: expect
.any(CircularArray
)
990 active
: expect
.objectContaining({
991 history
: expect
.any(CircularArray
)
995 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
996 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
999 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1000 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1002 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1004 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1005 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1007 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1009 if (workerNode
.usage
.elu
.utilization
== null) {
1010 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1012 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1013 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1016 // We need to clean up the resources after our test
1017 await pool
.destroy()
1020 it('Verify FAIR_SHARE strategy default policy', async () => {
1021 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1022 let pool
= new FixedThreadPool(
1024 './tests/worker-files/thread/testWorker.js',
1025 { workerChoiceStrategy
}
1027 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1028 dynamicWorkerUsage
: false,
1029 dynamicWorkerReady
: true
1031 await pool
.destroy()
1032 pool
= new DynamicThreadPool(
1035 './tests/worker-files/thread/testWorker.js',
1036 { workerChoiceStrategy
}
1038 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1039 dynamicWorkerUsage
: false,
1040 dynamicWorkerReady
: true
1042 // We need to clean up the resources after our test
1043 await pool
.destroy()
1046 it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => {
1047 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1048 let pool
= new FixedThreadPool(
1050 './tests/worker-files/thread/testWorker.js',
1051 { workerChoiceStrategy
}
1054 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1072 await pool
.destroy()
1073 pool
= new DynamicThreadPool(
1076 './tests/worker-files/thread/testWorker.js',
1077 { workerChoiceStrategy
}
1080 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1098 // We need to clean up the resources after our test
1099 await pool
.destroy()
1102 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
1103 const pool
= new FixedThreadPool(
1105 './tests/worker-files/thread/testWorker.js',
1106 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1108 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1109 const promises
= new Set()
1110 const maxMultiplier
= 2
1111 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1112 promises
.add(pool
.execute())
1114 await Promise
.all(promises
)
1115 for (const workerNode
of pool
.workerNodes
) {
1116 expect(workerNode
.usage
).toStrictEqual({
1118 executed
: expect
.any(Number
),
1125 runTime
: expect
.objectContaining({
1126 history
: expect
.any(CircularArray
)
1129 history
: new CircularArray()
1131 elu
: expect
.objectContaining({
1132 idle
: expect
.objectContaining({
1133 history
: expect
.any(CircularArray
)
1135 active
: expect
.objectContaining({
1136 history
: expect
.any(CircularArray
)
1140 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1141 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1144 if (workerNode
.usage
.runTime
.aggregate
== null) {
1145 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1147 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1149 if (workerNode
.usage
.runTime
.average
== null) {
1150 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1152 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1154 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1155 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1157 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1159 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1160 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1162 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1164 if (workerNode
.usage
.elu
.utilization
== null) {
1165 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1167 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1168 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1172 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1173 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1174 ).workersVirtualTaskEndTimestamp
.length
1175 ).toBe(pool
.workerNodes
.length
)
1176 // We need to clean up the resources after our test
1177 await pool
.destroy()
1180 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
1181 const pool
= new DynamicThreadPool(
1184 './tests/worker-files/thread/testWorker.js',
1185 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1187 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1188 const promises
= new Set()
1189 const maxMultiplier
= 2
1190 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1191 promises
.add(pool
.execute())
1193 await Promise
.all(promises
)
1194 for (const workerNode
of pool
.workerNodes
) {
1195 expect(workerNode
.usage
).toStrictEqual({
1197 executed
: expect
.any(Number
),
1204 runTime
: expect
.objectContaining({
1205 history
: expect
.any(CircularArray
)
1208 history
: new CircularArray()
1210 elu
: expect
.objectContaining({
1211 idle
: expect
.objectContaining({
1212 history
: expect
.any(CircularArray
)
1214 active
: expect
.objectContaining({
1215 history
: expect
.any(CircularArray
)
1219 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1220 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1223 if (workerNode
.usage
.runTime
.aggregate
== null) {
1224 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1226 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1228 if (workerNode
.usage
.runTime
.average
== null) {
1229 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1231 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1233 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1234 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1236 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1238 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1239 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1241 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1243 if (workerNode
.usage
.elu
.utilization
== null) {
1244 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1246 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1247 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1251 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1252 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1253 ).workersVirtualTaskEndTimestamp
.length
1254 ).toBe(pool
.workerNodes
.length
)
1255 // We need to clean up the resources after our test
1256 await pool
.destroy()
1259 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
1260 const pool
= new DynamicThreadPool(
1263 './tests/worker-files/thread/testWorker.js',
1265 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
1266 workerChoiceStrategyOptions
: {
1267 runTime
: { median
: true }
1271 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1272 const promises
= new Set()
1273 const maxMultiplier
= 2
1274 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1275 promises
.add(pool
.execute())
1277 await Promise
.all(promises
)
1278 for (const workerNode
of pool
.workerNodes
) {
1279 expect(workerNode
.usage
).toStrictEqual({
1281 executed
: expect
.any(Number
),
1288 runTime
: expect
.objectContaining({
1289 history
: expect
.any(CircularArray
)
1292 history
: new CircularArray()
1294 elu
: expect
.objectContaining({
1295 idle
: expect
.objectContaining({
1296 history
: expect
.any(CircularArray
)
1298 active
: expect
.objectContaining({
1299 history
: expect
.any(CircularArray
)
1303 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1304 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1307 if (workerNode
.usage
.runTime
.aggregate
== null) {
1308 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1310 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1312 if (workerNode
.usage
.runTime
.median
== null) {
1313 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1315 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1317 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1318 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1320 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1322 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1323 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1325 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1327 if (workerNode
.usage
.elu
.utilization
== null) {
1328 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1330 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1331 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1335 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1336 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1337 ).workersVirtualTaskEndTimestamp
.length
1338 ).toBe(pool
.workerNodes
.length
)
1339 // We need to clean up the resources after our test
1340 await pool
.destroy()
1343 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
1344 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1345 let pool
= new FixedThreadPool(
1347 './tests/worker-files/thread/testWorker.js'
1350 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1351 workerChoiceStrategy
1352 ).workersVirtualTaskEndTimestamp
1353 ).toBeInstanceOf(Array
)
1355 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1356 workerChoiceStrategy
1357 ).workersVirtualTaskEndTimestamp
.length
1359 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1360 workerChoiceStrategy
1361 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
1363 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1364 workerChoiceStrategy
1365 ).workersVirtualTaskEndTimestamp
.length
1367 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1369 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1370 workerChoiceStrategy
1371 ).workersVirtualTaskEndTimestamp
1372 ).toBeInstanceOf(Array
)
1374 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1375 workerChoiceStrategy
1376 ).workersVirtualTaskEndTimestamp
.length
1378 await pool
.destroy()
1379 pool
= new DynamicThreadPool(
1382 './tests/worker-files/thread/testWorker.js'
1385 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1386 workerChoiceStrategy
1387 ).workersVirtualTaskEndTimestamp
1388 ).toBeInstanceOf(Array
)
1390 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1391 workerChoiceStrategy
1392 ).workersVirtualTaskEndTimestamp
.length
1394 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1395 workerChoiceStrategy
1396 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
1398 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1399 workerChoiceStrategy
1400 ).workersVirtualTaskEndTimestamp
.length
1402 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1404 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1405 workerChoiceStrategy
1406 ).workersVirtualTaskEndTimestamp
1407 ).toBeInstanceOf(Array
)
1409 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1410 workerChoiceStrategy
1411 ).workersVirtualTaskEndTimestamp
.length
1413 // We need to clean up the resources after our test
1414 await pool
.destroy()
1417 it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1418 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1419 let pool
= new FixedThreadPool(
1421 './tests/worker-files/thread/testWorker.js',
1422 { workerChoiceStrategy
}
1424 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1425 dynamicWorkerUsage
: false,
1426 dynamicWorkerReady
: true
1428 await pool
.destroy()
1429 pool
= new DynamicThreadPool(
1432 './tests/worker-files/thread/testWorker.js',
1433 { workerChoiceStrategy
}
1435 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1436 dynamicWorkerUsage
: false,
1437 dynamicWorkerReady
: true
1439 // We need to clean up the resources after our test
1440 await pool
.destroy()
1443 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1444 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1445 let pool
= new FixedThreadPool(
1447 './tests/worker-files/thread/testWorker.js',
1448 { workerChoiceStrategy
}
1451 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1469 await pool
.destroy()
1470 pool
= new DynamicThreadPool(
1473 './tests/worker-files/thread/testWorker.js',
1474 { workerChoiceStrategy
}
1477 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1495 // We need to clean up the resources after our test
1496 await pool
.destroy()
1499 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1500 const pool
= new FixedThreadPool(
1502 './tests/worker-files/thread/testWorker.js',
1503 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1505 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1506 const promises
= new Set()
1507 const maxMultiplier
= 2
1508 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1509 promises
.add(pool
.execute())
1511 await Promise
.all(promises
)
1512 for (const workerNode
of pool
.workerNodes
) {
1513 expect(workerNode
.usage
).toStrictEqual({
1515 executed
: expect
.any(Number
),
1522 runTime
: expect
.objectContaining({
1523 history
: expect
.any(CircularArray
)
1526 history
: new CircularArray()
1530 history
: new CircularArray()
1533 history
: new CircularArray()
1537 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1538 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1541 if (workerNode
.usage
.runTime
.aggregate
== null) {
1542 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1544 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1546 if (workerNode
.usage
.runTime
.average
== null) {
1547 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1549 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1553 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1554 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1555 ).defaultWorkerWeight
1556 ).toBeGreaterThan(0)
1558 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1559 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1560 ).workerVirtualTaskRunTime
1561 ).toBeGreaterThanOrEqual(0)
1562 // We need to clean up the resources after our test
1563 await pool
.destroy()
1566 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1567 const pool
= new DynamicThreadPool(
1570 './tests/worker-files/thread/testWorker.js',
1571 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1573 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1574 const promises
= new Set()
1575 const maxMultiplier
= 2
1576 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1577 promises
.add(pool
.execute())
1579 await Promise
.all(promises
)
1580 for (const workerNode
of pool
.workerNodes
) {
1581 expect(workerNode
.usage
).toStrictEqual({
1583 executed
: expect
.any(Number
),
1590 runTime
: expect
.objectContaining({
1591 history
: expect
.any(CircularArray
)
1594 history
: new CircularArray()
1598 history
: new CircularArray()
1601 history
: new CircularArray()
1605 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1606 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1609 if (workerNode
.usage
.runTime
.aggregate
== null) {
1610 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1612 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1614 if (workerNode
.usage
.runTime
.average
== null) {
1615 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1617 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1621 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1622 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1623 ).defaultWorkerWeight
1624 ).toBeGreaterThan(0)
1626 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1627 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1628 ).workerVirtualTaskRunTime
1629 ).toBeGreaterThanOrEqual(0)
1630 // We need to clean up the resources after our test
1631 await pool
.destroy()
1634 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1635 const pool
= new DynamicThreadPool(
1638 './tests/worker-files/thread/testWorker.js',
1640 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1641 workerChoiceStrategyOptions
: {
1642 runTime
: { median
: true }
1646 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1647 const promises
= new Set()
1648 const maxMultiplier
= 2
1649 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1650 promises
.add(pool
.execute())
1652 await Promise
.all(promises
)
1653 for (const workerNode
of pool
.workerNodes
) {
1654 expect(workerNode
.usage
).toStrictEqual({
1656 executed
: expect
.any(Number
),
1663 runTime
: expect
.objectContaining({
1664 history
: expect
.any(CircularArray
)
1667 history
: new CircularArray()
1671 history
: new CircularArray()
1674 history
: new CircularArray()
1678 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1679 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1682 if (workerNode
.usage
.runTime
.aggregate
== null) {
1683 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1685 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1687 if (workerNode
.usage
.runTime
.median
== null) {
1688 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1690 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1694 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1695 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1696 ).defaultWorkerWeight
1697 ).toBeGreaterThan(0)
1699 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1700 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1701 ).workerVirtualTaskRunTime
1702 ).toBeGreaterThanOrEqual(0)
1703 // We need to clean up the resources after our test
1704 await pool
.destroy()
1707 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1708 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1709 let pool
= new FixedThreadPool(
1711 './tests/worker-files/thread/testWorker.js'
1714 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1715 workerChoiceStrategy
1719 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1720 workerChoiceStrategy
1721 ).defaultWorkerWeight
1724 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1725 workerChoiceStrategy
1726 ).workerVirtualTaskRunTime
1728 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1730 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1731 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1735 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1736 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1737 ).defaultWorkerWeight
1738 ).toBeGreaterThan(0)
1740 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1741 workerChoiceStrategy
1742 ).workerVirtualTaskRunTime
1744 await pool
.destroy()
1745 pool
= new DynamicThreadPool(
1748 './tests/worker-files/thread/testWorker.js'
1751 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1752 workerChoiceStrategy
1756 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1757 workerChoiceStrategy
1758 ).defaultWorkerWeight
1761 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1762 workerChoiceStrategy
1763 ).workerVirtualTaskRunTime
1765 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1767 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1768 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1772 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1773 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1774 ).defaultWorkerWeight
1775 ).toBeGreaterThan(0)
1777 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1778 workerChoiceStrategy
1779 ).workerVirtualTaskRunTime
1781 // We need to clean up the resources after our test
1782 await pool
.destroy()
1785 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1786 const workerChoiceStrategy
=
1787 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1788 let pool
= new FixedThreadPool(
1790 './tests/worker-files/thread/testWorker.js',
1791 { workerChoiceStrategy
}
1793 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1794 dynamicWorkerUsage
: false,
1795 dynamicWorkerReady
: true
1797 await pool
.destroy()
1798 pool
= new DynamicThreadPool(
1801 './tests/worker-files/thread/testWorker.js',
1802 { workerChoiceStrategy
}
1804 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1805 dynamicWorkerUsage
: false,
1806 dynamicWorkerReady
: true
1808 // We need to clean up the resources after our test
1809 await pool
.destroy()
1812 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1813 const workerChoiceStrategy
=
1814 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1815 let pool
= new FixedThreadPool(
1817 './tests/worker-files/thread/testWorker.js',
1818 { workerChoiceStrategy
}
1821 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1839 await pool
.destroy()
1840 pool
= new DynamicThreadPool(
1843 './tests/worker-files/thread/testWorker.js',
1844 { workerChoiceStrategy
}
1847 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1865 // We need to clean up the resources after our test
1866 await pool
.destroy()
1869 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1870 const pool
= new FixedThreadPool(
1872 './tests/worker-files/thread/testWorker.js',
1874 workerChoiceStrategy
:
1875 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1878 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1879 const promises
= new Set()
1880 const maxMultiplier
= 2
1881 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1882 promises
.add(pool
.execute())
1884 await Promise
.all(promises
)
1885 for (const workerNode
of pool
.workerNodes
) {
1886 expect(workerNode
.usage
).toStrictEqual({
1888 executed
: expect
.any(Number
),
1895 runTime
: expect
.objectContaining({
1896 history
: expect
.any(CircularArray
)
1899 history
: new CircularArray()
1903 history
: new CircularArray()
1906 history
: new CircularArray()
1910 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1911 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1916 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1917 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1918 ).defaultWorkerWeight
1919 ).toBeGreaterThan(0)
1921 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1922 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1926 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1927 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1931 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1932 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1936 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1937 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1940 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1941 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1942 ).defaultWorkerWeight
1944 // We need to clean up the resources after our test
1945 await pool
.destroy()
1948 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1949 const pool
= new DynamicThreadPool(
1952 './tests/worker-files/thread/testWorker.js',
1954 workerChoiceStrategy
:
1955 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1958 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1959 const promises
= new Set()
1960 const maxMultiplier
= 2
1961 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1962 promises
.add(pool
.execute())
1964 await Promise
.all(promises
)
1965 for (const workerNode
of pool
.workerNodes
) {
1966 expect(workerNode
.usage
).toStrictEqual({
1968 executed
: expect
.any(Number
),
1975 runTime
: expect
.objectContaining({
1976 history
: expect
.any(CircularArray
)
1979 history
: new CircularArray()
1983 history
: new CircularArray()
1986 history
: new CircularArray()
1990 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1991 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1996 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1997 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1998 ).defaultWorkerWeight
1999 ).toBeGreaterThan(0)
2001 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2002 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2006 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2007 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2011 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2012 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2016 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2017 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2020 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2021 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2022 ).defaultWorkerWeight
2024 // We need to clean up the resources after our test
2025 await pool
.destroy()
2028 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
2029 const workerChoiceStrategy
=
2030 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
2031 let pool
= new FixedThreadPool(
2033 './tests/worker-files/thread/testWorker.js'
2036 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2037 workerChoiceStrategy
2041 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2042 workerChoiceStrategy
2046 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2047 workerChoiceStrategy
2048 ).defaultWorkerWeight
2051 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2052 workerChoiceStrategy
2055 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2057 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2058 workerChoiceStrategy
2062 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2063 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2067 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2068 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2069 ).defaultWorkerWeight
2070 ).toBeGreaterThan(0)
2072 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2073 workerChoiceStrategy
2076 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2077 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2078 ).defaultWorkerWeight
2080 await pool
.destroy()
2081 pool
= new DynamicThreadPool(
2084 './tests/worker-files/thread/testWorker.js'
2087 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2088 workerChoiceStrategy
2092 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2093 workerChoiceStrategy
2097 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2098 workerChoiceStrategy
2099 ).defaultWorkerWeight
2102 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2103 workerChoiceStrategy
2106 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2108 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2109 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2113 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2114 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2115 ).defaultWorkerWeight
2116 ).toBeGreaterThan(0)
2118 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2119 workerChoiceStrategy
2122 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2123 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2124 ).defaultWorkerWeight
2126 // We need to clean up the resources after our test
2127 await pool
.destroy()
2130 it('Verify unknown strategy throw error', () => {
2133 new DynamicThreadPool(
2136 './tests/worker-files/thread/testWorker.js',
2137 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
2139 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")