X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=tests%2Fpools%2Fselection-strategies%2Fselection-strategies.test.js;h=8ab971589a7f6af2d34c45e3d1aabf9d84361a42;hb=86bf340d3da6dd24b2963b86e093b23104a2c265;hp=392aafcf3a58a79f6744a37268b01415243a2b97;hpb=a4958de2101f06e7096b83adbca82fcfd532a721;p=poolifier.git diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index 392aafcf..8ab97158 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' @@ -80,12 +81,12 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp + ).workersVirtualTaskEndTimestamp ).toBeInstanceOf(Array) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(0) } else if ( workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN @@ -118,14 +119,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, @@ -134,14 +136,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() }) @@ -186,7 +189,7 @@ describe('Selection strategies test suite', () => { ) let results = new Set() for (let i = 0; i < max; i++) { - results.add(pool.chooseWorkerNode()[1].worker.id) + results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.id) } expect(results.size).toBe(max) await pool.destroy() @@ -197,7 +200,7 @@ describe('Selection strategies test suite', () => { ) results = new Set() for (let i = 0; i < max; i++) { - results.add(pool.chooseWorkerNode()[1].worker.threadId) + results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.threadId) } expect(results.size).toBe(max) await pool.destroy() @@ -243,22 +246,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, @@ -267,25 +271,26 @@ 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 maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { await pool.execute() @@ -294,14 +299,14 @@ describe('Selection strategies test suite', () => { 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 maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { await pool.execute() @@ -310,22 +315,23 @@ describe('Selection strategies test suite', () => { 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, @@ -334,25 +340,26 @@ 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 maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { await pool.execute() @@ -361,14 +368,14 @@ describe('Selection strategies test suite', () => { 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 maxMultiplier = 2 for (let i = 0; i < max * maxMultiplier; i++) { await pool.execute() @@ -385,14 +392,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, @@ -401,14 +409,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() }) @@ -425,15 +434,25 @@ describe('Selection strategies test suite', () => { await pool.execute() } for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() + 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.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(pool.workerNodes.length) // We need to clean up the resources after our test await pool.destroy() @@ -452,21 +471,31 @@ describe('Selection strategies test suite', () => { await pool.execute() } for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() + expect(workerNode.tasksUsage).toStrictEqual({ + run: max * 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.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(pool.workerNodes.length) // We need to clean up the resources after our test 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, @@ -484,15 +513,25 @@ describe('Selection strategies test suite', () => { await pool.execute() } 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).toStrictEqual({ + run: max * 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.medRunTime).toBeGreaterThanOrEqual(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(pool.workerNodes.length) // We need to clean up the resources after our test await pool.destroy() @@ -507,31 +546,31 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp + ).workersVirtualTaskEndTimestamp ).toBeInstanceOf(Array) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(0) pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp[0] = 0 + ).workersVirtualTaskEndTimestamp[0] = performance.now() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(1) pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp + ).workersVirtualTaskEndTimestamp ).toBeInstanceOf(Array) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(0) await pool.destroy() pool = new DynamicThreadPool( @@ -542,31 +581,31 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp + ).workersVirtualTaskEndTimestamp ).toBeInstanceOf(Array) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(0) pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp[0] = 0 + ).workersVirtualTaskEndTimestamp[0] = performance.now() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(1) pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp + ).workersVirtualTaskEndTimestamp ).toBeInstanceOf(Array) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskTimestamp.length + ).workersVirtualTaskEndTimestamp.length ).toBe(0) // We need to clean up the resources after our test await pool.destroy() @@ -580,14 +619,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, @@ -596,14 +636,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() }) @@ -620,10 +661,20 @@ describe('Selection strategies test suite', () => { await pool.execute() } for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() + expect(workerNode.tasksUsage).toStrictEqual({ + run: max * 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.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -652,10 +703,20 @@ describe('Selection strategies test suite', () => { await pool.execute() } for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage.avgRunTime).toBeDefined() + expect(workerNode.tasksUsage).toStrictEqual({ + run: max * 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.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBeDefined() - expect(workerNode.tasksUsage.medRunTime).toBe(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -671,7 +732,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, @@ -689,9 +750,19 @@ describe('Selection strategies test suite', () => { await pool.execute() } 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).toStrictEqual({ + run: max * 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.medRunTime).toBeGreaterThanOrEqual(0) } expect(