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 workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
272 const pool
= new FixedThreadPool(
274 './tests/worker-files/thread/testWorker.js',
275 { workerChoiceStrategy
}
277 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
278 const promises
= new Set()
279 const maxMultiplier
= 2
280 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
281 promises
.add(pool
.execute())
283 await Promise
.all(promises
)
284 for (const workerNode
of pool
.workerNodes
) {
285 expect(workerNode
.usage
).toStrictEqual({
287 executed
: maxMultiplier
,
295 history
: new CircularArray()
298 history
: new CircularArray()
302 history
: new CircularArray()
305 history
: new CircularArray()
311 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
312 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
316 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
317 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
318 ).previousWorkerNodeKey
319 ).toBe(pool
.workerNodes
.length
- 1)
320 // We need to clean up the resources after our test
324 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
325 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
326 const pool
= new DynamicThreadPool(
329 './tests/worker-files/thread/testWorker.js',
330 { workerChoiceStrategy
}
332 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
333 const promises
= new Set()
334 const maxMultiplier
= 2
335 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
336 promises
.add(pool
.execute())
338 await Promise
.all(promises
)
339 for (const workerNode
of pool
.workerNodes
) {
340 expect(workerNode
.usage
).toStrictEqual({
342 executed
: expect
.any(Number
),
350 history
: new CircularArray()
353 history
: new CircularArray()
357 history
: new CircularArray()
360 history
: new CircularArray()
364 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
365 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
370 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
371 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
375 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
376 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
377 ).previousWorkerNodeKey
378 ).toBe(pool
.workerNodes
.length
- 1)
379 // We need to clean up the resources after our test
383 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
384 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
385 let pool
= new FixedClusterPool(
387 './tests/worker-files/cluster/testWorker.js',
388 { workerChoiceStrategy
}
390 let results
= new Set()
391 for (let i
= 0; i
< max
; i
++) {
392 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.id
)
394 expect(results
.size
).toBe(max
)
396 pool
= new FixedThreadPool(
398 './tests/worker-files/thread/testWorker.js',
399 { workerChoiceStrategy
}
402 for (let i
= 0; i
< max
; i
++) {
403 results
.add(pool
.workerNodes
[pool
.chooseWorkerNode()].worker
.threadId
)
405 expect(results
.size
).toBe(max
)
409 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
410 const workerChoiceStrategy
= WorkerChoiceStrategies
.ROUND_ROBIN
411 let pool
= new FixedThreadPool(
413 './tests/worker-files/thread/testWorker.js',
414 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
416 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
418 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
419 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
423 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
424 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
425 ).previousWorkerNodeKey
428 pool
= new DynamicThreadPool(
431 './tests/worker-files/thread/testWorker.js',
432 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
434 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
436 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
437 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
441 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
442 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
443 ).previousWorkerNodeKey
445 // We need to clean up the resources after our test
449 it('Verify LEAST_USED strategy default policy', async () => {
450 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
451 let pool
= new FixedThreadPool(
453 './tests/worker-files/thread/testWorker.js',
454 { workerChoiceStrategy
}
456 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
457 dynamicWorkerUsage
: false,
458 dynamicWorkerReady
: true
461 pool
= new DynamicThreadPool(
464 './tests/worker-files/thread/testWorker.js',
465 { workerChoiceStrategy
}
467 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
468 dynamicWorkerUsage
: false,
469 dynamicWorkerReady
: true
471 // We need to clean up the resources after our test
475 it('Verify LEAST_USED strategy default tasks statistics requirements', async () => {
476 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_USED
477 let pool
= new FixedThreadPool(
479 './tests/worker-files/thread/testWorker.js',
480 { workerChoiceStrategy
}
483 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
502 pool
= new DynamicThreadPool(
505 './tests/worker-files/thread/testWorker.js',
506 { workerChoiceStrategy
}
509 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
527 // We need to clean up the resources after our test
531 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
532 const pool
= new FixedThreadPool(
534 './tests/worker-files/thread/testWorker.js',
535 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
537 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
538 const promises
= new Set()
539 const maxMultiplier
= 2
540 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
541 promises
.add(pool
.execute())
543 await Promise
.all(promises
)
544 for (const workerNode
of pool
.workerNodes
) {
545 expect(workerNode
.usage
).toStrictEqual({
547 executed
: expect
.any(Number
),
555 history
: new CircularArray()
558 history
: new CircularArray()
562 history
: new CircularArray()
565 history
: new CircularArray()
569 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
570 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
574 // We need to clean up the resources after our test
578 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
579 const pool
= new DynamicThreadPool(
582 './tests/worker-files/thread/testWorker.js',
583 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_USED
}
585 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
586 const promises
= new Set()
587 const maxMultiplier
= 2
588 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
589 promises
.add(pool
.execute())
591 await Promise
.all(promises
)
592 for (const workerNode
of pool
.workerNodes
) {
593 expect(workerNode
.usage
).toStrictEqual({
595 executed
: expect
.any(Number
),
603 history
: new CircularArray()
606 history
: new CircularArray()
610 history
: new CircularArray()
613 history
: new CircularArray()
617 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
618 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
622 // We need to clean up the resources after our test
626 it('Verify LEAST_BUSY strategy default policy', async () => {
627 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
628 let pool
= new FixedThreadPool(
630 './tests/worker-files/thread/testWorker.js',
631 { workerChoiceStrategy
}
633 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
634 dynamicWorkerUsage
: false,
635 dynamicWorkerReady
: true
638 pool
= new DynamicThreadPool(
641 './tests/worker-files/thread/testWorker.js',
642 { workerChoiceStrategy
}
644 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
645 dynamicWorkerUsage
: false,
646 dynamicWorkerReady
: true
648 // We need to clean up the resources after our test
652 it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => {
653 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_BUSY
654 let pool
= new FixedThreadPool(
656 './tests/worker-files/thread/testWorker.js',
657 { workerChoiceStrategy
}
660 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
679 pool
= new DynamicThreadPool(
682 './tests/worker-files/thread/testWorker.js',
683 { workerChoiceStrategy
}
686 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
704 // We need to clean up the resources after our test
708 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
709 const pool
= new FixedThreadPool(
711 './tests/worker-files/thread/testWorker.js',
712 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
714 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
715 const promises
= new Set()
716 const maxMultiplier
= 2
717 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
718 promises
.add(pool
.execute())
720 await Promise
.all(promises
)
721 for (const workerNode
of pool
.workerNodes
) {
722 expect(workerNode
.usage
).toStrictEqual({
724 executed
: expect
.any(Number
),
731 runTime
: expect
.objectContaining({
732 history
: expect
.any(CircularArray
)
734 waitTime
: expect
.objectContaining({
735 history
: expect
.any(CircularArray
)
739 history
: new CircularArray()
742 history
: new CircularArray()
746 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
747 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
750 if (workerNode
.usage
.runTime
.aggregate
== null) {
751 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
753 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
755 if (workerNode
.usage
.waitTime
.aggregate
== null) {
756 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
758 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
761 // We need to clean up the resources after our test
765 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
766 const pool
= new DynamicThreadPool(
769 './tests/worker-files/thread/testWorker.js',
770 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_BUSY
}
772 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
773 const promises
= new Set()
774 const maxMultiplier
= 2
775 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
776 promises
.add(pool
.execute())
778 await Promise
.all(promises
)
779 for (const workerNode
of pool
.workerNodes
) {
780 expect(workerNode
.usage
).toStrictEqual({
782 executed
: expect
.any(Number
),
789 runTime
: expect
.objectContaining({
790 history
: expect
.any(CircularArray
)
792 waitTime
: expect
.objectContaining({
793 history
: expect
.any(CircularArray
)
797 history
: new CircularArray()
800 history
: new CircularArray()
804 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
805 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
808 if (workerNode
.usage
.runTime
.aggregate
== null) {
809 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
811 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
813 if (workerNode
.usage
.waitTime
.aggregate
== null) {
814 expect(workerNode
.usage
.waitTime
.aggregate
).toBeUndefined()
816 expect(workerNode
.usage
.waitTime
.aggregate
).toBeGreaterThan(0)
819 // We need to clean up the resources after our test
823 it('Verify LEAST_ELU strategy default policy', async () => {
824 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
825 let pool
= new FixedThreadPool(
827 './tests/worker-files/thread/testWorker.js',
828 { workerChoiceStrategy
}
830 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
831 dynamicWorkerUsage
: false,
832 dynamicWorkerReady
: true
835 pool
= new DynamicThreadPool(
838 './tests/worker-files/thread/testWorker.js',
839 { workerChoiceStrategy
}
841 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
842 dynamicWorkerUsage
: false,
843 dynamicWorkerReady
: true
845 // We need to clean up the resources after our test
849 it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => {
850 const workerChoiceStrategy
= WorkerChoiceStrategies
.LEAST_ELU
851 let pool
= new FixedThreadPool(
853 './tests/worker-files/thread/testWorker.js',
854 { workerChoiceStrategy
}
857 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
876 pool
= new DynamicThreadPool(
879 './tests/worker-files/thread/testWorker.js',
880 { workerChoiceStrategy
}
883 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
901 // We need to clean up the resources after our test
905 it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => {
906 const pool
= new FixedThreadPool(
908 './tests/worker-files/thread/testWorker.js',
909 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
911 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
912 const promises
= new Set()
913 const maxMultiplier
= 2
914 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
915 promises
.add(pool
.execute())
917 await Promise
.all(promises
)
918 for (const workerNode
of pool
.workerNodes
) {
919 expect(workerNode
.usage
).toStrictEqual({
921 executed
: expect
.any(Number
),
929 history
: new CircularArray()
932 history
: new CircularArray()
934 elu
: expect
.objectContaining({
935 idle
: expect
.objectContaining({
936 history
: expect
.any(CircularArray
)
938 active
: expect
.objectContaining({
939 history
: expect
.any(CircularArray
)
943 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
944 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
947 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
948 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
950 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
952 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
953 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
955 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
957 if (workerNode
.usage
.elu
.utilization
== null) {
958 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
960 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
961 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
964 // We need to clean up the resources after our test
968 it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => {
969 const pool
= new DynamicThreadPool(
972 './tests/worker-files/thread/testWorker.js',
973 { workerChoiceStrategy
: WorkerChoiceStrategies
.LEAST_ELU
}
975 // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
976 const promises
= new Set()
977 const maxMultiplier
= 2
978 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
979 promises
.add(pool
.execute())
981 await Promise
.all(promises
)
982 for (const workerNode
of pool
.workerNodes
) {
983 expect(workerNode
.usage
).toStrictEqual({
985 executed
: expect
.any(Number
),
993 history
: new CircularArray()
996 history
: new CircularArray()
998 elu
: expect
.objectContaining({
999 idle
: expect
.objectContaining({
1000 history
: expect
.any(CircularArray
)
1002 active
: expect
.objectContaining({
1003 history
: expect
.any(CircularArray
)
1007 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1008 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1011 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1012 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1014 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1016 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1017 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1019 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1021 if (workerNode
.usage
.elu
.utilization
== null) {
1022 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1024 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1025 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1028 // We need to clean up the resources after our test
1029 await pool
.destroy()
1032 it('Verify FAIR_SHARE strategy default policy', async () => {
1033 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1034 let pool
= new FixedThreadPool(
1036 './tests/worker-files/thread/testWorker.js',
1037 { workerChoiceStrategy
}
1039 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1040 dynamicWorkerUsage
: false,
1041 dynamicWorkerReady
: true
1043 await pool
.destroy()
1044 pool
= new DynamicThreadPool(
1047 './tests/worker-files/thread/testWorker.js',
1048 { workerChoiceStrategy
}
1050 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1051 dynamicWorkerUsage
: false,
1052 dynamicWorkerReady
: true
1054 // We need to clean up the resources after our test
1055 await pool
.destroy()
1058 it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => {
1059 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1060 let pool
= new FixedThreadPool(
1062 './tests/worker-files/thread/testWorker.js',
1063 { workerChoiceStrategy
}
1066 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1084 await pool
.destroy()
1085 pool
= new DynamicThreadPool(
1088 './tests/worker-files/thread/testWorker.js',
1089 { workerChoiceStrategy
}
1092 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1110 // We need to clean up the resources after our test
1111 await pool
.destroy()
1114 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
1115 const pool
= new FixedThreadPool(
1117 './tests/worker-files/thread/testWorker.js',
1118 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1120 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1121 const promises
= new Set()
1122 const maxMultiplier
= 2
1123 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1124 promises
.add(pool
.execute())
1126 await Promise
.all(promises
)
1127 for (const workerNode
of pool
.workerNodes
) {
1128 expect(workerNode
.usage
).toStrictEqual({
1130 executed
: expect
.any(Number
),
1137 runTime
: expect
.objectContaining({
1138 history
: expect
.any(CircularArray
)
1141 history
: new CircularArray()
1143 elu
: expect
.objectContaining({
1144 idle
: expect
.objectContaining({
1145 history
: expect
.any(CircularArray
)
1147 active
: expect
.objectContaining({
1148 history
: expect
.any(CircularArray
)
1152 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1153 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1156 if (workerNode
.usage
.runTime
.aggregate
== null) {
1157 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1159 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1161 if (workerNode
.usage
.runTime
.average
== null) {
1162 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1164 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1166 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1167 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1169 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1171 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1172 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1174 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1176 if (workerNode
.usage
.elu
.utilization
== null) {
1177 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1179 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1180 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1184 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1185 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1186 ).workersVirtualTaskEndTimestamp
.length
1187 ).toBe(pool
.workerNodes
.length
)
1188 // We need to clean up the resources after our test
1189 await pool
.destroy()
1192 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
1193 const pool
= new DynamicThreadPool(
1196 './tests/worker-files/thread/testWorker.js',
1197 { workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
}
1199 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1200 const promises
= new Set()
1201 const maxMultiplier
= 2
1202 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1203 promises
.add(pool
.execute())
1205 await Promise
.all(promises
)
1206 for (const workerNode
of pool
.workerNodes
) {
1207 expect(workerNode
.usage
).toStrictEqual({
1209 executed
: expect
.any(Number
),
1216 runTime
: expect
.objectContaining({
1217 history
: expect
.any(CircularArray
)
1220 history
: new CircularArray()
1222 elu
: expect
.objectContaining({
1223 idle
: expect
.objectContaining({
1224 history
: expect
.any(CircularArray
)
1226 active
: expect
.objectContaining({
1227 history
: expect
.any(CircularArray
)
1231 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1232 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1235 if (workerNode
.usage
.runTime
.aggregate
== null) {
1236 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1238 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1240 if (workerNode
.usage
.runTime
.average
== null) {
1241 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1243 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1245 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1246 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1248 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1250 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1251 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1253 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1255 if (workerNode
.usage
.elu
.utilization
== null) {
1256 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1258 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1259 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1263 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1264 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1265 ).workersVirtualTaskEndTimestamp
.length
1266 ).toBe(pool
.workerNodes
.length
)
1267 // We need to clean up the resources after our test
1268 await pool
.destroy()
1271 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
1272 const pool
= new DynamicThreadPool(
1275 './tests/worker-files/thread/testWorker.js',
1277 workerChoiceStrategy
: WorkerChoiceStrategies
.FAIR_SHARE
,
1278 workerChoiceStrategyOptions
: {
1279 runTime
: { median
: true }
1283 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
1284 const promises
= new Set()
1285 const maxMultiplier
= 2
1286 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1287 promises
.add(pool
.execute())
1289 await Promise
.all(promises
)
1290 for (const workerNode
of pool
.workerNodes
) {
1291 expect(workerNode
.usage
).toStrictEqual({
1293 executed
: expect
.any(Number
),
1300 runTime
: expect
.objectContaining({
1301 history
: expect
.any(CircularArray
)
1304 history
: new CircularArray()
1306 elu
: expect
.objectContaining({
1307 idle
: expect
.objectContaining({
1308 history
: expect
.any(CircularArray
)
1310 active
: expect
.objectContaining({
1311 history
: expect
.any(CircularArray
)
1315 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1316 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1319 if (workerNode
.usage
.runTime
.aggregate
== null) {
1320 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1322 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1324 if (workerNode
.usage
.runTime
.median
== null) {
1325 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1327 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1329 if (workerNode
.usage
.elu
.active
.aggregate
== null) {
1330 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeUndefined()
1332 expect(workerNode
.usage
.elu
.active
.aggregate
).toBeGreaterThan(0)
1334 if (workerNode
.usage
.elu
.idle
.aggregate
== null) {
1335 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeUndefined()
1337 expect(workerNode
.usage
.elu
.idle
.aggregate
).toBeGreaterThanOrEqual(0)
1339 if (workerNode
.usage
.elu
.utilization
== null) {
1340 expect(workerNode
.usage
.elu
.utilization
).toBeUndefined()
1342 expect(workerNode
.usage
.elu
.utilization
).toBeGreaterThanOrEqual(0)
1343 expect(workerNode
.usage
.elu
.utilization
).toBeLessThanOrEqual(1)
1347 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1348 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1349 ).workersVirtualTaskEndTimestamp
.length
1350 ).toBe(pool
.workerNodes
.length
)
1351 // We need to clean up the resources after our test
1352 await pool
.destroy()
1355 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
1356 const workerChoiceStrategy
= WorkerChoiceStrategies
.FAIR_SHARE
1357 let pool
= new FixedThreadPool(
1359 './tests/worker-files/thread/testWorker.js'
1362 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1363 workerChoiceStrategy
1364 ).workersVirtualTaskEndTimestamp
1365 ).toBeInstanceOf(Array
)
1367 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1368 workerChoiceStrategy
1369 ).workersVirtualTaskEndTimestamp
.length
1371 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1372 workerChoiceStrategy
1373 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
1375 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1376 workerChoiceStrategy
1377 ).workersVirtualTaskEndTimestamp
.length
1379 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1381 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1382 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1383 ).workersVirtualTaskEndTimestamp
1384 ).toBeInstanceOf(Array
)
1386 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1387 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1388 ).workersVirtualTaskEndTimestamp
.length
1390 await pool
.destroy()
1391 pool
= new DynamicThreadPool(
1394 './tests/worker-files/thread/testWorker.js'
1397 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1398 workerChoiceStrategy
1399 ).workersVirtualTaskEndTimestamp
1400 ).toBeInstanceOf(Array
)
1402 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1403 workerChoiceStrategy
1404 ).workersVirtualTaskEndTimestamp
.length
1406 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1407 workerChoiceStrategy
1408 ).workersVirtualTaskEndTimestamp
[0] = performance
.now()
1410 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1411 workerChoiceStrategy
1412 ).workersVirtualTaskEndTimestamp
.length
1414 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1416 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1417 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1418 ).workersVirtualTaskEndTimestamp
1419 ).toBeInstanceOf(Array
)
1421 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1422 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1423 ).workersVirtualTaskEndTimestamp
.length
1425 // We need to clean up the resources after our test
1426 await pool
.destroy()
1429 it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1430 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1431 let pool
= new FixedThreadPool(
1433 './tests/worker-files/thread/testWorker.js',
1434 { workerChoiceStrategy
}
1436 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1437 dynamicWorkerUsage
: false,
1438 dynamicWorkerReady
: true
1440 await pool
.destroy()
1441 pool
= new DynamicThreadPool(
1444 './tests/worker-files/thread/testWorker.js',
1445 { workerChoiceStrategy
}
1447 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1448 dynamicWorkerUsage
: false,
1449 dynamicWorkerReady
: true
1451 // We need to clean up the resources after our test
1452 await pool
.destroy()
1455 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1456 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1457 let pool
= new FixedThreadPool(
1459 './tests/worker-files/thread/testWorker.js',
1460 { workerChoiceStrategy
}
1463 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1481 await pool
.destroy()
1482 pool
= new DynamicThreadPool(
1485 './tests/worker-files/thread/testWorker.js',
1486 { workerChoiceStrategy
}
1489 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1507 // We need to clean up the resources after our test
1508 await pool
.destroy()
1511 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1512 const pool
= new FixedThreadPool(
1514 './tests/worker-files/thread/testWorker.js',
1515 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1517 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1518 const promises
= new Set()
1519 const maxMultiplier
= 2
1520 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1521 promises
.add(pool
.execute())
1523 await Promise
.all(promises
)
1524 for (const workerNode
of pool
.workerNodes
) {
1525 expect(workerNode
.usage
).toStrictEqual({
1527 executed
: expect
.any(Number
),
1534 runTime
: expect
.objectContaining({
1535 history
: expect
.any(CircularArray
)
1538 history
: new CircularArray()
1542 history
: new CircularArray()
1545 history
: new CircularArray()
1549 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1550 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1553 if (workerNode
.usage
.runTime
.aggregate
== null) {
1554 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1556 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1558 if (workerNode
.usage
.runTime
.average
== null) {
1559 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1561 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1565 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1566 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1570 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1571 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1572 ).previousWorkerNodeKey
1575 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1576 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1577 ).defaultWorkerWeight
1578 ).toBeGreaterThan(0)
1580 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1581 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1582 ).workerVirtualTaskRunTime
1583 ).toBeGreaterThanOrEqual(0)
1584 // We need to clean up the resources after our test
1585 await pool
.destroy()
1588 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1589 const pool
= new DynamicThreadPool(
1592 './tests/worker-files/thread/testWorker.js',
1593 { workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
}
1595 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1596 const promises
= new Set()
1597 const maxMultiplier
= 2
1598 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1599 promises
.add(pool
.execute())
1601 await Promise
.all(promises
)
1602 for (const workerNode
of pool
.workerNodes
) {
1603 expect(workerNode
.usage
).toStrictEqual({
1605 executed
: expect
.any(Number
),
1612 runTime
: expect
.objectContaining({
1613 history
: expect
.any(CircularArray
)
1616 history
: new CircularArray()
1620 history
: new CircularArray()
1623 history
: new CircularArray()
1627 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1628 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1631 if (workerNode
.usage
.runTime
.aggregate
== null) {
1632 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1634 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1636 if (workerNode
.usage
.runTime
.average
== null) {
1637 expect(workerNode
.usage
.runTime
.average
).toBeUndefined()
1639 expect(workerNode
.usage
.runTime
.average
).toBeGreaterThan(0)
1643 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1644 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1648 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1649 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1650 ).previousWorkerNodeKey
1653 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1654 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1655 ).defaultWorkerWeight
1656 ).toBeGreaterThan(0)
1658 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1659 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1660 ).workerVirtualTaskRunTime
1661 ).toBeGreaterThanOrEqual(0)
1662 // We need to clean up the resources after our test
1663 await pool
.destroy()
1666 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1667 const pool
= new DynamicThreadPool(
1670 './tests/worker-files/thread/testWorker.js',
1672 workerChoiceStrategy
: WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
,
1673 workerChoiceStrategyOptions
: {
1674 runTime
: { median
: true }
1678 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1679 const promises
= new Set()
1680 const maxMultiplier
= 2
1681 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1682 promises
.add(pool
.execute())
1684 await Promise
.all(promises
)
1685 for (const workerNode
of pool
.workerNodes
) {
1686 expect(workerNode
.usage
).toStrictEqual({
1688 executed
: expect
.any(Number
),
1695 runTime
: expect
.objectContaining({
1696 history
: expect
.any(CircularArray
)
1699 history
: new CircularArray()
1703 history
: new CircularArray()
1706 history
: new CircularArray()
1710 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1711 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1714 if (workerNode
.usage
.runTime
.aggregate
== null) {
1715 expect(workerNode
.usage
.runTime
.aggregate
).toBeUndefined()
1717 expect(workerNode
.usage
.runTime
.aggregate
).toBeGreaterThan(0)
1719 if (workerNode
.usage
.runTime
.median
== null) {
1720 expect(workerNode
.usage
.runTime
.median
).toBeUndefined()
1722 expect(workerNode
.usage
.runTime
.median
).toBeGreaterThan(0)
1726 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1727 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1731 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1732 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1733 ).previousWorkerNodeKey
1736 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1737 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1738 ).defaultWorkerWeight
1739 ).toBeGreaterThan(0)
1741 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1742 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1743 ).workerVirtualTaskRunTime
1744 ).toBeGreaterThanOrEqual(0)
1745 // We need to clean up the resources after our test
1746 await pool
.destroy()
1749 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1750 const workerChoiceStrategy
= WorkerChoiceStrategies
.WEIGHTED_ROUND_ROBIN
1751 let pool
= new FixedThreadPool(
1753 './tests/worker-files/thread/testWorker.js'
1756 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1757 workerChoiceStrategy
1761 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1762 workerChoiceStrategy
1763 ).previousWorkerNodeKey
1766 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1767 workerChoiceStrategy
1768 ).defaultWorkerWeight
1771 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1772 workerChoiceStrategy
1773 ).workerVirtualTaskRunTime
1775 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1777 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1778 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1782 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1783 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1784 ).previousWorkerNodeKey
1787 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1788 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1789 ).defaultWorkerWeight
1790 ).toBeGreaterThan(0)
1792 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1793 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1794 ).workerVirtualTaskRunTime
1796 await pool
.destroy()
1797 pool
= new DynamicThreadPool(
1800 './tests/worker-files/thread/testWorker.js'
1803 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1804 workerChoiceStrategy
1808 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1809 workerChoiceStrategy
1810 ).previousWorkerNodeKey
1813 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1814 workerChoiceStrategy
1815 ).defaultWorkerWeight
1818 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1819 workerChoiceStrategy
1820 ).workerVirtualTaskRunTime
1822 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
1824 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1825 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1829 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1830 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1831 ).previousWorkerNodeKey
1834 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1835 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1836 ).defaultWorkerWeight
1837 ).toBeGreaterThan(0)
1839 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1840 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1841 ).workerVirtualTaskRunTime
1843 // We need to clean up the resources after our test
1844 await pool
.destroy()
1847 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
1848 const workerChoiceStrategy
=
1849 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1850 let pool
= new FixedThreadPool(
1852 './tests/worker-files/thread/testWorker.js',
1853 { workerChoiceStrategy
}
1855 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1856 dynamicWorkerUsage
: false,
1857 dynamicWorkerReady
: true
1859 await pool
.destroy()
1860 pool
= new DynamicThreadPool(
1863 './tests/worker-files/thread/testWorker.js',
1864 { workerChoiceStrategy
}
1866 expect(pool
.workerChoiceStrategyContext
.getStrategyPolicy()).toStrictEqual({
1867 dynamicWorkerUsage
: false,
1868 dynamicWorkerReady
: true
1870 // We need to clean up the resources after our test
1871 await pool
.destroy()
1874 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
1875 const workerChoiceStrategy
=
1876 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1877 let pool
= new FixedThreadPool(
1879 './tests/worker-files/thread/testWorker.js',
1880 { workerChoiceStrategy
}
1883 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1901 await pool
.destroy()
1902 pool
= new DynamicThreadPool(
1905 './tests/worker-files/thread/testWorker.js',
1906 { workerChoiceStrategy
}
1909 pool
.workerChoiceStrategyContext
.getTaskStatisticsRequirements()
1927 // We need to clean up the resources after our test
1928 await pool
.destroy()
1931 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1932 const pool
= new FixedThreadPool(
1934 './tests/worker-files/thread/testWorker.js',
1936 workerChoiceStrategy
:
1937 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1940 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1941 const promises
= new Set()
1942 const maxMultiplier
= 2
1943 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
1944 promises
.add(pool
.execute())
1946 await Promise
.all(promises
)
1947 for (const workerNode
of pool
.workerNodes
) {
1948 expect(workerNode
.usage
).toStrictEqual({
1950 executed
: expect
.any(Number
),
1957 runTime
: expect
.objectContaining({
1958 history
: expect
.any(CircularArray
)
1961 history
: new CircularArray()
1965 history
: new CircularArray()
1968 history
: new CircularArray()
1972 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
1973 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
1978 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1979 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1980 ).defaultWorkerWeight
1981 ).toBeGreaterThan(0)
1983 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1984 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1988 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1989 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1993 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1994 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
1998 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
1999 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2000 ).previousWorkerNodeKey
2001 ).toEqual(expect
.any(Number
))
2003 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2004 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2007 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2008 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2009 ).defaultWorkerWeight
2011 // We need to clean up the resources after our test
2012 await pool
.destroy()
2015 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
2016 const pool
= new DynamicThreadPool(
2019 './tests/worker-files/thread/testWorker.js',
2021 workerChoiceStrategy
:
2022 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
2025 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
2026 const promises
= new Set()
2027 const maxMultiplier
= 2
2028 for (let i
= 0; i
< max
* maxMultiplier
; i
++) {
2029 promises
.add(pool
.execute())
2031 await Promise
.all(promises
)
2032 for (const workerNode
of pool
.workerNodes
) {
2033 expect(workerNode
.usage
).toStrictEqual({
2035 executed
: expect
.any(Number
),
2042 runTime
: expect
.objectContaining({
2043 history
: expect
.any(CircularArray
)
2046 history
: new CircularArray()
2050 history
: new CircularArray()
2053 history
: new CircularArray()
2057 expect(workerNode
.usage
.tasks
.executed
).toBeGreaterThanOrEqual(0)
2058 expect(workerNode
.usage
.tasks
.executed
).toBeLessThanOrEqual(
2063 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2064 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2065 ).defaultWorkerWeight
2066 ).toBeGreaterThan(0)
2068 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2069 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2073 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2074 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2078 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2079 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2083 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2084 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2085 ).previousWorkerNodeKey
2086 ).toEqual(expect
.any(Number
))
2088 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2089 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2092 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2093 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2094 ).defaultWorkerWeight
2096 // We need to clean up the resources after our test
2097 await pool
.destroy()
2100 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
2101 const workerChoiceStrategy
=
2102 WorkerChoiceStrategies
.INTERLEAVED_WEIGHTED_ROUND_ROBIN
2103 let pool
= new FixedThreadPool(
2105 './tests/worker-files/thread/testWorker.js'
2108 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2109 workerChoiceStrategy
2113 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2114 workerChoiceStrategy
2118 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2119 workerChoiceStrategy
2123 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2124 workerChoiceStrategy
2125 ).previousWorkerNodeKey
2128 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2129 workerChoiceStrategy
2130 ).defaultWorkerWeight
2133 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2134 workerChoiceStrategy
2137 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2139 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2140 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2144 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2145 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2149 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2150 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2154 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2155 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2156 ).previousWorkerNodeKey
2159 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2160 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2161 ).defaultWorkerWeight
2162 ).toBeGreaterThan(0)
2164 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2165 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2168 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2169 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2170 ).defaultWorkerWeight
2172 await pool
.destroy()
2173 pool
= new DynamicThreadPool(
2176 './tests/worker-files/thread/testWorker.js'
2179 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2180 workerChoiceStrategy
2184 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2185 workerChoiceStrategy
2189 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2190 workerChoiceStrategy
2194 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2195 workerChoiceStrategy
2196 ).previousWorkerNodeKey
2199 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2200 workerChoiceStrategy
2201 ).defaultWorkerWeight
2204 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2205 workerChoiceStrategy
2208 pool
.setWorkerChoiceStrategy(workerChoiceStrategy
)
2210 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2211 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2215 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2216 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2220 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2221 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2225 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2226 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2227 ).previousWorkerNodeKey
2230 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2231 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2232 ).defaultWorkerWeight
2233 ).toBeGreaterThan(0)
2235 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2236 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2239 pool
.workerChoiceStrategyContext
.workerChoiceStrategies
.get(
2240 pool
.workerChoiceStrategyContext
.workerChoiceStrategy
2241 ).defaultWorkerWeight
2243 // We need to clean up the resources after our test
2244 await pool
.destroy()
2247 it('Verify unknown strategy throw error', () => {
2250 new DynamicThreadPool(
2253 './tests/worker-files/thread/testWorker.js',
2254 { workerChoiceStrategy
: 'UNKNOWN_STRATEGY' }
2256 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")