X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=tests%2Fpools%2Fselection-strategies%2Fselection-strategies.test.js;h=d09dde6f636f29cb3839888889cd0e9a0dd5979f;hb=97a2abc3c559695c4fae99c48d1a2dc636275ccb;hp=7b11bf402e06f981d53dda669809808dbb3c9ca8;hpb=f0829c537c1be61af8472ce3167d7a58fe0c8e69;p=poolifier.git diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index 7b11bf40..d09dde6f 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -2,7 +2,8 @@ const { expect } = require('expect') const { WorkerChoiceStrategies, DynamicThreadPool, - FixedThreadPool + FixedThreadPool, + FixedClusterPool } = require('../../../lib/index') describe('Selection strategies test suite', () => { @@ -11,7 +12,8 @@ describe('Selection strategies test suite', () => { it('Verify that WorkerChoiceStrategies enumeration provides string values', () => { expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN') - expect(WorkerChoiceStrategies.LESS_RECENTLY_USED).toBe('LESS_RECENTLY_USED') + expect(WorkerChoiceStrategies.LESS_USED).toBe('LESS_USED') + expect(WorkerChoiceStrategies.LESS_BUSY).toBe('LESS_BUSY') expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE') expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe( 'WEIGHTED_ROUND_ROBIN' @@ -31,6 +33,22 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) + it('Verify ROUND_ROBIN strategy is taken at pool creation', async () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } + ) + expect(pool.opts.workerChoiceStrategy).toBe( + WorkerChoiceStrategies.ROUND_ROBIN + ) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy().nextWorkerId + ).toBe(0) + // We need to clean up the resources after our test + await pool.destroy() + }) + it('Verify ROUND_ROBIN strategy can be set after pool creation', async () => { const pool = new DynamicThreadPool( min, @@ -52,8 +70,7 @@ describe('Selection strategies test suite', () => { ) pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(false) await pool.destroy() pool = new DynamicThreadPool( @@ -63,8 +80,7 @@ describe('Selection strategies test suite', () => { ) pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(false) // We need to clean up the resources after our test await pool.destroy() @@ -109,41 +125,93 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) - it('Verify LESS_RECENTLY_USED strategy is taken at pool creation', async () => { + it('Verify ROUND_ROBIN strategy runtime behavior', async () => { + let pool = new FixedClusterPool( + max, + './tests/worker-files/cluster/testWorker.js' + ) + let results = new Set() + for (let i = 0; i < max; i++) { + results.add(pool.chooseWorker()[1].id) + } + expect(results.size).toBe(max) + await pool.destroy() + pool = new FixedThreadPool(max, './tests/worker-files/thread/testWorker.js') + results = new Set() + for (let i = 0; i < max; i++) { + results.add(pool.chooseWorker()[1].threadId) + } + expect(results.size).toBe(max) + await pool.destroy() + }) + + it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => { + let pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } + ) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy().nextWorkerId + ).toBeUndefined() + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy().nextWorkerId + ).toBe(0) + await pool.destroy() + pool = new DynamicThreadPool( + min, + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } + ) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.nextWorkerId + ).toBeUndefined() + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.nextWorkerId + ).toBe(0) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_USED strategy is taken at pool creation', async () => { const pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.LESS_RECENTLY_USED } + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } ) expect(pool.opts.workerChoiceStrategy).toBe( - WorkerChoiceStrategies.LESS_RECENTLY_USED + WorkerChoiceStrategies.LESS_USED ) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_RECENTLY_USED strategy can be set after pool creation', async () => { + it('Verify LESS_USED strategy can be set after pool creation', async () => { const pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js' ) - pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_RECENTLY_USED) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED) expect(pool.opts.workerChoiceStrategy).toBe( - WorkerChoiceStrategies.LESS_RECENTLY_USED + WorkerChoiceStrategies.LESS_USED ) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_RECENTLY_USED strategy default tasks usage statistics requirements', async () => { + it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => { let pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js' ) - pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_RECENTLY_USED) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(false) await pool.destroy() pool = new DynamicThreadPool( @@ -151,22 +219,21 @@ describe('Selection strategies test suite', () => { max, './tests/worker-files/thread/testWorker.js' ) - pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_RECENTLY_USED) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(false) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify LESS_RECENTLY_USED strategy can be run in a fixed pool', async () => { + it('Verify LESS_USED strategy can be run in a fixed pool', async () => { const pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.LESS_RECENTLY_USED } + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } ) - // TODO: Create a better test to cover `LessRecentlyUsedWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` const promises = [] for (let i = 0; i < max * 2; i++) { promises.push(pool.execute()) @@ -176,14 +243,96 @@ describe('Selection strategies test suite', () => { await pool.destroy() }) - it('Verify LESS_RECENTLY_USED strategy can be run in a dynamic pool', async () => { + it('Verify LESS_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_RECENTLY_USED } + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } ) - // TODO: Create a better test to cover `LessRecentlyUsedWorkerChoiceStrategy#choose` + // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` + const promises = [] + for (let i = 0; i < max * 2; i++) { + promises.push(pool.execute()) + } + await Promise.all(promises) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy is taken at pool creation', async () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + ) + expect(pool.opts.workerChoiceStrategy).toBe( + WorkerChoiceStrategies.LESS_BUSY + ) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy can be set after pool creation', async () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js' + ) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) + expect(pool.opts.workerChoiceStrategy).toBe( + WorkerChoiceStrategies.LESS_BUSY + ) + // We need to clean up the resources after our test + await pool.destroy() + }) + + it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => { + let pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js' + ) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime + ).toBe(true) + await pool.destroy() + pool = new DynamicThreadPool( + min, + max, + './tests/worker-files/thread/testWorker.js' + ) + pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) + expect( + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime + ).toBe(true) + // 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 () => { + const pool = new FixedThreadPool( + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + ) + // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` + const promises = [] + for (let i = 0; i < max * 2; i++) { + promises.push(pool.execute()) + } + await Promise.all(promises) + // 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 () => { + const pool = new DynamicThreadPool( + min, + max, + './tests/worker-files/thread/testWorker.js', + { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } + ) + // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` const promises = [] for (let i = 0; i < max * 2; i++) { promises.push(pool.execute()) @@ -202,6 +351,20 @@ describe('Selection strategies test suite', () => { expect(pool.opts.workerChoiceStrategy).toBe( WorkerChoiceStrategies.FAIR_SHARE ) + for (const workerKey of pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.keys()) { + expect( + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.get(workerKey).start + ).toBe(0) + expect( + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.get(workerKey).end + ).toBe(0) + } // We need to clean up the resources after our test await pool.destroy() }) @@ -226,8 +389,7 @@ describe('Selection strategies test suite', () => { ) pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(true) await pool.destroy() pool = new DynamicThreadPool( @@ -237,8 +399,7 @@ describe('Selection strategies test suite', () => { ) pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(true) // We need to clean up the resources after our test await pool.destroy() @@ -256,6 +417,10 @@ describe('Selection strategies test suite', () => { promises.push(pool.execute()) } await Promise.all(promises) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.size + ).toBe(pool.workers.length) // We need to clean up the resources after our test await pool.destroy() }) @@ -273,30 +438,36 @@ describe('Selection strategies test suite', () => { promises.push(pool.execute()) } await Promise.all(promises) + // expect( + // pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + // .workerChoiceStrategy.workerLastVirtualTaskTimestamp.size + // ).toBe(pool.workers.length) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify FAIR_SHARE strategy statistics are resets after setting it', async () => { + it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => { let pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js' ) expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() .workerLastVirtualTaskTimestamp ).toBeUndefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) - for (const worker of pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.keys()) { + for (const workerKey of pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.keys()) { expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get( - worker - ).start + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.get(workerKey).start ).toBe(0) expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get( - worker - ).end + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerLastVirtualTaskTimestamp.get(workerKey).end ).toBe(0) } await pool.destroy() @@ -306,20 +477,24 @@ describe('Selection strategies test suite', () => { './tests/worker-files/thread/testWorker.js' ) expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy - .workerLastVirtualTaskTimestamp + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.workerLastVirtualTaskTimestamp ).toBeUndefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) - for (const worker of pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy.workerLastVirtualTaskTimestamp.keys()) { + for (const workerKey of pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerChoiceStrategy.workerLastVirtualTaskTimestamp.keys()) { expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get( - worker - ).start + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(workerKey) + .start ).toBe(0) expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy.workerLastVirtualTaskTimestamp.get( - worker - ).end + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerChoiceStrategy.workerLastVirtualTaskTimestamp.get(workerKey) + .end ).toBe(0) } // We need to clean up the resources after our test @@ -335,6 +510,27 @@ describe('Selection strategies test suite', () => { expect(pool.opts.workerChoiceStrategy).toBe( WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN ) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy().currentWorkerId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .defaultWorkerWeight + ).toBeGreaterThan(0) + for (const workerKey of pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workersTaskRunTime.keys()) { + expect( + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workersTaskRunTime.get(workerKey).weight + ).toBeGreaterThan(0) + expect( + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workersTaskRunTime.get(workerKey).runTime + ).toBe(0) + } // We need to clean up the resources after our test await pool.destroy() }) @@ -359,8 +555,7 @@ describe('Selection strategies test suite', () => { ) pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(true) await pool.destroy() pool = new DynamicThreadPool( @@ -370,8 +565,7 @@ describe('Selection strategies test suite', () => { ) pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) expect( - pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() - .requiredStatistics.runTime + pool.workerChoiceStrategyContext.getRequiredStatistics().runTime ).toBe(true) // We need to clean up the resources after our test await pool.destroy() @@ -389,6 +583,10 @@ describe('Selection strategies test suite', () => { promises.push(pool.execute()) } await Promise.all(promises) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workersTaskRunTime.size + ).toBe(pool.workers.length) // We need to clean up the resources after our test await pool.destroy() }) @@ -406,24 +604,45 @@ describe('Selection strategies test suite', () => { promises.push(pool.execute()) } await Promise.all(promises) + // expect( + // pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + // .workerChoiceStrategy.workersTaskRunTime.size + // ).toBe(pool.workers.length) // We need to clean up the resources after our test await pool.destroy() }) - it('Verify WEIGHTED_ROUND_ROBIN strategy statistics are resets after setting it', async () => { + it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => { let pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js' ) expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy().currentWorkerId + ).toBeUndefined() + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .defaultWorkerWeight + ).toBeUndefined() + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workersTaskRunTime ).toBeUndefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) - for (const worker of pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.keys()) { + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy().currentWorkerId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .defaultWorkerWeight + ).toBeGreaterThan(0) + for (const workerKey of pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workersTaskRunTime.keys()) { expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workersTaskRunTime.get( - worker - ).runTime + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workersTaskRunTime.get(workerKey).runTime ).toBe(0) } await pool.destroy() @@ -433,15 +652,33 @@ describe('Selection strategies test suite', () => { './tests/worker-files/thread/testWorker.js' ) expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy - .workersTaskRunTime + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.currentWorkerId + ).toBeUndefined() + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.defaultWorkerWeight + ).toBeUndefined() + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.workersTaskRunTime ).toBeUndefined() pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) - for (const worker of pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy.workersTaskRunTime.keys()) { + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.currentWorkerId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.getWorkerChoiceStrategy() + .workerChoiceStrategy.defaultWorkerWeight + ).toBeGreaterThan(0) + for (const workerKey of pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerChoiceStrategy.workersTaskRunTime.keys()) { expect( - pool.workerChoiceStrategyContext.workerChoiceStrategy.workerChoiceStrategy.workersTaskRunTime.get( - worker - ).runTime + pool.workerChoiceStrategyContext + .getWorkerChoiceStrategy() + .workerChoiceStrategy.workersTaskRunTime.get(workerKey).runTime ).toBe(0) } // We need to clean up the resources after our test