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
315 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
316 WorkerChoiceStrategies
.ROUND_ROBIN
317 ).previousWorkerNodeKey
318 ).toBe(pool
.workerNodes
.length
- 1)
319 // We need to clean up the resources after our test
323 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
324 const pool
= new DynamicThreadPool(
327 './tests/worker-files/thread/testWorker.js',
328 { workerChoiceStrategy
: WorkerChoiceStrategies
.ROUND_ROBIN
}
330 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
331 const promises
= new Set()
332 const maxMultiplier
= 2
333 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
334 promises
.add(pool
.execute())
336 await Promise
.all(promises
)
337 for (const workerNode
of pool
.workerNodes
) {
338 expect(workerNode
.usage
).toStrictEqual({
340 executed
: expect
.any(Number
),
348 history
: new CircularArray()
351 history
: new CircularArray()
355 history
: new CircularArray()
358 history
: new CircularArray()
362 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
363 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
368 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
369 WorkerChoiceStrategies
.ROUND_ROBIN
373 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
374 WorkerChoiceStrategies
.ROUND_ROBIN
375 ).previousWorkerNodeKey
376 ).toBe(pool
.workerNodes
.length
- 1)
377 // We need to clean up the resources after our test
381 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
382 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
383 let pool
= new FixedClusterPool(
385 './tests/worker-files/cluster/testWorker.js',
386 { workerChoiceStrategy
}
388 let results
= new Set()
389 for (let i
= 0; i
< max
; i
++) {
390 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
392 expect(results
.size
).toBe(max
)
394 pool
= new FixedThreadPool(
396 './tests/worker-files/thread/testWorker.js',
397 { workerChoiceStrategy
}
400 for (let i
= 0; i
< max
; i
++) {
401 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
403 expect(results
.size
).toBe(max
)
407 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
408 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
409 let pool
= new FixedThreadPool(
411 './tests/worker-files/thread/testWorker.js',
412 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
414 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
416 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
417 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
421 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
422 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
423 ).previousWorkerNodeKey
426 pool
= new DynamicThreadPool(
429 './tests/worker-files/thread/testWorker.js',
430 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
432 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
434 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
435 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
439 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
440 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
441 ).previousWorkerNodeKey
443 // We need to clean up the resources after our test
447 it('Verify LEAST_USED strategy default policy', async () => {
448 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
449 let pool
= new FixedThreadPool(
451 './tests/worker-files/thread/testWorker.js',
452 { workerChoiceStrategy
}
454 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
455 dynamicWorkerUsage
: false,
456 dynamicWorkerReady
: true
459 pool
= new DynamicThreadPool(
462 './tests/worker-files/thread/testWorker.js',
463 { workerChoiceStrategy
}
465 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
466 dynamicWorkerUsage
: false,
467 dynamicWorkerReady
: true
469 // We need to clean up the resources after our test
473 it('Verify LEAST_USED strategy default tasks statistics requirements', async () => {
474 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
475 let pool
= new FixedThreadPool(
477 './tests/worker-files/thread/testWorker.js',
478 { workerChoiceStrategy
}
481 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
500 pool
= new DynamicThreadPool(
503 './tests/worker-files/thread/testWorker.js',
504 { workerChoiceStrategy
}
507 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
525 // We need to clean up the resources after our test
529 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
530 const pool
= new FixedThreadPool(
532 './tests/worker-files/thread/testWorker.js',
533 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
535 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
536 const promises
= new Set()
537 const maxMultiplier
= 2
538 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
539 promises
.add(pool
.execute())
541 await Promise
.all(promises
)
542 for (const workerNode
of pool
.workerNodes
) {
543 expect(workerNode
.usage
).toStrictEqual({
545 executed
: expect
.any(Number
),
553 history
: new CircularArray()
556 history
: new CircularArray()
560 history
: new CircularArray()
563 history
: new CircularArray()
567 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
568 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
572 // We need to clean up the resources after our test
576 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
577 const pool
= new DynamicThreadPool(
580 './tests/worker-files/thread/testWorker.js',
581 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
583 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
584 const promises
= new Set()
585 const maxMultiplier
= 2
586 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
587 promises
.add(pool
.execute())
589 await Promise
.all(promises
)
590 for (const workerNode
of pool
.workerNodes
) {
591 expect(workerNode
.usage
).toStrictEqual({
593 executed
: expect
.any(Number
),
601 history
: new CircularArray()
604 history
: new CircularArray()
608 history
: new CircularArray()
611 history
: new CircularArray()
615 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
616 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
620 // We need to clean up the resources after our test
624 it('Verify LEAST_BUSY strategy default policy', async () => {
625 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
626 let pool
= new FixedThreadPool(
628 './tests/worker-files/thread/testWorker.js',
629 { workerChoiceStrategy
}
631 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
632 dynamicWorkerUsage
: false,
633 dynamicWorkerReady
: true
636 pool
= new DynamicThreadPool(
639 './tests/worker-files/thread/testWorker.js',
640 { workerChoiceStrategy
}
642 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
643 dynamicWorkerUsage
: false,
644 dynamicWorkerReady
: true
646 // We need to clean up the resources after our test
650 it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => {
651 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
652 let pool
= new FixedThreadPool(
654 './tests/worker-files/thread/testWorker.js',
655 { workerChoiceStrategy
}
658 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
677 pool
= new DynamicThreadPool(
680 './tests/worker-files/thread/testWorker.js',
681 { workerChoiceStrategy
}
684 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
702 // We need to clean up the resources after our test
706 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
707 const pool
= new FixedThreadPool(
709 './tests/worker-files/thread/testWorker.js',
710 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
712 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
713 const promises
= new Set()
714 const maxMultiplier
= 2
715 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
716 promises
.add(pool
.execute())
718 await Promise
.all(promises
)
719 for (const workerNode
of pool
.workerNodes
) {
720 expect(workerNode
.usage
).toStrictEqual({
722 executed
: expect
.any(Number
),
729 runTime
: expect
.objectContaining({
730 history
: expect
.any(CircularArray
)
732 waitTime
: expect
.objectContaining({
733 history
: expect
.any(CircularArray
)
737 history
: new CircularArray()
740 history
: new CircularArray()
744 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
745 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
748 if (workerNode
.usage
.runTime
.aggregate
== null) {
749 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
751 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
753 if (workerNode
.usage
.waitTime
.aggregate
== null) {
754 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
756 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
759 // We need to clean up the resources after our test
763 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
764 const pool
= new DynamicThreadPool(
767 './tests/worker-files/thread/testWorker.js',
768 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
770 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
771 const promises
= new Set()
772 const maxMultiplier
= 2
773 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
774 promises
.add(pool
.execute())
776 await Promise
.all(promises
)
777 for (const workerNode
of pool
.workerNodes
) {
778 expect(workerNode
.usage
).toStrictEqual({
780 executed
: expect
.any(Number
),
787 runTime
: expect
.objectContaining({
788 history
: expect
.any(CircularArray
)
790 waitTime
: expect
.objectContaining({
791 history
: expect
.any(CircularArray
)
795 history
: new CircularArray()
798 history
: new CircularArray()
802 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
803 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
806 if (workerNode
.usage
.runTime
.aggregate
== null) {
807 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
809 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
811 if (workerNode
.usage
.waitTime
.aggregate
== null) {
812 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
814 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
817 // We need to clean up the resources after our test
821 it('Verify LEAST_ELU strategy default policy', async () => {
822 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
823 let pool
= new FixedThreadPool(
825 './tests/worker-files/thread/testWorker.js',
826 { workerChoiceStrategy
}
828 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
829 dynamicWorkerUsage
: false,
830 dynamicWorkerReady
: true
833 pool
= new DynamicThreadPool(
836 './tests/worker-files/thread/testWorker.js',
837 { workerChoiceStrategy
}
839 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
840 dynamicWorkerUsage
: false,
841 dynamicWorkerReady
: true
843 // We need to clean up the resources after our test
847 it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => {
848 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
849 let pool
= new FixedThreadPool(
851 './tests/worker-files/thread/testWorker.js',
852 { workerChoiceStrategy
}
855 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
874 pool
= new DynamicThreadPool(
877 './tests/worker-files/thread/testWorker.js',
878 { workerChoiceStrategy
}
881 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
899 // We need to clean up the resources after our test
903 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
904 const pool
= new FixedThreadPool(
906 './tests/worker-files/thread/testWorker.js',
907 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
909 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
910 const promises
= new Set()
911 const maxMultiplier
= 2
912 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
913 promises
.add(pool
.execute())
915 await Promise
.all(promises
)
916 for (const workerNode
of pool
.workerNodes
) {
917 expect(workerNode
.usage
).toStrictEqual({
919 executed
: expect
.any(Number
),
927 history
: new CircularArray()
930 history
: new CircularArray()
932 elu
: expect
.objectContaining({
933 idle
: expect
.objectContaining({
934 history
: expect
.any(CircularArray
)
936 active
: expect
.objectContaining({
937 history
: expect
.any(CircularArray
)
941 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
942 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
945 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
946 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
948 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
950 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
951 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
953 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
955 if (workerNode
.usage
.elu
.utilization
== null) {
956 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
958 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
959 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
962 // We need to clean up the resources after our test
966 it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => {
967 const pool
= new DynamicThreadPool(
970 './tests/worker-files/thread/testWorker.js',
971 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
973 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
974 const promises
= new Set()
975 const maxMultiplier
= 2
976 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
977 promises
.add(pool
.execute())
979 await Promise
.all(promises
)
980 for (const workerNode
of pool
.workerNodes
) {
981 expect(workerNode
.usage
).toStrictEqual({
983 executed
: expect
.any(Number
),
991 history
: new CircularArray()
994 history
: new CircularArray()
996 elu
: expect
.objectContaining({
997 idle
: expect
.objectContaining({
998 history
: expect
.any(CircularArray
)
1000 active
: expect
.objectContaining({
1001 history
: expect
.any(CircularArray
)
1005 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1006 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1009 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1010 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1012 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1014 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1015 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1017 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1019 if (workerNode
.usage
.elu
.utilization
== null) {
1020 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1022 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1023 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1026 // We need to clean up the resources after our test
1027 await pool
.destroy()
1030 it('Verify FAIR_SHARE strategy default policy', async () => {
1031 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1032 let pool
= new FixedThreadPool(
1034 './tests/worker-files/thread/testWorker.js',
1035 { workerChoiceStrategy
}
1037 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1038 dynamicWorkerUsage
: false,
1039 dynamicWorkerReady
: true
1041 await pool
.destroy()
1042 pool
= new DynamicThreadPool(
1045 './tests/worker-files/thread/testWorker.js',
1046 { workerChoiceStrategy
}
1048 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1049 dynamicWorkerUsage
: false,
1050 dynamicWorkerReady
: true
1052 // We need to clean up the resources after our test
1053 await pool
.destroy()
1056 it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => {
1057 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1058 let pool
= new FixedThreadPool(
1060 './tests/worker-files/thread/testWorker.js',
1061 { workerChoiceStrategy
}
1064 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1082 await pool
.destroy()
1083 pool
= new DynamicThreadPool(
1086 './tests/worker-files/thread/testWorker.js',
1087 { workerChoiceStrategy
}
1090 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1108 // We need to clean up the resources after our test
1109 await pool
.destroy()
1112 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
1113 const pool
= new FixedThreadPool(
1115 './tests/worker-files/thread/testWorker.js',
1116 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1118 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1119 const promises
= new Set()
1120 const maxMultiplier
= 2
1121 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1122 promises
.add(pool
.execute())
1124 await Promise
.all(promises
)
1125 for (const workerNode
of pool
.workerNodes
) {
1126 expect(workerNode
.usage
).toStrictEqual({
1128 executed
: expect
.any(Number
),
1135 runTime
: expect
.objectContaining({
1136 history
: expect
.any(CircularArray
)
1139 history
: new CircularArray()
1141 elu
: expect
.objectContaining({
1142 idle
: expect
.objectContaining({
1143 history
: expect
.any(CircularArray
)
1145 active
: expect
.objectContaining({
1146 history
: expect
.any(CircularArray
)
1150 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1151 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1154 if (workerNode
.usage
.runTime
.aggregate
== null) {
1155 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1157 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1159 if (workerNode
.usage
.runTime
.average
== null) {
1160 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1162 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1164 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1165 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1167 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1169 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1170 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1172 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1174 if (workerNode
.usage
.elu
.utilization
== null) {
1175 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1177 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1178 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1182 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1183 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1184 ).workersVirtualTaskEndTimestamp
.length
1185 ).toBe(pool
.workerNodes
.length
)
1186 // We need to clean up the resources after our test
1187 await pool
.destroy()
1190 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
1191 const pool
= new DynamicThreadPool(
1194 './tests/worker-files/thread/testWorker.js',
1195 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1197 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1198 const promises
= new Set()
1199 const maxMultiplier
= 2
1200 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1201 promises
.add(pool
.execute())
1203 await Promise
.all(promises
)
1204 for (const workerNode
of pool
.workerNodes
) {
1205 expect(workerNode
.usage
).toStrictEqual({
1207 executed
: expect
.any(Number
),
1214 runTime
: expect
.objectContaining({
1215 history
: expect
.any(CircularArray
)
1218 history
: new CircularArray()
1220 elu
: expect
.objectContaining({
1221 idle
: expect
.objectContaining({
1222 history
: expect
.any(CircularArray
)
1224 active
: expect
.objectContaining({
1225 history
: expect
.any(CircularArray
)
1229 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1230 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1233 if (workerNode
.usage
.runTime
.aggregate
== null) {
1234 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1236 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1238 if (workerNode
.usage
.runTime
.average
== null) {
1239 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1241 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1243 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1244 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1246 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1248 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1249 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1251 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1253 if (workerNode
.usage
.elu
.utilization
== null) {
1254 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1256 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1257 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1261 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1262 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1263 ).workersVirtualTaskEndTimestamp
.length
1264 ).toBe(pool
.workerNodes
.length
)
1265 // We need to clean up the resources after our test
1266 await pool
.destroy()
1269 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
1270 const pool
= new DynamicThreadPool(
1273 './tests/worker-files/thread/testWorker.js',
1275 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
1276 workerChoiceStrategyOptions
: {
1277 runTime
: { median
: true }
1281 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1282 const promises
= new Set()
1283 const maxMultiplier
= 2
1284 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1285 promises
.add(pool
.execute())
1287 await Promise
.all(promises
)
1288 for (const workerNode
of pool
.workerNodes
) {
1289 expect(workerNode
.usage
).toStrictEqual({
1291 executed
: expect
.any(Number
),
1298 runTime
: expect
.objectContaining({
1299 history
: expect
.any(CircularArray
)
1302 history
: new CircularArray()
1304 elu
: expect
.objectContaining({
1305 idle
: expect
.objectContaining({
1306 history
: expect
.any(CircularArray
)
1308 active
: expect
.objectContaining({
1309 history
: expect
.any(CircularArray
)
1313 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1314 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1317 if (workerNode
.usage
.runTime
.aggregate
== null) {
1318 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1320 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1322 if (workerNode
.usage
.runTime
.median
== null) {
1323 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1325 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1327 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1328 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1330 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1332 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1333 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1335 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1337 if (workerNode
.usage
.elu
.utilization
== null) {
1338 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1340 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1341 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1345 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1346 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1347 ).workersVirtualTaskEndTimestamp
.length
1348 ).toBe(pool
.workerNodes
.length
)
1349 // We need to clean up the resources after our test
1350 await pool
.destroy()
1353 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
1354 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1355 let pool
= new FixedThreadPool(
1357 './tests/worker-files/thread/testWorker.js'
1360 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1361 workerChoiceStrategy
1362 ).workersVirtualTaskEndTimestamp
1363 ).toBeInstanceOf(Array
)
1365 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1366 workerChoiceStrategy
1367 ).workersVirtualTaskEndTimestamp
.length
1369 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1370 workerChoiceStrategy
1371 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
1373 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1374 workerChoiceStrategy
1375 ).workersVirtualTaskEndTimestamp
.length
1377 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1379 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1380 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1381 ).workersVirtualTaskEndTimestamp
1382 ).toBeInstanceOf(Array
)
1384 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1385 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1386 ).workersVirtualTaskEndTimestamp
.length
1388 await pool
.destroy()
1389 pool
= new DynamicThreadPool(
1392 './tests/worker-files/thread/testWorker.js'
1395 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1396 workerChoiceStrategy
1397 ).workersVirtualTaskEndTimestamp
1398 ).toBeInstanceOf(Array
)
1400 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1401 workerChoiceStrategy
1402 ).workersVirtualTaskEndTimestamp
.length
1404 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1405 workerChoiceStrategy
1406 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
1408 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1409 workerChoiceStrategy
1410 ).workersVirtualTaskEndTimestamp
.length
1412 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1414 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1415 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1416 ).workersVirtualTaskEndTimestamp
1417 ).toBeInstanceOf(Array
)
1419 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1420 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1421 ).workersVirtualTaskEndTimestamp
.length
1423 // We need to clean up the resources after our test
1424 await pool
.destroy()
1427 it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1428 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1429 let pool
= new FixedThreadPool(
1431 './tests/worker-files/thread/testWorker.js',
1432 { workerChoiceStrategy
}
1434 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1435 dynamicWorkerUsage
: false,
1436 dynamicWorkerReady
: true
1438 await pool
.destroy()
1439 pool
= new DynamicThreadPool(
1442 './tests/worker-files/thread/testWorker.js',
1443 { workerChoiceStrategy
}
1445 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1446 dynamicWorkerUsage
: false,
1447 dynamicWorkerReady
: true
1449 // We need to clean up the resources after our test
1450 await pool
.destroy()
1453 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1454 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1455 let pool
= new FixedThreadPool(
1457 './tests/worker-files/thread/testWorker.js',
1458 { workerChoiceStrategy
}
1461 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1479 await pool
.destroy()
1480 pool
= new DynamicThreadPool(
1483 './tests/worker-files/thread/testWorker.js',
1484 { workerChoiceStrategy
}
1487 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1505 // We need to clean up the resources after our test
1506 await pool
.destroy()
1509 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1510 const pool
= new FixedThreadPool(
1512 './tests/worker-files/thread/testWorker.js',
1513 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1515 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1516 const promises
= new Set()
1517 const maxMultiplier
= 2
1518 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1519 promises
.add(pool
.execute())
1521 await Promise
.all(promises
)
1522 for (const workerNode
of pool
.workerNodes
) {
1523 expect(workerNode
.usage
).toStrictEqual({
1525 executed
: expect
.any(Number
),
1532 runTime
: expect
.objectContaining({
1533 history
: expect
.any(CircularArray
)
1536 history
: new CircularArray()
1540 history
: new CircularArray()
1543 history
: new CircularArray()
1547 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1548 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1551 if (workerNode
.usage
.runTime
.aggregate
== null) {
1552 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1554 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1556 if (workerNode
.usage
.runTime
.average
== null) {
1557 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1559 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1563 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1564 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1565 ).defaultWorkerWeight
1566 ).toBeGreaterThan(0)
1568 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1569 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1570 ).workerVirtualTaskRunTime
1571 ).toBeGreaterThanOrEqual(0)
1572 // We need to clean up the resources after our test
1573 await pool
.destroy()
1576 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1577 const pool
= new DynamicThreadPool(
1580 './tests/worker-files/thread/testWorker.js',
1581 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1583 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1584 const promises
= new Set()
1585 const maxMultiplier
= 2
1586 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1587 promises
.add(pool
.execute())
1589 await Promise
.all(promises
)
1590 for (const workerNode
of pool
.workerNodes
) {
1591 expect(workerNode
.usage
).toStrictEqual({
1593 executed
: expect
.any(Number
),
1600 runTime
: expect
.objectContaining({
1601 history
: expect
.any(CircularArray
)
1604 history
: new CircularArray()
1608 history
: new CircularArray()
1611 history
: new CircularArray()
1615 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1616 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1619 if (workerNode
.usage
.runTime
.aggregate
== null) {
1620 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1622 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1624 if (workerNode
.usage
.runTime
.average
== null) {
1625 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1627 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1631 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1632 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1633 ).defaultWorkerWeight
1634 ).toBeGreaterThan(0)
1636 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1637 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1638 ).workerVirtualTaskRunTime
1639 ).toBeGreaterThanOrEqual(0)
1640 // We need to clean up the resources after our test
1641 await pool
.destroy()
1644 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1645 const pool
= new DynamicThreadPool(
1648 './tests/worker-files/thread/testWorker.js',
1650 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1651 workerChoiceStrategyOptions
: {
1652 runTime
: { median
: true }
1656 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1657 const promises
= new Set()
1658 const maxMultiplier
= 2
1659 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1660 promises
.add(pool
.execute())
1662 await Promise
.all(promises
)
1663 for (const workerNode
of pool
.workerNodes
) {
1664 expect(workerNode
.usage
).toStrictEqual({
1666 executed
: expect
.any(Number
),
1673 runTime
: expect
.objectContaining({
1674 history
: expect
.any(CircularArray
)
1677 history
: new CircularArray()
1681 history
: new CircularArray()
1684 history
: new CircularArray()
1688 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1689 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1692 if (workerNode
.usage
.runTime
.aggregate
== null) {
1693 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1695 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1697 if (workerNode
.usage
.runTime
.median
== null) {
1698 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1700 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1704 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1705 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1706 ).defaultWorkerWeight
1707 ).toBeGreaterThan(0)
1709 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1710 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1711 ).workerVirtualTaskRunTime
1712 ).toBeGreaterThanOrEqual(0)
1713 // We need to clean up the resources after our test
1714 await pool
.destroy()
1717 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1718 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1719 let pool
= new FixedThreadPool(
1721 './tests/worker-files/thread/testWorker.js'
1724 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1725 workerChoiceStrategy
1729 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1730 workerChoiceStrategy
1731 ).previousWorkerNodeKey
1734 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1735 workerChoiceStrategy
1736 ).defaultWorkerWeight
1739 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1740 workerChoiceStrategy
1741 ).workerVirtualTaskRunTime
1743 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1745 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1746 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1750 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1751 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1752 ).previousWorkerNodeKey
1755 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1756 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1757 ).defaultWorkerWeight
1758 ).toBeGreaterThan(0)
1760 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1761 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1762 ).workerVirtualTaskRunTime
1764 await pool
.destroy()
1765 pool
= new DynamicThreadPool(
1768 './tests/worker-files/thread/testWorker.js'
1771 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1772 workerChoiceStrategy
1776 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1777 workerChoiceStrategy
1778 ).previousWorkerNodeKey
1781 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1782 workerChoiceStrategy
1783 ).defaultWorkerWeight
1786 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1787 workerChoiceStrategy
1788 ).workerVirtualTaskRunTime
1790 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1792 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1793 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1797 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1798 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1799 ).previousWorkerNodeKey
1802 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1803 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1804 ).defaultWorkerWeight
1805 ).toBeGreaterThan(0)
1807 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1808 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1809 ).workerVirtualTaskRunTime
1811 // We need to clean up the resources after our test
1812 await pool
.destroy()
1815 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1816 const workerChoiceStrategy
=
1817 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1818 let pool
= new FixedThreadPool(
1820 './tests/worker-files/thread/testWorker.js',
1821 { workerChoiceStrategy
}
1823 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1824 dynamicWorkerUsage
: false,
1825 dynamicWorkerReady
: true
1827 await pool
.destroy()
1828 pool
= new DynamicThreadPool(
1831 './tests/worker-files/thread/testWorker.js',
1832 { workerChoiceStrategy
}
1834 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1835 dynamicWorkerUsage
: false,
1836 dynamicWorkerReady
: true
1838 // We need to clean up the resources after our test
1839 await pool
.destroy()
1842 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1843 const workerChoiceStrategy
=
1844 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1845 let pool
= new FixedThreadPool(
1847 './tests/worker-files/thread/testWorker.js',
1848 { workerChoiceStrategy
}
1851 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1869 await pool
.destroy()
1870 pool
= new DynamicThreadPool(
1873 './tests/worker-files/thread/testWorker.js',
1874 { workerChoiceStrategy
}
1877 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1895 // We need to clean up the resources after our test
1896 await pool
.destroy()
1899 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1900 const pool
= new FixedThreadPool(
1902 './tests/worker-files/thread/testWorker.js',
1904 workerChoiceStrategy
:
1905 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1908 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1909 const promises
= new Set()
1910 const maxMultiplier
= 2
1911 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1912 promises
.add(pool
.execute())
1914 await Promise
.all(promises
)
1915 for (const workerNode
of pool
.workerNodes
) {
1916 expect(workerNode
.usage
).toStrictEqual({
1918 executed
: expect
.any(Number
),
1925 runTime
: expect
.objectContaining({
1926 history
: expect
.any(CircularArray
)
1929 history
: new CircularArray()
1933 history
: new CircularArray()
1936 history
: new CircularArray()
1940 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1941 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1946 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1947 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1948 ).defaultWorkerWeight
1949 ).toBeGreaterThan(0)
1951 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1952 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1956 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1957 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1961 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1962 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1966 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1967 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1968 ).previousWorkerNodeKey
1969 ).toEqual(expect
.any(Number
))
1971 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1972 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1975 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1976 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1977 ).defaultWorkerWeight
1979 // We need to clean up the resources after our test
1980 await pool
.destroy()
1983 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1984 const pool
= new DynamicThreadPool(
1987 './tests/worker-files/thread/testWorker.js',
1989 workerChoiceStrategy
:
1990 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1993 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1994 const promises
= new Set()
1995 const maxMultiplier
= 2
1996 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1997 promises
.add(pool
.execute())
1999 await Promise
.all(promises
)
2000 for (const workerNode
of pool
.workerNodes
) {
2001 expect(workerNode
.usage
).toStrictEqual({
2003 executed
: expect
.any(Number
),
2010 runTime
: expect
.objectContaining({
2011 history
: expect
.any(CircularArray
)
2014 history
: new CircularArray()
2018 history
: new CircularArray()
2021 history
: new CircularArray()
2025 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
2026 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
2031 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2032 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2033 ).defaultWorkerWeight
2034 ).toBeGreaterThan(0)
2036 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2037 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2041 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2042 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2046 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2047 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2051 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2052 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2053 ).previousWorkerNodeKey
2054 ).toEqual(expect
.any(Number
))
2056 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2057 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2060 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2061 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2062 ).defaultWorkerWeight
2064 // We need to clean up the resources after our test
2065 await pool
.destroy()
2068 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
2069 const workerChoiceStrategy
=
2070 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
2071 let pool
= new FixedThreadPool(
2073 './tests/worker-files/thread/testWorker.js'
2076 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2077 workerChoiceStrategy
2081 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2082 workerChoiceStrategy
2086 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2087 workerChoiceStrategy
2091 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2092 workerChoiceStrategy
2093 ).previousWorkerNodeKey
2096 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2097 workerChoiceStrategy
2098 ).defaultWorkerWeight
2101 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2102 workerChoiceStrategy
2105 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2107 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2108 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
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
2124 ).previousWorkerNodeKey
2127 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2128 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2129 ).defaultWorkerWeight
2130 ).toBeGreaterThan(0)
2132 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2133 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2136 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2137 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2138 ).defaultWorkerWeight
2140 await pool
.destroy()
2141 pool
= new DynamicThreadPool(
2144 './tests/worker-files/thread/testWorker.js'
2147 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2148 workerChoiceStrategy
2152 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2153 workerChoiceStrategy
2157 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2158 workerChoiceStrategy
2162 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2163 workerChoiceStrategy
2164 ).previousWorkerNodeKey
2167 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2168 workerChoiceStrategy
2169 ).defaultWorkerWeight
2172 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2173 workerChoiceStrategy
2176 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2178 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2179 pool
.workerChoiceStrategyContext
.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
2195 ).previousWorkerNodeKey
2198 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2199 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2200 ).defaultWorkerWeight
2201 ).toBeGreaterThan(0)
2203 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2204 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2207 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2208 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2209 ).defaultWorkerWeight
2211 // We need to clean up the resources after our test
2212 await pool
.destroy()
2215 it('Verify unknown strategy throw error', () => {
2218 new DynamicThreadPool(
2221 './tests/worker-files/thread/testWorker.js',
2222 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
2224 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")