7b4b9bf536acd131c3dcc1a9e729f90e86ff05e4
1 const { expect
} = require('expect')
2 const { FixedThreadPool
, PoolEvents
} = require('../../../lib/index')
3 const { WorkerFunctions
} = require('../../test-types')
4 const TestUtils
= require('../../test-utils')
6 describe('Fixed thread pool test suite', () => {
7 const numberOfThreads
= 6
8 const pool
= new FixedThreadPool(
10 './tests/worker-files/thread/testWorker.js',
12 errorHandler
: e
=> console
.error(e
)
15 const queuePool
= new FixedThreadPool(
17 './tests/worker-files/thread/testWorker.js',
19 enableTasksQueue
: true,
23 errorHandler
: e
=> console
.error(e
)
26 const emptyPool
= new FixedThreadPool(
28 './tests/worker-files/thread/emptyWorker.js',
29 { exitHandler
: () => console
.log('empty pool worker exited') }
31 const echoPool
= new FixedThreadPool(
33 './tests/worker-files/thread/echoWorker.js'
35 const errorPool
= new FixedThreadPool(
37 './tests/worker-files/thread/errorWorker.js',
39 errorHandler
: e
=> console
.error(e
)
42 const asyncErrorPool
= new FixedThreadPool(
44 './tests/worker-files/thread/asyncErrorWorker.js',
46 errorHandler
: e
=> console
.error(e
)
49 const asyncPool
= new FixedThreadPool(
51 './tests/worker-files/thread/asyncWorker.js'
54 after('Destroy all pools', async () => {
55 // We need to clean up the resources after our test
56 await echoPool
.destroy()
57 await asyncPool
.destroy()
58 await errorPool
.destroy()
59 await asyncErrorPool
.destroy()
60 await emptyPool
.destroy()
61 await queuePool
.destroy()
64 it('Verify that the function is executed in a worker thread', async () => {
65 let result
= await pool
.execute({
66 function: WorkerFunctions
.fibonacci
68 expect(result
).toBe(false)
69 result
= await pool
.execute({
70 function: WorkerFunctions
.factorial
72 expect(result
).toBe(false)
75 it('Verify that is possible to invoke the execute method without input', async () => {
76 const result
= await pool
.execute()
77 expect(result
).toBe(false)
80 it("Verify that 'busy' event is emitted", async () => {
82 pool
.emitter
.on(PoolEvents
.busy
, () => ++poolBusy
)
83 for (let i
= 0; i
< numberOfThreads
* 2; i
++) {
86 // The `busy` event is triggered when the number of submitted tasks at once reach the number of fixed pool workers.
87 // So in total numberOfThreads + 1 times for a loop submitting up to numberOfThreads * 2 tasks to the fixed pool.
88 expect(poolBusy
).toBe(numberOfThreads
+ 1)
91 it('Verify that tasks queuing is working', async () => {
92 const maxMultiplier
= 10
93 for (let i
= 0; i
< numberOfThreads
* maxMultiplier
; i
++) {
96 for (const workerNode
of queuePool
.workerNodes
) {
97 expect(workerNode
.tasksUsage
.running
).toBeLessThanOrEqual(
98 queuePool
.opts
.tasksQueueOptions
.concurrency
100 expect(workerNode
.tasksUsage
.run
).toBe(0)
101 expect(workerNode
.tasksQueue
.length
).toBeGreaterThan(0)
103 // FIXME: wait for ongoing tasks to be executed
105 for (let i
= 0; i
< numberOfThreads
* maxMultiplier
; i
++) {
106 promises
.push(queuePool
.execute())
108 await Promise
.all(promises
)
109 for (const workerNode
of queuePool
.workerNodes
) {
110 expect(workerNode
.tasksUsage
.running
).toBe(0)
111 expect(workerNode
.tasksUsage
.run
).toBeGreaterThan(0)
112 expect(workerNode
.tasksQueue
.length
).toBe(0)
116 it('Verify that is possible to have a worker that return undefined', async () => {
117 const result
= await emptyPool
.execute()
118 expect(result
).toBeUndefined()
121 it('Verify that data are sent to the worker correctly', async () => {
122 const data
= { f
: 10 }
123 const result
= await echoPool
.execute(data
)
124 expect(result
).toStrictEqual(data
)
127 it('Verify that error handling is working properly:sync', async () => {
128 const data
= { f
: 10 }
131 await errorPool
.execute(data
)
135 expect(inError
).toBeDefined()
136 expect(inError
).toBeInstanceOf(Error
)
137 expect(inError
.message
).toBeDefined()
138 expect(typeof inError
.message
=== 'string').toBe(true)
139 expect(inError
.message
).toBe('Error Message from ThreadWorker')
142 it('Verify that error handling is working properly:async', async () => {
143 const data
= { f
: 10 }
146 await asyncErrorPool
.execute(data
)
150 expect(inError
).toBeDefined()
151 expect(inError
).toBeInstanceOf(Error
)
152 expect(inError
.message
).toBeDefined()
153 expect(typeof inError
.message
=== 'string').toBe(true)
154 expect(inError
.message
).toBe('Error Message from ThreadWorker:async')
157 it('Verify that async function is working properly', async () => {
158 const data
= { f
: 10 }
159 const startTime
= performance
.now()
160 const result
= await asyncPool
.execute(data
)
161 const usedTime
= performance
.now() - startTime
162 expect(result
).toStrictEqual(data
)
163 expect(usedTime
).toBeGreaterThanOrEqual(2000)
166 it('Shutdown test', async () => {
167 const exitPromise
= TestUtils
.waitExits(pool
, numberOfThreads
)
169 const numberOfExitEvents
= await exitPromise
170 expect(numberOfExitEvents
).toBe(numberOfThreads
)
173 it('Should work even without opts in input', async () => {
174 const pool1
= new FixedThreadPool(
176 './tests/worker-files/thread/testWorker.js'
178 const res
= await pool1
.execute()
179 expect(res
).toBe(false)
180 // We need to clean up the resources after our test
181 await pool1
.destroy()
184 it('Verify that a pool with zero worker fails', async () => {
186 () => new FixedThreadPool(0, './tests/worker-files/thread/testWorker.js')
187 ).toThrowError(new Error('Cannot instantiate a fixed pool with no worker'))