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
127 workerChoiceStrategy
=== WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
130 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
132 ).defaultWorkerWeight
135 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
137 ).workerNodeVirtualTaskRunTime
140 workerChoiceStrategy
===
141 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
144 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
146 ).defaultWorkerWeight
149 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
151 ).workerNodeVirtualTaskRunTime
154 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
159 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
164 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
168 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
170 ).defaultWorkerWeight
177 it('Verify ROUND_ROBIN strategy default policy', async () => {
178 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
179 let pool
= new FixedThreadPool(
181 './tests/worker-files/thread/testWorker.js',
182 { workerChoiceStrategy
}
184 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
185 dynamicWorkerUsage
: false,
186 dynamicWorkerReady
: true
189 pool
= new DynamicThreadPool(
192 './tests/worker-files/thread/testWorker.js',
193 { workerChoiceStrategy
}
195 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
196 dynamicWorkerUsage
: false,
197 dynamicWorkerReady
: true
199 // We need to clean up the resources after our test
203 it('Verify ROUND_ROBIN strategy default tasks statistics requirements', async () => {
204 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
205 let pool
= new FixedThreadPool(
207 './tests/worker-files/thread/testWorker.js',
208 { workerChoiceStrategy
}
211 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
230 pool
= new DynamicThreadPool(
233 './tests/worker-files/thread/testWorker.js',
234 { workerChoiceStrategy
}
237 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
255 // We need to clean up the resources after our test
259 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
260 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
261 const pool
= new FixedThreadPool(
263 './tests/worker-files/thread/testWorker.js',
264 { workerChoiceStrategy
}
266 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
267 const promises
= new Set()
268 const maxMultiplier
= 2
269 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
270 promises
.add(pool
.execute())
272 await Promise
.all(promises
)
273 for (const workerNode
of pool
.workerNodes
) {
274 expect(workerNode
.usage
).toStrictEqual({
276 executed
: maxMultiplier
,
284 history
: new CircularArray()
287 history
: new CircularArray()
291 history
: new CircularArray()
294 history
: new CircularArray()
300 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
301 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
305 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
306 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
307 ).previousWorkerNodeKey
308 ).toBe(pool
.workerNodes
.length
- 1)
309 // We need to clean up the resources after our test
313 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
314 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
315 const pool
= new DynamicThreadPool(
318 './tests/worker-files/thread/testWorker.js',
319 { workerChoiceStrategy
}
321 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
322 const promises
= new Set()
323 const maxMultiplier
= 2
324 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
325 promises
.add(pool
.execute())
327 await Promise
.all(promises
)
328 for (const workerNode
of pool
.workerNodes
) {
329 expect(workerNode
.usage
).toStrictEqual({
331 executed
: expect
.any(Number
),
339 history
: new CircularArray()
342 history
: new CircularArray()
346 history
: new CircularArray()
349 history
: new CircularArray()
353 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
354 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
359 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
360 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
364 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
365 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
366 ).previousWorkerNodeKey
367 ).toBe(pool
.workerNodes
.length
- 1)
368 // We need to clean up the resources after our test
372 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
373 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
374 let pool
= new FixedClusterPool(
376 './tests/worker-files/cluster/testWorker.js',
377 { workerChoiceStrategy
}
379 let results
= new Set()
380 for (let i
= 0; i
< max
; i
++) {
381 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
383 expect(results
.size
).toBe(max
)
385 pool
= new FixedThreadPool(
387 './tests/worker-files/thread/testWorker.js',
388 { workerChoiceStrategy
}
391 for (let i
= 0; i
< max
; i
++) {
392 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
394 expect(results
.size
).toBe(max
)
398 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
399 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
400 let pool
= new FixedThreadPool(
402 './tests/worker-files/thread/testWorker.js',
403 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
406 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
407 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
411 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
412 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
413 ).previousWorkerNodeKey
415 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
417 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
418 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
422 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
423 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
424 ).previousWorkerNodeKey
427 pool
= new DynamicThreadPool(
430 './tests/worker-files/thread/testWorker.js',
431 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
434 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
435 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
439 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
440 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
441 ).previousWorkerNodeKey
443 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
445 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
446 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
450 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
451 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
452 ).previousWorkerNodeKey
454 // We need to clean up the resources after our test
458 it('Verify LEAST_USED strategy default policy', async () => {
459 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
460 let pool
= new FixedThreadPool(
462 './tests/worker-files/thread/testWorker.js',
463 { workerChoiceStrategy
}
465 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
466 dynamicWorkerUsage
: false,
467 dynamicWorkerReady
: true
470 pool
= new DynamicThreadPool(
473 './tests/worker-files/thread/testWorker.js',
474 { workerChoiceStrategy
}
476 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
477 dynamicWorkerUsage
: false,
478 dynamicWorkerReady
: true
480 // We need to clean up the resources after our test
484 it('Verify LEAST_USED strategy default tasks statistics requirements', async () => {
485 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
486 let pool
= new FixedThreadPool(
488 './tests/worker-files/thread/testWorker.js',
489 { workerChoiceStrategy
}
492 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
511 pool
= new DynamicThreadPool(
514 './tests/worker-files/thread/testWorker.js',
515 { workerChoiceStrategy
}
518 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
536 // We need to clean up the resources after our test
540 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
541 const pool
= new FixedThreadPool(
543 './tests/worker-files/thread/testWorker.js',
544 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
546 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
547 const promises
= new Set()
548 const maxMultiplier
= 2
549 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
550 promises
.add(pool
.execute())
552 await Promise
.all(promises
)
553 for (const workerNode
of pool
.workerNodes
) {
554 expect(workerNode
.usage
).toStrictEqual({
556 executed
: expect
.any(Number
),
564 history
: new CircularArray()
567 history
: new CircularArray()
571 history
: new CircularArray()
574 history
: new CircularArray()
578 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
579 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
584 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
585 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
587 ).toEqual(expect
.any(Number
))
589 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
590 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
591 ).previousWorkerNodeKey
592 ).toEqual(expect
.any(Number
))
593 // We need to clean up the resources after our test
597 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
598 const pool
= new DynamicThreadPool(
601 './tests/worker-files/thread/testWorker.js',
602 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
604 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
605 const promises
= new Set()
606 const maxMultiplier
= 2
607 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
608 promises
.add(pool
.execute())
610 await Promise
.all(promises
)
611 for (const workerNode
of pool
.workerNodes
) {
612 expect(workerNode
.usage
).toStrictEqual({
614 executed
: expect
.any(Number
),
622 history
: new CircularArray()
625 history
: new CircularArray()
629 history
: new CircularArray()
632 history
: new CircularArray()
636 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
637 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
642 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
643 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
645 ).toEqual(expect
.any(Number
))
647 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
648 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
649 ).previousWorkerNodeKey
650 ).toEqual(expect
.any(Number
))
651 // We need to clean up the resources after our test
655 it('Verify LEAST_BUSY strategy default policy', async () => {
656 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
657 let pool
= new FixedThreadPool(
659 './tests/worker-files/thread/testWorker.js',
660 { workerChoiceStrategy
}
662 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
663 dynamicWorkerUsage
: false,
664 dynamicWorkerReady
: true
667 pool
= new DynamicThreadPool(
670 './tests/worker-files/thread/testWorker.js',
671 { workerChoiceStrategy
}
673 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
674 dynamicWorkerUsage
: false,
675 dynamicWorkerReady
: true
677 // We need to clean up the resources after our test
681 it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => {
682 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
683 let pool
= new FixedThreadPool(
685 './tests/worker-files/thread/testWorker.js',
686 { workerChoiceStrategy
}
689 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
708 pool
= new DynamicThreadPool(
711 './tests/worker-files/thread/testWorker.js',
712 { workerChoiceStrategy
}
715 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
733 // We need to clean up the resources after our test
737 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
738 const pool
= new FixedThreadPool(
740 './tests/worker-files/thread/testWorker.js',
741 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
743 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
744 const promises
= new Set()
745 const maxMultiplier
= 2
746 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
747 promises
.add(pool
.execute())
749 await Promise
.all(promises
)
750 for (const workerNode
of pool
.workerNodes
) {
751 expect(workerNode
.usage
).toStrictEqual({
753 executed
: expect
.any(Number
),
760 runTime
: expect
.objectContaining({
761 history
: expect
.any(CircularArray
)
763 waitTime
: expect
.objectContaining({
764 history
: expect
.any(CircularArray
)
768 history
: new CircularArray()
771 history
: new CircularArray()
775 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
776 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
779 if (workerNode
.usage
.runTime
.aggregate
== null) {
780 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
782 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
784 if (workerNode
.usage
.waitTime
.aggregate
== null) {
785 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
787 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
791 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
792 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
794 ).toEqual(expect
.any(Number
))
796 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
797 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
798 ).previousWorkerNodeKey
799 ).toEqual(expect
.any(Number
))
800 // We need to clean up the resources after our test
804 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
805 const pool
= new DynamicThreadPool(
808 './tests/worker-files/thread/testWorker.js',
809 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
811 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
812 const promises
= new Set()
813 const maxMultiplier
= 2
814 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
815 promises
.add(pool
.execute())
817 await Promise
.all(promises
)
818 for (const workerNode
of pool
.workerNodes
) {
819 expect(workerNode
.usage
).toStrictEqual({
821 executed
: expect
.any(Number
),
828 runTime
: expect
.objectContaining({
829 history
: expect
.any(CircularArray
)
831 waitTime
: expect
.objectContaining({
832 history
: expect
.any(CircularArray
)
836 history
: new CircularArray()
839 history
: new CircularArray()
843 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
844 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
847 if (workerNode
.usage
.runTime
.aggregate
== null) {
848 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
850 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
852 if (workerNode
.usage
.waitTime
.aggregate
== null) {
853 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
855 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
859 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
860 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
862 ).toEqual(expect
.any(Number
))
864 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
865 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
866 ).previousWorkerNodeKey
867 ).toEqual(expect
.any(Number
))
868 // We need to clean up the resources after our test
872 it('Verify LEAST_ELU strategy default policy', async () => {
873 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
874 let pool
= new FixedThreadPool(
876 './tests/worker-files/thread/testWorker.js',
877 { workerChoiceStrategy
}
879 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
880 dynamicWorkerUsage
: false,
881 dynamicWorkerReady
: true
884 pool
= new DynamicThreadPool(
887 './tests/worker-files/thread/testWorker.js',
888 { workerChoiceStrategy
}
890 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
891 dynamicWorkerUsage
: false,
892 dynamicWorkerReady
: true
894 // We need to clean up the resources after our test
898 it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => {
899 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
900 let pool
= new FixedThreadPool(
902 './tests/worker-files/thread/testWorker.js',
903 { workerChoiceStrategy
}
906 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
925 pool
= new DynamicThreadPool(
928 './tests/worker-files/thread/testWorker.js',
929 { workerChoiceStrategy
}
932 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
950 // We need to clean up the resources after our test
954 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
955 const pool
= new FixedThreadPool(
957 './tests/worker-files/thread/testWorker.js',
958 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
960 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
961 const promises
= new Set()
962 const maxMultiplier
= 2
963 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
964 promises
.add(pool
.execute())
966 await Promise
.all(promises
)
967 for (const workerNode
of pool
.workerNodes
) {
968 expect(workerNode
.usage
).toStrictEqual({
970 executed
: expect
.any(Number
),
978 history
: new CircularArray()
981 history
: new CircularArray()
983 elu
: expect
.objectContaining({
984 idle
: expect
.objectContaining({
985 history
: expect
.any(CircularArray
)
987 active
: expect
.objectContaining({
988 history
: expect
.any(CircularArray
)
992 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
993 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
996 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
997 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
999 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1001 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1002 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1004 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1006 if (workerNode
.usage
.elu
.utilization
== null) {
1007 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1009 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1010 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1014 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1015 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1017 ).toEqual(expect
.any(Number
))
1019 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1020 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1021 ).previousWorkerNodeKey
1022 ).toEqual(expect
.any(Number
))
1023 // We need to clean up the resources after our test
1024 await pool
.destroy()
1027 it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => {
1028 const pool
= new DynamicThreadPool(
1031 './tests/worker-files/thread/testWorker.js',
1032 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
1034 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
1035 const promises
= new Set()
1036 const maxMultiplier
= 2
1037 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1038 promises
.add(pool
.execute())
1040 await Promise
.all(promises
)
1041 for (const workerNode
of pool
.workerNodes
) {
1042 expect(workerNode
.usage
).toStrictEqual({
1044 executed
: expect
.any(Number
),
1052 history
: new CircularArray()
1055 history
: new CircularArray()
1057 elu
: expect
.objectContaining({
1058 idle
: expect
.objectContaining({
1059 history
: expect
.any(CircularArray
)
1061 active
: expect
.objectContaining({
1062 history
: expect
.any(CircularArray
)
1066 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1067 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1070 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1071 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1073 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1075 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1076 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1078 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1080 if (workerNode
.usage
.elu
.utilization
== null) {
1081 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1083 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1084 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1088 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1089 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1091 ).toEqual(expect
.any(Number
))
1093 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1094 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1095 ).previousWorkerNodeKey
1096 ).toEqual(expect
.any(Number
))
1097 // We need to clean up the resources after our test
1098 await pool
.destroy()
1101 it('Verify FAIR_SHARE strategy default policy', async () => {
1102 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1103 let pool
= new FixedThreadPool(
1105 './tests/worker-files/thread/testWorker.js',
1106 { workerChoiceStrategy
}
1108 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1109 dynamicWorkerUsage
: false,
1110 dynamicWorkerReady
: true
1112 await pool
.destroy()
1113 pool
= new DynamicThreadPool(
1116 './tests/worker-files/thread/testWorker.js',
1117 { workerChoiceStrategy
}
1119 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1120 dynamicWorkerUsage
: false,
1121 dynamicWorkerReady
: true
1123 // We need to clean up the resources after our test
1124 await pool
.destroy()
1127 it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => {
1128 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1129 let pool
= new FixedThreadPool(
1131 './tests/worker-files/thread/testWorker.js',
1132 { workerChoiceStrategy
}
1135 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1153 await pool
.destroy()
1154 pool
= new DynamicThreadPool(
1157 './tests/worker-files/thread/testWorker.js',
1158 { workerChoiceStrategy
}
1161 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1179 // We need to clean up the resources after our test
1180 await pool
.destroy()
1183 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
1184 const pool
= new FixedThreadPool(
1186 './tests/worker-files/thread/testWorker.js',
1187 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1189 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1190 const promises
= new Set()
1191 const maxMultiplier
= 2
1192 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1193 promises
.add(pool
.execute())
1195 await Promise
.all(promises
)
1196 for (const workerNode
of pool
.workerNodes
) {
1197 expect(workerNode
.usage
).toStrictEqual({
1199 executed
: expect
.any(Number
),
1206 runTime
: expect
.objectContaining({
1207 history
: expect
.any(CircularArray
)
1210 history
: new CircularArray()
1212 elu
: expect
.objectContaining({
1213 idle
: expect
.objectContaining({
1214 history
: expect
.any(CircularArray
)
1216 active
: expect
.objectContaining({
1217 history
: expect
.any(CircularArray
)
1221 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1222 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1225 if (workerNode
.usage
.runTime
.aggregate
== null) {
1226 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1228 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1230 if (workerNode
.usage
.runTime
.average
== null) {
1231 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1233 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1235 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1236 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1238 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1240 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1241 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1243 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1245 if (workerNode
.usage
.elu
.utilization
== null) {
1246 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1248 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1249 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1253 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1254 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1256 ).toEqual(expect
.any(Number
))
1258 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1259 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1260 ).previousWorkerNodeKey
1261 ).toEqual(expect
.any(Number
))
1262 // We need to clean up the resources after our test
1263 await pool
.destroy()
1266 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
1267 const pool
= new DynamicThreadPool(
1270 './tests/worker-files/thread/testWorker.js',
1271 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1273 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1274 const promises
= new Set()
1275 const maxMultiplier
= 2
1276 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1277 promises
.add(pool
.execute())
1279 await Promise
.all(promises
)
1280 for (const workerNode
of pool
.workerNodes
) {
1281 expect(workerNode
.usage
).toStrictEqual({
1283 executed
: expect
.any(Number
),
1290 runTime
: expect
.objectContaining({
1291 history
: expect
.any(CircularArray
)
1294 history
: new CircularArray()
1296 elu
: expect
.objectContaining({
1297 idle
: expect
.objectContaining({
1298 history
: expect
.any(CircularArray
)
1300 active
: expect
.objectContaining({
1301 history
: expect
.any(CircularArray
)
1305 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1306 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1309 if (workerNode
.usage
.runTime
.aggregate
== null) {
1310 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1312 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1314 if (workerNode
.usage
.runTime
.average
== null) {
1315 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1317 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1319 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1320 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1322 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1324 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1325 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1327 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1329 if (workerNode
.usage
.elu
.utilization
== null) {
1330 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1332 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1333 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1337 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1338 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1340 ).toEqual(expect
.any(Number
))
1342 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1343 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1344 ).previousWorkerNodeKey
1345 ).toEqual(expect
.any(Number
))
1346 // We need to clean up the resources after our test
1347 await pool
.destroy()
1350 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
1351 const pool
= new DynamicThreadPool(
1354 './tests/worker-files/thread/testWorker.js',
1356 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
1357 workerChoiceStrategyOptions
: {
1358 runTime
: { median
: true }
1362 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1363 const promises
= new Set()
1364 const maxMultiplier
= 2
1365 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1366 promises
.add(pool
.execute())
1368 await Promise
.all(promises
)
1369 for (const workerNode
of pool
.workerNodes
) {
1370 expect(workerNode
.usage
).toStrictEqual({
1372 executed
: expect
.any(Number
),
1379 runTime
: expect
.objectContaining({
1380 history
: expect
.any(CircularArray
)
1383 history
: new CircularArray()
1385 elu
: expect
.objectContaining({
1386 idle
: expect
.objectContaining({
1387 history
: expect
.any(CircularArray
)
1389 active
: expect
.objectContaining({
1390 history
: expect
.any(CircularArray
)
1394 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1395 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1398 if (workerNode
.usage
.runTime
.aggregate
== null) {
1399 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1401 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1403 if (workerNode
.usage
.runTime
.median
== null) {
1404 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1406 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1408 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1409 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1411 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1413 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1414 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1416 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1418 if (workerNode
.usage
.elu
.utilization
== null) {
1419 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1421 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1422 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1426 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1427 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1429 ).toEqual(expect
.any(Number
))
1431 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1432 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1433 ).previousWorkerNodeKey
1434 ).toEqual(expect
.any(Number
))
1435 // We need to clean up the resources after our test
1436 await pool
.destroy()
1439 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
1440 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1441 let pool
= new FixedThreadPool(
1443 './tests/worker-files/thread/testWorker.js'
1445 for (const workerNode
of pool
.workerNodes
) {
1446 workerNode
.strategyData
= {
1447 virtualTaskEndTimestamp
: performance
.now()
1450 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1451 for (const workerNode
of pool
.workerNodes
) {
1452 expect(workerNode
.strategyData
.virtualTaskEndTimestamp
).toBeUndefined()
1454 await pool
.destroy()
1455 pool
= new DynamicThreadPool(
1458 './tests/worker-files/thread/testWorker.js'
1460 for (const workerNode
of pool
.workerNodes
) {
1461 workerNode
.strategyData
= {
1462 virtualTaskEndTimestamp
: performance
.now()
1465 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1466 for (const workerNode
of pool
.workerNodes
) {
1467 expect(workerNode
.strategyData
.virtualTaskEndTimestamp
).toBeUndefined()
1469 // We need to clean up the resources after our test
1470 await pool
.destroy()
1473 it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1474 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1475 let pool
= new FixedThreadPool(
1477 './tests/worker-files/thread/testWorker.js',
1478 { workerChoiceStrategy
}
1480 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1481 dynamicWorkerUsage
: false,
1482 dynamicWorkerReady
: true
1484 await pool
.destroy()
1485 pool
= new DynamicThreadPool(
1488 './tests/worker-files/thread/testWorker.js',
1489 { workerChoiceStrategy
}
1491 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1492 dynamicWorkerUsage
: false,
1493 dynamicWorkerReady
: true
1495 // We need to clean up the resources after our test
1496 await pool
.destroy()
1499 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1500 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1501 let pool
= new FixedThreadPool(
1503 './tests/worker-files/thread/testWorker.js',
1504 { workerChoiceStrategy
}
1507 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1525 await pool
.destroy()
1526 pool
= new DynamicThreadPool(
1529 './tests/worker-files/thread/testWorker.js',
1530 { workerChoiceStrategy
}
1533 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1551 // We need to clean up the resources after our test
1552 await pool
.destroy()
1555 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1556 const pool
= new FixedThreadPool(
1558 './tests/worker-files/thread/testWorker.js',
1559 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1561 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1562 const promises
= new Set()
1563 const maxMultiplier
= 2
1564 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1565 promises
.add(pool
.execute())
1567 await Promise
.all(promises
)
1568 for (const workerNode
of pool
.workerNodes
) {
1569 expect(workerNode
.usage
).toStrictEqual({
1571 executed
: expect
.any(Number
),
1578 runTime
: expect
.objectContaining({
1579 history
: expect
.any(CircularArray
)
1582 history
: new CircularArray()
1586 history
: new CircularArray()
1589 history
: new CircularArray()
1593 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1594 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1597 if (workerNode
.usage
.runTime
.aggregate
== null) {
1598 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1600 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1602 if (workerNode
.usage
.runTime
.average
== null) {
1603 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1605 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1609 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1610 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1614 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1615 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1616 ).previousWorkerNodeKey
1619 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1620 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1621 ).defaultWorkerWeight
1622 ).toBeGreaterThan(0)
1624 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1625 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1626 ).workerNodeVirtualTaskRunTime
1627 ).toBeGreaterThanOrEqual(0)
1628 // We need to clean up the resources after our test
1629 await pool
.destroy()
1632 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1633 const pool
= new DynamicThreadPool(
1636 './tests/worker-files/thread/testWorker.js',
1637 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1639 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1640 const promises
= new Set()
1641 const maxMultiplier
= 2
1642 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1643 promises
.add(pool
.execute())
1645 await Promise
.all(promises
)
1646 for (const workerNode
of pool
.workerNodes
) {
1647 expect(workerNode
.usage
).toStrictEqual({
1649 executed
: expect
.any(Number
),
1656 runTime
: expect
.objectContaining({
1657 history
: expect
.any(CircularArray
)
1660 history
: new CircularArray()
1664 history
: new CircularArray()
1667 history
: new CircularArray()
1671 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1672 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1675 if (workerNode
.usage
.runTime
.aggregate
== null) {
1676 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1678 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1680 if (workerNode
.usage
.runTime
.average
== null) {
1681 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1683 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1687 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1688 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1692 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1693 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1694 ).previousWorkerNodeKey
1697 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1698 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1699 ).defaultWorkerWeight
1700 ).toBeGreaterThan(0)
1702 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1703 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1704 ).workerNodeVirtualTaskRunTime
1705 ).toBeGreaterThanOrEqual(0)
1706 // We need to clean up the resources after our test
1707 await pool
.destroy()
1710 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1711 const pool
= new DynamicThreadPool(
1714 './tests/worker-files/thread/testWorker.js',
1716 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1717 workerChoiceStrategyOptions
: {
1718 runTime
: { median
: true }
1722 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1723 const promises
= new Set()
1724 const maxMultiplier
= 2
1725 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1726 promises
.add(pool
.execute())
1728 await Promise
.all(promises
)
1729 for (const workerNode
of pool
.workerNodes
) {
1730 expect(workerNode
.usage
).toStrictEqual({
1732 executed
: expect
.any(Number
),
1739 runTime
: expect
.objectContaining({
1740 history
: expect
.any(CircularArray
)
1743 history
: new CircularArray()
1747 history
: new CircularArray()
1750 history
: new CircularArray()
1754 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1755 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1758 if (workerNode
.usage
.runTime
.aggregate
== null) {
1759 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1761 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1763 if (workerNode
.usage
.runTime
.median
== null) {
1764 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1766 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1770 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1771 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1775 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1776 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1777 ).previousWorkerNodeKey
1780 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1781 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1782 ).defaultWorkerWeight
1783 ).toBeGreaterThan(0)
1785 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1786 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1787 ).workerNodeVirtualTaskRunTime
1788 ).toBeGreaterThanOrEqual(0)
1789 // We need to clean up the resources after our test
1790 await pool
.destroy()
1793 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1794 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1795 let pool
= new FixedThreadPool(
1797 './tests/worker-files/thread/testWorker.js'
1800 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1801 workerChoiceStrategy
1805 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1806 workerChoiceStrategy
1807 ).previousWorkerNodeKey
1810 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1811 workerChoiceStrategy
1812 ).defaultWorkerWeight
1815 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1816 workerChoiceStrategy
1817 ).workerNodeVirtualTaskRunTime
1819 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1821 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1822 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1826 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1827 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1828 ).previousWorkerNodeKey
1831 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1832 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1833 ).defaultWorkerWeight
1834 ).toBeGreaterThan(0)
1836 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1837 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1838 ).workerNodeVirtualTaskRunTime
1840 await pool
.destroy()
1841 pool
= new DynamicThreadPool(
1844 './tests/worker-files/thread/testWorker.js'
1847 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1848 workerChoiceStrategy
1852 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1853 workerChoiceStrategy
1854 ).previousWorkerNodeKey
1857 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1858 workerChoiceStrategy
1859 ).defaultWorkerWeight
1862 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1863 workerChoiceStrategy
1864 ).workerNodeVirtualTaskRunTime
1866 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1868 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1869 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1873 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1874 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1875 ).previousWorkerNodeKey
1878 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1879 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1880 ).defaultWorkerWeight
1881 ).toBeGreaterThan(0)
1883 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1884 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1885 ).workerNodeVirtualTaskRunTime
1887 // We need to clean up the resources after our test
1888 await pool
.destroy()
1891 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1892 const workerChoiceStrategy
=
1893 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1894 let pool
= new FixedThreadPool(
1896 './tests/worker-files/thread/testWorker.js',
1897 { workerChoiceStrategy
}
1899 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1900 dynamicWorkerUsage
: false,
1901 dynamicWorkerReady
: true
1903 await pool
.destroy()
1904 pool
= new DynamicThreadPool(
1907 './tests/worker-files/thread/testWorker.js',
1908 { workerChoiceStrategy
}
1910 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1911 dynamicWorkerUsage
: false,
1912 dynamicWorkerReady
: true
1914 // We need to clean up the resources after our test
1915 await pool
.destroy()
1918 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1919 const workerChoiceStrategy
=
1920 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1921 let pool
= new FixedThreadPool(
1923 './tests/worker-files/thread/testWorker.js',
1924 { workerChoiceStrategy
}
1927 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1945 await pool
.destroy()
1946 pool
= new DynamicThreadPool(
1949 './tests/worker-files/thread/testWorker.js',
1950 { workerChoiceStrategy
}
1953 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1971 // We need to clean up the resources after our test
1972 await pool
.destroy()
1975 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1976 const pool
= new FixedThreadPool(
1978 './tests/worker-files/thread/testWorker.js',
1980 workerChoiceStrategy
:
1981 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1984 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1985 const promises
= new Set()
1986 const maxMultiplier
= 2
1987 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1988 promises
.add(pool
.execute())
1990 await Promise
.all(promises
)
1991 for (const workerNode
of pool
.workerNodes
) {
1992 expect(workerNode
.usage
).toStrictEqual({
1994 executed
: expect
.any(Number
),
2001 runTime
: expect
.objectContaining({
2002 history
: expect
.any(CircularArray
)
2005 history
: new CircularArray()
2009 history
: new CircularArray()
2012 history
: new CircularArray()
2016 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
2017 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
2022 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2023 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2024 ).defaultWorkerWeight
2025 ).toBeGreaterThan(0)
2027 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2028 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2032 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2033 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2037 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2038 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2042 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2043 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2044 ).previousWorkerNodeKey
2045 ).toEqual(expect
.any(Number
))
2047 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2048 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2051 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2052 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2053 ).defaultWorkerWeight
2055 // We need to clean up the resources after our test
2056 await pool
.destroy()
2059 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
2060 const pool
= new DynamicThreadPool(
2063 './tests/worker-files/thread/testWorker.js',
2065 workerChoiceStrategy
:
2066 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
2069 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
2070 const promises
= new Set()
2071 const maxMultiplier
= 2
2072 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
2073 promises
.add(pool
.execute())
2075 await Promise
.all(promises
)
2076 for (const workerNode
of pool
.workerNodes
) {
2077 expect(workerNode
.usage
).toStrictEqual({
2079 executed
: expect
.any(Number
),
2086 runTime
: expect
.objectContaining({
2087 history
: expect
.any(CircularArray
)
2090 history
: new CircularArray()
2094 history
: new CircularArray()
2097 history
: new CircularArray()
2101 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
2102 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
2107 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2108 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2109 ).defaultWorkerWeight
2110 ).toBeGreaterThan(0)
2112 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2113 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2117 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2118 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2122 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2123 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2127 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2128 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2129 ).previousWorkerNodeKey
2130 ).toEqual(expect
.any(Number
))
2132 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2133 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2136 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2137 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2138 ).defaultWorkerWeight
2140 // We need to clean up the resources after our test
2141 await pool
.destroy()
2144 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
2145 const workerChoiceStrategy
=
2146 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
2147 let pool
= new FixedThreadPool(
2149 './tests/worker-files/thread/testWorker.js'
2152 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2153 workerChoiceStrategy
2157 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2158 workerChoiceStrategy
2162 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2163 workerChoiceStrategy
2167 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2168 workerChoiceStrategy
2169 ).previousWorkerNodeKey
2172 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2173 workerChoiceStrategy
2174 ).defaultWorkerWeight
2177 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2178 workerChoiceStrategy
2181 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2183 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2184 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2188 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2189 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2193 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2194 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2198 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2199 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2200 ).previousWorkerNodeKey
2203 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2204 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2205 ).defaultWorkerWeight
2206 ).toBeGreaterThan(0)
2208 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2209 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2212 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2213 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2214 ).defaultWorkerWeight
2216 await pool
.destroy()
2217 pool
= new DynamicThreadPool(
2220 './tests/worker-files/thread/testWorker.js'
2223 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2224 workerChoiceStrategy
2228 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2229 workerChoiceStrategy
2233 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2234 workerChoiceStrategy
2238 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2239 workerChoiceStrategy
2240 ).previousWorkerNodeKey
2243 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2244 workerChoiceStrategy
2245 ).defaultWorkerWeight
2248 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2249 workerChoiceStrategy
2252 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2254 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2255 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2259 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2260 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2264 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2265 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2269 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2270 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2271 ).previousWorkerNodeKey
2274 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2275 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2276 ).defaultWorkerWeight
2277 ).toBeGreaterThan(0)
2279 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2280 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2283 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2284 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2285 ).defaultWorkerWeight
2287 // We need to clean up the resources after our test
2288 await pool
.destroy()
2291 it('Verify unknown strategy throw error', () => {
2294 new DynamicThreadPool(
2297 './tests/worker-files/thread/testWorker.js',
2298 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
2300 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")