X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=tests%2Fpools%2Fabstract%2Fabstract-pool.test.js;h=dbda7af72301be5e29ecc1125a691839ada6f85f;hb=d46660cd0cccf38566337876c3fad0c3795aeb94;hp=02baefaf93b5639867d8bb6e852dce39c25dfa57;hpb=5a5fc090d6f7eb9248df1ba5c0ff4d001461b6d4;p=poolifier.git diff --git a/tests/pools/abstract/abstract-pool.test.js b/tests/pools/abstract/abstract-pool.test.js index 02baefaf..dbda7af7 100644 --- a/tests/pools/abstract/abstract-pool.test.js +++ b/tests/pools/abstract/abstract-pool.test.js @@ -5,13 +5,15 @@ const { FixedClusterPool, FixedThreadPool, PoolEvents, - WorkerChoiceStrategies + WorkerChoiceStrategies, + PoolTypes, + WorkerTypes } = require('../../../lib') const { CircularArray } = require('../../../lib/circular-array') const { Queue } = require('../../../lib/queue') describe('Abstract pool test suite', () => { - const numberOfWorkers = 1 + const numberOfWorkers = 2 class StubPoolWithRemoveAllWorker extends FixedThreadPool { removeAllWorker () { this.workerNodes = [] @@ -82,15 +84,17 @@ describe('Abstract pool test suite', () => { numberOfWorkers, './tests/worker-files/thread/testWorker.js' ) - expect(pool.opts.enableEvents).toBe(true) expect(pool.emitter).toBeDefined() + expect(pool.opts.enableEvents).toBe(true) + expect(pool.opts.restartWorkerOnError).toBe(true) expect(pool.opts.enableTasksQueue).toBe(false) expect(pool.opts.tasksQueueOptions).toBeUndefined() expect(pool.opts.workerChoiceStrategy).toBe( WorkerChoiceStrategies.ROUND_ROBIN ) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ - medRunTime: false + medRunTime: false, + medWaitTime: false }) expect(pool.opts.messageHandler).toBeUndefined() expect(pool.opts.errorHandler).toBeUndefined() @@ -105,9 +109,10 @@ describe('Abstract pool test suite', () => { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED, workerChoiceStrategyOptions: { medRunTime: true, - weights: { 0: 300 } + weights: { 0: 300, 1: 200 } }, enableEvents: false, + restartWorkerOnError: false, enableTasksQueue: true, tasksQueueOptions: { concurrency: 2 }, messageHandler: testHandler, @@ -116,8 +121,9 @@ describe('Abstract pool test suite', () => { exitHandler: testHandler } ) - expect(pool.opts.enableEvents).toBe(false) expect(pool.emitter).toBeUndefined() + expect(pool.opts.enableEvents).toBe(false) + expect(pool.opts.restartWorkerOnError).toBe(false) expect(pool.opts.enableTasksQueue).toBe(true) expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 2 }) expect(pool.opts.workerChoiceStrategy).toBe( @@ -125,7 +131,7 @@ describe('Abstract pool test suite', () => { ) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ medRunTime: true, - weights: { 0: 300 } + weights: { 0: 300, 1: 200 } }) expect(pool.opts.messageHandler).toStrictEqual(testHandler) expect(pool.opts.errorHandler).toStrictEqual(testHandler) @@ -177,18 +183,25 @@ describe('Abstract pool test suite', () => { { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } ) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ - medRunTime: false + medRunTime: false, + medWaitTime: false }) for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext .workerChoiceStrategies) { - expect(workerChoiceStrategy.opts).toStrictEqual({ medRunTime: false }) + expect(workerChoiceStrategy.opts).toStrictEqual({ + medRunTime: false, + medWaitTime: false + }) } - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({ + runTime: true, + avgRunTime: true, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false, + elu: false + }) pool.setWorkerChoiceStrategyOptions({ medRunTime: true }) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ medRunTime: true @@ -197,12 +210,15 @@ describe('Abstract pool test suite', () => { .workerChoiceStrategies) { expect(workerChoiceStrategy.opts).toStrictEqual({ medRunTime: true }) } - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(false) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(true) + expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({ + runTime: true, + avgRunTime: false, + medRunTime: true, + waitTime: false, + avgWaitTime: false, + medWaitTime: false, + elu: false + }) pool.setWorkerChoiceStrategyOptions({ medRunTime: false }) expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ medRunTime: false @@ -211,12 +227,15 @@ describe('Abstract pool test suite', () => { .workerChoiceStrategies) { expect(workerChoiceStrategy.opts).toStrictEqual({ medRunTime: false }) } - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime - ).toBe(true) - expect( - pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime - ).toBe(false) + expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({ + runTime: true, + avgRunTime: true, + medRunTime: false, + waitTime: false, + avgWaitTime: false, + medWaitTime: false, + elu: false + }) await pool.destroy() }) @@ -254,6 +273,44 @@ describe('Abstract pool test suite', () => { await pool.destroy() }) + it('Verify that pool info is set', async () => { + let pool = new FixedThreadPool( + numberOfWorkers, + './tests/worker-files/thread/testWorker.js' + ) + expect(pool.info).toStrictEqual({ + type: PoolTypes.fixed, + worker: WorkerTypes.thread, + minSize: numberOfWorkers, + maxSize: numberOfWorkers, + workerNodes: numberOfWorkers, + idleWorkerNodes: numberOfWorkers, + busyWorkerNodes: 0, + runningTasks: 0, + queuedTasks: 0, + maxQueuedTasks: 0 + }) + await pool.destroy() + pool = new DynamicClusterPool( + numberOfWorkers, + numberOfWorkers * 2, + './tests/worker-files/thread/testWorker.js' + ) + expect(pool.info).toStrictEqual({ + type: PoolTypes.dynamic, + worker: WorkerTypes.cluster, + minSize: numberOfWorkers, + maxSize: numberOfWorkers * 2, + workerNodes: numberOfWorkers, + idleWorkerNodes: numberOfWorkers, + busyWorkerNodes: 0, + runningTasks: 0, + queuedTasks: 0, + maxQueuedTasks: 0 + }) + await pool.destroy() + }) + it('Simulate worker not found', async () => { const pool = new StubPoolWithRemoveAllWorker( numberOfWorkers, @@ -275,15 +332,20 @@ describe('Abstract pool test suite', () => { './tests/worker-files/cluster/testWorker.js' ) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage).toBeDefined() - expect(workerNode.tasksUsage.run).toBe(0) - expect(workerNode.tasksUsage.running).toBe(0) - expect(workerNode.tasksUsage.runTime).toBe(0) - expect(workerNode.tasksUsage.runTimeHistory).toBeInstanceOf(CircularArray) - expect(workerNode.tasksUsage.runTimeHistory.length).toBe(0) - expect(workerNode.tasksUsage.avgRunTime).toBe(0) - expect(workerNode.tasksUsage.medRunTime).toBe(0) - expect(workerNode.tasksUsage.error).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + ran: 0, + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0, + elu: undefined + }) } await pool.destroy() }) @@ -306,32 +368,43 @@ describe('Abstract pool test suite', () => { numberOfWorkers, './tests/worker-files/cluster/testWorker.js' ) - const promises = [] - for (let i = 0; i < numberOfWorkers * 2; i++) { - promises.push(pool.execute()) + const promises = new Set() + const maxMultiplier = 2 + for (let i = 0; i < numberOfWorkers * maxMultiplier; i++) { + promises.add(pool.execute()) } for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage).toBeDefined() - expect(workerNode.tasksUsage.run).toBe(0) - expect(workerNode.tasksUsage.running).toBe(numberOfWorkers * 2) - expect(workerNode.tasksUsage.runTime).toBe(0) - expect(workerNode.tasksUsage.runTimeHistory).toBeInstanceOf(CircularArray) - expect(workerNode.tasksUsage.runTimeHistory.length).toBe(0) - expect(workerNode.tasksUsage.avgRunTime).toBe(0) - expect(workerNode.tasksUsage.medRunTime).toBe(0) - expect(workerNode.tasksUsage.error).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + ran: 0, + running: maxMultiplier, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0, + elu: undefined + }) } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage).toBeDefined() - expect(workerNode.tasksUsage.run).toBe(numberOfWorkers * 2) - expect(workerNode.tasksUsage.running).toBe(0) - expect(workerNode.tasksUsage.runTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.runTimeHistory).toBeInstanceOf(CircularArray) - expect(workerNode.tasksUsage.runTimeHistory.length).toBe(0) - expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBe(0) - expect(workerNode.tasksUsage.error).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + ran: 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, + elu: undefined + }) } await pool.destroy() }) @@ -342,33 +415,48 @@ describe('Abstract pool test suite', () => { numberOfWorkers, './tests/worker-files/thread/testWorker.js' ) - const promises = [] - for (let i = 0; i < numberOfWorkers * 2; i++) { - promises.push(pool.execute()) + const promises = new Set() + const maxMultiplier = 2 + for (let i = 0; i < numberOfWorkers * maxMultiplier; i++) { + promises.add(pool.execute()) } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage).toBeDefined() - expect(workerNode.tasksUsage.run).toBe(numberOfWorkers * 2) - expect(workerNode.tasksUsage.running).toBe(0) - expect(workerNode.tasksUsage.runTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.runTimeHistory).toBeInstanceOf(CircularArray) - expect(workerNode.tasksUsage.runTimeHistory.length).toBe(0) - expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0) - expect(workerNode.tasksUsage.medRunTime).toBe(0) - expect(workerNode.tasksUsage.error).toBe(0) + expect(workerNode.tasksUsage).toStrictEqual({ + ran: expect.any(Number), + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0, + elu: undefined + }) + expect(workerNode.tasksUsage.ran).toBeGreaterThan(0) + expect(workerNode.tasksUsage.ran).toBeLessThanOrEqual(maxMultiplier) } pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) for (const workerNode of pool.workerNodes) { - expect(workerNode.tasksUsage).toBeDefined() - expect(workerNode.tasksUsage.run).toBe(0) - expect(workerNode.tasksUsage.running).toBe(0) - expect(workerNode.tasksUsage.runTime).toBe(0) - expect(workerNode.tasksUsage.runTimeHistory).toBeInstanceOf(CircularArray) + expect(workerNode.tasksUsage).toStrictEqual({ + ran: 0, + running: 0, + runTime: 0, + runTimeHistory: expect.any(CircularArray), + avgRunTime: 0, + medRunTime: 0, + waitTime: 0, + waitTimeHistory: expect.any(CircularArray), + avgWaitTime: 0, + medWaitTime: 0, + error: 0, + elu: undefined + }) expect(workerNode.tasksUsage.runTimeHistory.length).toBe(0) - expect(workerNode.tasksUsage.avgRunTime).toBe(0) - expect(workerNode.tasksUsage.medRunTime).toBe(0) - expect(workerNode.tasksUsage.error).toBe(0) + expect(workerNode.tasksUsage.waitTimeHistory.length).toBe(0) } await pool.destroy() }) @@ -379,16 +467,32 @@ describe('Abstract pool test suite', () => { numberOfWorkers, './tests/worker-files/thread/testWorker.js' ) - const promises = [] + const promises = new Set() let poolFull = 0 - pool.emitter.on(PoolEvents.full, () => ++poolFull) + let poolInfo + pool.emitter.on(PoolEvents.full, info => { + ++poolFull + poolInfo = info + }) for (let i = 0; i < numberOfWorkers * 2; i++) { - promises.push(pool.execute()) + promises.add(pool.execute()) } await Promise.all(promises) // The `full` event is triggered when the number of submitted tasks at once reach the max number of workers in the dynamic pool. - // So in total numberOfWorkers + 1 times for a loop submitting up to numberOfWorkers * 2 tasks to the dynamic pool. - expect(poolFull).toBe(numberOfWorkers + 1) + // So in total numberOfWorkers * 2 times for a loop submitting up to numberOfWorkers * 2 tasks to the dynamic pool with min = max = numberOfWorkers. + expect(poolFull).toBe(numberOfWorkers * 2) + expect(poolInfo).toStrictEqual({ + type: PoolTypes.dynamic, + worker: WorkerTypes.thread, + minSize: expect.any(Number), + maxSize: expect.any(Number), + workerNodes: expect.any(Number), + idleWorkerNodes: expect.any(Number), + busyWorkerNodes: expect.any(Number), + runningTasks: expect.any(Number), + queuedTasks: expect.any(Number), + maxQueuedTasks: expect.any(Number) + }) await pool.destroy() }) @@ -397,16 +501,32 @@ describe('Abstract pool test suite', () => { numberOfWorkers, './tests/worker-files/thread/testWorker.js' ) - const promises = [] + const promises = new Set() let poolBusy = 0 - pool.emitter.on(PoolEvents.busy, () => ++poolBusy) + let poolInfo + pool.emitter.on(PoolEvents.busy, info => { + ++poolBusy + poolInfo = info + }) for (let i = 0; i < numberOfWorkers * 2; i++) { - promises.push(pool.execute()) + promises.add(pool.execute()) } await Promise.all(promises) // The `busy` event is triggered when the number of submitted tasks at once reach the number of fixed pool workers. // So in total numberOfWorkers + 1 times for a loop submitting up to numberOfWorkers * 2 tasks to the fixed pool. expect(poolBusy).toBe(numberOfWorkers + 1) + expect(poolInfo).toStrictEqual({ + type: PoolTypes.fixed, + worker: WorkerTypes.thread, + minSize: expect.any(Number), + maxSize: expect.any(Number), + workerNodes: expect.any(Number), + idleWorkerNodes: expect.any(Number), + busyWorkerNodes: expect.any(Number), + runningTasks: expect.any(Number), + queuedTasks: expect.any(Number), + maxQueuedTasks: expect.any(Number) + }) await pool.destroy() })