X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=tests%2Fpools%2Fselection-strategies%2Fselection-strategies.test.js;h=352eb7f636e30788ce90c80d4e6d98c1255ded77;hb=5a31b13c97c664f37f284960713e5261e6b04055;hp=9a85c3ff9de048b9f401a7ca2530b710528219e0;hpb=644992db7bd22ca02c9610f7d622d7973f861d0b;p=poolifier.git diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index 9a85c3ff..352eb7f6 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -5,6 +5,7 @@ const { FixedThreadPool, FixedClusterPool } = require('../../../lib') +const { CircularArray } = require('../../../lib/circular-array') describe('Selection strategies test suite', () => { const min = 0 @@ -12,8 +13,8 @@ describe('Selection strategies test suite', () => { it('Verify that WorkerChoiceStrategies enumeration provides string values', () => { expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN') - expect(WorkerChoiceStrategies.LESS_USED).toBe('LESS_USED') - expect(WorkerChoiceStrategies.LESS_BUSY).toBe('LESS_BUSY') + expect(WorkerChoiceStrategies.LEAST_USED).toBe('LEAST_USED') + expect(WorkerChoiceStrategies.LEAST_BUSY).toBe('LEAST_BUSY') expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE') expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe( 'WEIGHTED_ROUND_ROBIN' @@ -121,14 +122,15 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: false, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) await pool.destroy() pool = new DynamicThreadPool( min, @@ -137,14 +139,15 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: false, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) // We need to clean up the resources after our test await pool.destroy() }) @@ -156,9 +159,26 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } ) // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) + } + await Promise.all(promises) + for (const workerNode of pool.workerNodes) { + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) } // We need to clean up the resources after our test await pool.destroy() @@ -172,9 +192,26 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } ) // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) + } + await Promise.all(promises) + for (const workerNode of pool.workerNodes) { + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) } // We need to clean up the resources after our test await pool.destroy() @@ -246,22 +283,23 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) - it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => { - const workerChoiceStrategy = WorkerChoiceStrategies.LESS_USED + it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => { + const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED let pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: false, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) await pool.destroy() pool = new DynamicThreadPool( min, @@ -270,65 +308,101 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: false, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_USED strategy can be run in a fixed pool', async () => { + it('Verify LEAST_USED strategy can be run in a fixed pool', async () => { const pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } + { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED } ) - // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) + } + await Promise.all(promises) + for (const workerNode of pool.workerNodes) { + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) } // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_USED strategy can be run in a dynamic pool', async () => { + it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => { const pool = new DynamicThreadPool( min, max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } + { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED } ) - // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) + } + await Promise.all(promises) + for (const workerNode of pool.workerNodes) { + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) } // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => { - const workerChoiceStrategy = WorkerChoiceStrategies.LESS_BUSY + it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => { + const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY let pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: true, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) await pool.destroy() pool = new DynamicThreadPool( min, @@ -337,44 +411,85 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: true, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => { + it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => { const pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY } ) - // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) + } + await Promise.all(promises) + for (const workerNode of pool.workerNodes) { + expect(workerNode.tasksUsage).toStrictEqual({ + run: expect.any(Number), + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.run).toBeGreaterThan(0) + expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) } // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => { + it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => { const pool = new DynamicThreadPool( min, max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY } ) - // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) + } + await Promise.all(promises) + for (const workerNode of pool.workerNodes) { + expect(workerNode.tasksUsage).toStrictEqual({ + run: expect.any(Number), + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.run).toBeGreaterThan(0) + expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) } // We need to clean up the resources after our test await pool.destroy() @@ -388,14 +503,15 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: true, + avgRunTime: true, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) await pool.destroy() pool = new DynamicThreadPool( min, @@ -404,14 +520,15 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: true, + avgRunTime: true, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) // We need to clean up the resources after our test await pool.destroy() }) @@ -423,15 +540,28 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } ) // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) } + await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() - expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: expect.any(Number), + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) + expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -450,15 +580,28 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } ) // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) } + await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() - expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: expect.any(Number), + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) + expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -469,7 +612,7 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) - it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median run time statistic', async () => { + it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => { const pool = new DynamicThreadPool( min, max, @@ -482,15 +625,28 @@ describe('Selection strategies test suite', () => { } ) // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) } + await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() - expect(workerNode.tasksUsage.avgRunTime).toBe(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBeGreaterThanOrEqual(0) + expect(workerNode.tasksUsage).toStrictEqual({ + run: maxMultiplier, + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: expect.any(Number), + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) + expect(workerNode.tasksUsage.medRunTime).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -583,14 +739,15 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: true, + avgRunTime: true, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) await pool.destroy() pool = new DynamicThreadPool( min, @@ -599,14 +756,15 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().runTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: true, + avgRunTime: true, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) // We need to clean up the resources after our test await pool.destroy() }) @@ -618,15 +776,30 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } ) // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) } + await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() + expect(workerNode.tasksUsage).toStrictEqual({ + run: expect.any(Number), + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: expect.any(Number), + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.run).toBeGreaterThanOrEqual(0) + expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier) + expect(workerNode.tasksUsage.runTime).toBeGreaterThanOrEqual(0) expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -650,15 +823,30 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } ) // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) } + await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() - expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + run: expect.any(Number), + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: expect.any(Number), + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.run).toBeGreaterThan(0) + expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) + expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -674,7 +862,7 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) - it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median run time statistic', async () => { + it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => { const pool = new DynamicThreadPool( min, max, @@ -687,15 +875,30 @@ describe('Selection strategies test suite', () => { } ) // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` + const promises = new Set() const maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { - await pool.execute() + promises.add(pool.execute()) } + await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() - expect(workerNode.tasksUsage.avgRunTime).toBe(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBeGreaterThanOrEqual(0) + expect(workerNode.tasksUsage).toStrictEqual({ + run: expect.any(Number), + running: 0, + runTime: expect.any(Number), + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: expect.any(Number), + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0 + }) + expect(workerNode.tasksUsage.run).toBeGreaterThan(0) + expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier) + expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0) + expect(workerNode.tasksUsage.medRunTime).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -789,6 +992,45 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) + it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => { + const workerChoiceStrategy = + WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN + let pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy } + ) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: false, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) + await pool.destroy() + pool = new DynamicThreadPool( + min, + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy } + ) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics() + ).toStrictEqual({ + runTime: false, + avgRunTime: false, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false + }) + // We need to clean up the resources after our test + await pool.destroy() + }) + it('Verify unknown strategy throw error', () => { expect( () =>