build: silence sourcemap enablement warning
[poolifier.git] / tests / pools / thread / dynamic.test.js
CommitLineData
a61a0724 1const { expect } = require('expect')
cdace0e5 2const { DynamicThreadPool, PoolEvents } = require('../../../lib')
dbca3be9 3const { TaskFunctions } = require('../../test-types')
bac873bd 4const { sleep, waitWorkerEvents } = require('../../test-utils')
506c2a14 5
a35560ba 6describe('Dynamic thread pool test suite', () => {
e1ffb94f
JB
7 const min = 1
8 const max = 3
9 const pool = new DynamicThreadPool(
10 min,
11 max,
12 './tests/worker-files/thread/testWorker.js',
13 {
041dc05b 14 errorHandler: e => console.error(e)
e1ffb94f
JB
15 }
16 )
17
506c2a14 18 it('Verify that the function is executed in a worker thread', async () => {
6db75ad9 19 let result = await pool.execute({
dbca3be9 20 function: TaskFunctions.fibonacci
6db75ad9 21 })
024daf59 22 expect(result).toBe(75025)
6db75ad9 23 result = await pool.execute({
dbca3be9 24 function: TaskFunctions.factorial
6db75ad9 25 })
70a4f5ea 26 expect(result).toBe(9.33262154439441e157)
506c2a14 27 })
28
29 it('Verify that new workers are created when required, max size is not exceeded and that after a while new workers will die', async () => {
7c0ba920 30 let poolBusy = 0
aee46736 31 pool.emitter.on(PoolEvents.busy, () => ++poolBusy)
cf9aa6c3 32 for (let i = 0; i < max * 2; i++) {
8cbb82eb 33 pool.execute()
506c2a14 34 }
f06e48d8
JB
35 expect(pool.workerNodes.length).toBeLessThanOrEqual(max)
36 expect(pool.workerNodes.length).toBeGreaterThan(min)
94407def 37 expect(poolBusy).toBe(1)
bac873bd 38 const numberOfExitEvents = await waitWorkerEvents(pool, 'exit', max - min)
bdacc2d2 39 expect(numberOfExitEvents).toBe(max - min)
506c2a14 40 })
41
bcf04003 42 it('Verify scale thread up and down is working', async () => {
f06e48d8 43 expect(pool.workerNodes.length).toBe(min)
e211bc18 44 for (let i = 0; i < max * 2; i++) {
6db75ad9 45 pool.execute()
bcf04003 46 }
f06e48d8 47 expect(pool.workerNodes.length).toBe(max)
bac873bd 48 await waitWorkerEvents(pool, 'exit', max - min)
f06e48d8 49 expect(pool.workerNodes.length).toBe(min)
e211bc18 50 for (let i = 0; i < max * 2; i++) {
6db75ad9 51 pool.execute()
bcf04003 52 }
f06e48d8 53 expect(pool.workerNodes.length).toBe(max)
bac873bd 54 await waitWorkerEvents(pool, 'exit', max - min)
f06e48d8 55 expect(pool.workerNodes.length).toBe(min)
bcf04003 56 })
c01733f1 57
506c2a14 58 it('Shutdown test', async () => {
bac873bd 59 const exitPromise = waitWorkerEvents(pool, 'exit', min)
c726f66c 60 expect(pool.emitter.eventNames()).toStrictEqual([PoolEvents.busy])
ef3891a3
JB
61 let poolDestroy = 0
62 pool.emitter.on(PoolEvents.destroy, () => ++poolDestroy)
c726f66c
JB
63 expect(pool.emitter.eventNames()).toStrictEqual([
64 PoolEvents.busy,
65 PoolEvents.destroy
66 ])
1f9a5a44 67 await pool.destroy()
cf597bc5 68 const numberOfExitEvents = await exitPromise
bb9423b7
JB
69 expect(pool.started).toBe(false)
70 expect(pool.workerNodes.length).toBe(0)
cf597bc5 71 expect(numberOfExitEvents).toBe(min)
ef3891a3 72 expect(poolDestroy).toBe(1)
506c2a14 73 })
74
8d3782fa
JB
75 it('Validation of inputs test', () => {
76 expect(() => new DynamicThreadPool(min)).toThrowError(
d4aeae5a 77 'Please specify a file with a worker implementation'
85a3f8a7 78 )
506c2a14 79 })
80
81 it('Should work even without opts in input', async () => {
0fe39c97 82 const pool = new DynamicThreadPool(
e1ffb94f
JB
83 min,
84 max,
76b1e974 85 './tests/worker-files/thread/testWorker.js'
325f50bc 86 )
0fe39c97 87 const res = await pool.execute()
30b963d4 88 expect(res).toStrictEqual({ ok: 1 })
0e2503fc 89 // We need to clean up the resources after our test
0fe39c97 90 await pool.destroy()
506c2a14 91 })
c01733f1 92
1c6fe997 93 it('Verify scale thread up and down is working when long executing task is used:hard', async () => {
c01733f1 94 const longRunningPool = new DynamicThreadPool(
95 min,
96 max,
85a3f8a7 97 './tests/worker-files/thread/longRunningWorkerHardBehavior.js',
4c35177b 98 {
041dc05b 99 errorHandler: e => console.error(e),
73bfd59d
JB
100 onlineHandler: () => console.info('long executing worker is online'),
101 exitHandler: () => console.info('long executing worker exited')
4c35177b 102 }
103 )
f06e48d8 104 expect(longRunningPool.workerNodes.length).toBe(min)
e211bc18 105 for (let i = 0; i < max * 2; i++) {
6db75ad9 106 longRunningPool.execute()
4c35177b 107 }
f06e48d8 108 expect(longRunningPool.workerNodes.length).toBe(max)
bac873bd 109 await waitWorkerEvents(longRunningPool, 'exit', max - min)
f06e48d8 110 expect(longRunningPool.workerNodes.length).toBe(min)
d710242d
JB
111 expect(
112 longRunningPool.workerChoiceStrategyContext.workerChoiceStrategies.get(
113 longRunningPool.workerChoiceStrategyContext.workerChoiceStrategy
9b106837 114 ).nextWorkerNodeKey
d710242d 115 ).toBeLessThan(longRunningPool.workerNodes.length)
0e2503fc
JB
116 // We need to clean up the resources after our test
117 await longRunningPool.destroy()
4c35177b 118 })
119
1c6fe997 120 it('Verify scale thread up and down is working when long executing task is used:soft', async () => {
4c35177b 121 const longRunningPool = new DynamicThreadPool(
122 min,
123 max,
85a3f8a7 124 './tests/worker-files/thread/longRunningWorkerSoftBehavior.js',
c01733f1 125 {
041dc05b 126 errorHandler: e => console.error(e),
73bfd59d
JB
127 onlineHandler: () => console.info('long executing worker is online'),
128 exitHandler: () => console.info('long executing worker exited')
c01733f1 129 }
130 )
f06e48d8 131 expect(longRunningPool.workerNodes.length).toBe(min)
e211bc18 132 for (let i = 0; i < max * 2; i++) {
6db75ad9 133 longRunningPool.execute()
c01733f1 134 }
f06e48d8 135 expect(longRunningPool.workerNodes.length).toBe(max)
920278a2 136 await sleep(1000)
1c6fe997 137 // Here we expect the workerNodes to be at the max size since the task is still executing
f06e48d8 138 expect(longRunningPool.workerNodes.length).toBe(max)
0e2503fc
JB
139 // We need to clean up the resources after our test
140 await longRunningPool.destroy()
c01733f1 141 })
8d3782fa
JB
142
143 it('Verify that a pool with zero worker can be instantiated', async () => {
144 const pool = new DynamicThreadPool(
145 0,
146 max,
147 './tests/worker-files/thread/testWorker.js'
148 )
149 expect(pool).toBeInstanceOf(DynamicThreadPool)
150 // We need to clean up the resources after our test
151 await pool.destroy()
152 })
506c2a14 153})