+const { MessageChannel } = require('worker_threads')
const { expect } = require('expect')
const {
DynamicClusterPool,
FixedClusterPool,
FixedThreadPool,
PoolEvents,
- WorkerChoiceStrategies,
PoolTypes,
+ WorkerChoiceStrategies,
WorkerTypes
} = require('../../../lib')
const { CircularArray } = require('../../../lib/circular-array')
describe('Abstract pool test suite', () => {
const numberOfWorkers = 2
- class StubPoolWithRemoveAllWorker extends FixedThreadPool {
- removeAllWorker () {
- this.workerNodes = []
- this.promiseResponseMap.clear()
- this.handleWorkerReadyMessage = () => {}
- }
- }
class StubPoolWithIsMain extends FixedThreadPool {
isMain () {
return false
expect(() => new FixedThreadPool(numberOfWorkers, '')).toThrowError(
expectedError
)
+ expect(() => new FixedThreadPool(numberOfWorkers, 0)).toThrowError(
+ expectedError
+ )
+ expect(() => new FixedThreadPool(numberOfWorkers, true)).toThrowError(
+ expectedError
+ )
+ expect(
+ () => new FixedThreadPool(numberOfWorkers, './dummyWorker.ts')
+ ).toThrowError(new Error("Cannot find the worker file './dummyWorker.ts'"))
})
it('Verify that numberOfWorkers is checked', () => {
)
})
- it('Verify dynamic pool sizing', () => {
+ it('Verify that dynamic pool sizing is checked', () => {
+ expect(
+ () =>
+ new DynamicClusterPool(
+ 1,
+ undefined,
+ './tests/worker-files/cluster/testWorker.js'
+ )
+ ).toThrowError(
+ new TypeError(
+ 'Cannot instantiate a dynamic pool without specifying the maximum pool size'
+ )
+ )
+ expect(
+ () =>
+ new DynamicThreadPool(
+ 0.5,
+ 1,
+ './tests/worker-files/thread/testWorker.js'
+ )
+ ).toThrowError(
+ new TypeError(
+ 'Cannot instantiate a pool with a non safe integer number of workers'
+ )
+ )
+ expect(
+ () =>
+ new DynamicClusterPool(
+ 0,
+ 0.5,
+ './tests/worker-files/cluster/testWorker.js'
+ )
+ ).toThrowError(
+ new TypeError(
+ 'Cannot instantiate a dynamic pool with a non safe integer maximum pool size'
+ )
+ )
expect(
() =>
new DynamicThreadPool(2, 1, './tests/worker-files/thread/testWorker.js')
)
expect(
() =>
- new DynamicThreadPool(1, 1, './tests/worker-files/thread/testWorker.js')
+ new DynamicClusterPool(
+ 1,
+ 1,
+ './tests/worker-files/cluster/testWorker.js'
+ )
).toThrowError(
new RangeError(
'Cannot instantiate a dynamic pool with a minimum pool size equal to the maximum pool size. Use a fixed pool instead'
)
)
+ expect(
+ () =>
+ new DynamicThreadPool(0, 0, './tests/worker-files/thread/testWorker.js')
+ ).toThrowError(
+ new RangeError(
+ 'Cannot instantiate a dynamic pool with a pool size equal to zero'
+ )
+ )
})
it('Verify that pool options are checked', async () => {
version,
type: PoolTypes.fixed,
worker: WorkerTypes.thread,
- ready: false,
+ ready: true,
strategy: WorkerChoiceStrategies.ROUND_ROBIN,
minSize: numberOfWorkers,
maxSize: numberOfWorkers,
version,
type: PoolTypes.dynamic,
worker: WorkerTypes.cluster,
- ready: false,
+ ready: true,
strategy: WorkerChoiceStrategies.ROUND_ROBIN,
minSize: Math.floor(numberOfWorkers / 2),
maxSize: numberOfWorkers,
await pool.destroy()
})
- it('Simulate worker not found', async () => {
- const pool = new StubPoolWithRemoveAllWorker(
- numberOfWorkers,
- './tests/worker-files/thread/testWorker.js',
- {
- errorHandler: e => console.error(e)
- }
- )
- expect(pool.workerNodes.length).toBe(numberOfWorkers)
- // Simulate worker not found.
- pool.removeAllWorker()
- expect(pool.workerNodes.length).toBe(0)
- await pool.destroy()
- })
-
it('Verify that pool worker tasks usage are initialized', async () => {
const pool = new FixedClusterPool(
numberOfWorkers,
id: expect.any(Number),
type: WorkerTypes.cluster,
dynamic: false,
- ready: false
+ ready: true
})
}
await pool.destroy()
id: expect.any(Number),
type: WorkerTypes.thread,
dynamic: false,
- ready: false
+ ready: true,
+ messageChannel: expect.any(MessageChannel)
})
}
})
})
expect(workerNode.usage.tasks.executed).toBeGreaterThan(0)
expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(maxMultiplier)
+ expect(workerNode.usage.runTime.history.length).toBe(0)
+ expect(workerNode.usage.waitTime.history.length).toBe(0)
+ expect(workerNode.usage.elu.idle.history.length).toBe(0)
+ expect(workerNode.usage.elu.active.history.length).toBe(0)
}
pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
for (const workerNode of pool.workerNodes) {
})
expect(workerNode.usage.runTime.history.length).toBe(0)
expect(workerNode.usage.waitTime.history.length).toBe(0)
+ expect(workerNode.usage.elu.idle.history.length).toBe(0)
+ expect(workerNode.usage.elu.active.history.length).toBe(0)
}
await pool.destroy()
})
})
it("Verify that pool event emitter 'ready' event can register a callback", async () => {
- const pool = new FixedClusterPool(
+ const pool = new DynamicClusterPool(
+ Math.floor(numberOfWorkers / 2),
numberOfWorkers,
'./tests/worker-files/cluster/testWorker.js'
)
- let poolReady = 0
let poolInfo
+ let poolReady = 0
pool.emitter.on(PoolEvents.ready, info => {
++poolReady
poolInfo = info
expect(poolReady).toBe(1)
expect(poolInfo).toStrictEqual({
version,
- type: PoolTypes.fixed,
+ type: PoolTypes.dynamic,
worker: WorkerTypes.cluster,
ready: true,
strategy: WorkerChoiceStrategies.ROUND_ROBIN,