refactor: remove duplicate import in examples
[poolifier.git] / tests / worker / abstract-worker.test.js
CommitLineData
a61a0724 1const { expect } = require('expect')
df9aaf20 2const sinon = require('sinon')
8620fb25 3const { ClusterWorker, KillBehaviors, ThreadWorker } = require('../../lib')
df9aaf20 4const { EMPTY_FUNCTION } = require('../../lib/utils')
7fc5cce6 5
e1ffb94f 6describe('Abstract worker test suite', () => {
1f68cede 7 class StubWorkerWithMainWorker extends ThreadWorker {
e1ffb94f
JB
8 constructor (fn, opts) {
9 super(fn, opts)
78cea37e 10 this.mainWorker = undefined
e1ffb94f 11 }
7fc5cce6 12 }
c510fea7 13
e088a00c 14 it('Verify worker options default values', () => {
8620fb25 15 const worker = new ThreadWorker(() => {})
978aad6f 16 expect(worker.opts.maxInactiveTime).toStrictEqual(60000)
e088a00c 17 expect(worker.opts.killBehavior).toBe(KillBehaviors.SOFT)
df9aaf20 18 expect(worker.opts.killHandler).toStrictEqual(EMPTY_FUNCTION)
571227f4 19 expect(worker.opts.async).toBe(undefined)
8620fb25
JB
20 })
21
22 it('Verify that worker options are set at worker creation', () => {
df9aaf20
JB
23 const killHandler = () => {
24 console.info('Worker received kill message')
25 }
8620fb25
JB
26 const worker = new ClusterWorker(() => {}, {
27 maxInactiveTime: 6000,
df9aaf20
JB
28 killBehavior: KillBehaviors.HARD,
29 killHandler,
30 async: true
8620fb25 31 })
978aad6f 32 expect(worker.opts.maxInactiveTime).toStrictEqual(6000)
e088a00c 33 expect(worker.opts.killBehavior).toBe(KillBehaviors.HARD)
df9aaf20 34 expect(worker.opts.killHandler).toStrictEqual(killHandler)
571227f4 35 expect(worker.opts.async).toBe(undefined)
8620fb25
JB
36 })
37
a86b6df1
JB
38 it('Verify that taskFunctions parameter is mandatory', () => {
39 expect(() => new ClusterWorker()).toThrowError(
40 'taskFunctions parameter is mandatory'
41 )
d4aeae5a
JB
42 })
43
f34fdabe 44 it('Verify that taskFunctions parameter is a function or a plain object', () => {
a86b6df1 45 expect(() => new ClusterWorker(0)).toThrowError(
f34fdabe
JB
46 new TypeError(
47 'taskFunctions parameter is not a function or a plain object'
48 )
d4aeae5a
JB
49 )
50 expect(() => new ClusterWorker('')).toThrowError(
f34fdabe
JB
51 new TypeError(
52 'taskFunctions parameter is not a function or a plain object'
53 )
a86b6df1
JB
54 )
55 expect(() => new ClusterWorker(true)).toThrowError(
f34fdabe
JB
56 new TypeError(
57 'taskFunctions parameter is not a function or a plain object'
58 )
d4aeae5a 59 )
a86b6df1 60 expect(() => new ClusterWorker([])).toThrowError(
f34fdabe
JB
61 new TypeError(
62 'taskFunctions parameter is not a function or a plain object'
63 )
a86b6df1
JB
64 )
65 expect(() => new ClusterWorker(new Map())).toThrowError(
f34fdabe
JB
66 new TypeError(
67 'taskFunctions parameter is not a function or a plain object'
68 )
a86b6df1
JB
69 )
70 expect(() => new ClusterWorker(new Set())).toThrowError(
f34fdabe
JB
71 new TypeError(
72 'taskFunctions parameter is not a function or a plain object'
73 )
a86b6df1
JB
74 )
75 expect(() => new ClusterWorker(new WeakMap())).toThrowError(
f34fdabe
JB
76 new TypeError(
77 'taskFunctions parameter is not a function or a plain object'
78 )
d4aeae5a 79 )
a86b6df1 80 expect(() => new ClusterWorker(new WeakSet())).toThrowError(
f34fdabe
JB
81 new TypeError(
82 'taskFunctions parameter is not a function or a plain object'
83 )
a86b6df1 84 )
f34fdabe
JB
85 })
86
87 it('Verify that taskFunctions parameter is not an empty object', () => {
630f0acf 88 expect(() => new ClusterWorker({})).toThrowError(
0d80593b 89 new Error('taskFunctions parameter object is empty')
630f0acf 90 )
a86b6df1
JB
91 })
92
2a69b8c5
JB
93 it('Verify that taskFunctions parameter with unique function is taken', () => {
94 const worker = new ThreadWorker(() => {})
95 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
96 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
97 expect(worker.taskFunctions.size).toBe(2)
98 expect(worker.taskFunctions.get('default')).toStrictEqual(
99 worker.taskFunctions.get('fn1')
100 )
101 })
102
f34fdabe
JB
103 it('Verify that taskFunctions parameter with multiple task functions contains function', () => {
104 const fn1 = () => {
105 return 1
106 }
107 const fn2 = ''
108 expect(() => new ThreadWorker({ fn1, fn2 })).toThrowError(
109 new TypeError('A taskFunctions parameter object value is not a function')
110 )
111 })
112
a86b6df1
JB
113 it('Verify that taskFunctions parameter with multiple task functions is taken', () => {
114 const fn1 = () => {
115 return 1
116 }
117 const fn2 = () => {
118 return 2
119 }
120 const worker = new ClusterWorker({ fn1, fn2 })
2a69b8c5
JB
121 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
122 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
123 expect(worker.taskFunctions.get('fn2')).toBeInstanceOf(Function)
124 expect(worker.taskFunctions.size).toBe(3)
125 expect(worker.taskFunctions.get('default')).toStrictEqual(
126 worker.taskFunctions.get('fn1')
127 )
d4aeae5a
JB
128 })
129
df9aaf20
JB
130 it('Verify that sync kill handler is called when worker is killed', () => {
131 const worker = new ClusterWorker(() => {}, {
132 killHandler: sinon.stub().returns()
133 })
134 worker.isMain = false
135 worker.handleKillMessage()
136 expect(worker.opts.killHandler.calledOnce).toBe(true)
137 })
138
139 // it('Verify that async kill handler is called when worker is killed', () => {
140 // const worker = new ClusterWorker(() => {}, {
141 // killHandler: sinon.stub().resolves()
142 // })
143 // worker.isMain = false
144 // worker.handleKillMessage()
145 // expect(worker.opts.killHandler.calledOnce).toBe(true)
146 // })
147
2431bdb4
JB
148 it('Verify that handleError() method works properly', () => {
149 const error = new Error('Error as an error')
150 const worker = new ClusterWorker(() => {})
151 expect(worker.handleError(error)).not.toBeInstanceOf(Error)
152 expect(worker.handleError(error)).toStrictEqual(error.message)
153 const errorMessage = 'Error as a string'
154 expect(worker.handleError(errorMessage)).toStrictEqual(errorMessage)
7fc5cce6
APA
155 })
156
318d4156 157 it('Verify that getMainWorker() throw error if main worker is not set', () => {
7fc5cce6 158 expect(() =>
1f68cede 159 new StubWorkerWithMainWorker(() => {}).getMainWorker()
e102732c 160 ).toThrowError('Main worker not set')
7fc5cce6 161 })
2a69b8c5
JB
162
163 it('Verify that hasTaskFunction() works', () => {
164 const fn1 = () => {
165 return 1
166 }
167 const fn2 = () => {
168 return 2
169 }
170 const worker = new ClusterWorker({ fn1, fn2 })
171 expect(worker.hasTaskFunction('default')).toBe(true)
172 expect(worker.hasTaskFunction('fn1')).toBe(true)
173 expect(worker.hasTaskFunction('fn2')).toBe(true)
174 expect(worker.hasTaskFunction('fn3')).toBe(false)
175 })
176
177 it('Verify that addTaskFunction() works', () => {
178 const fn1 = () => {
179 return 1
180 }
181 const fn2 = () => {
182 return 2
183 }
184 const fn1Replacement = () => {
185 return 3
186 }
187 const worker = new ThreadWorker(fn1)
188 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
189 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
190 expect(worker.taskFunctions.size).toBe(2)
191 expect(worker.taskFunctions.get('default')).toStrictEqual(
192 worker.taskFunctions.get('fn1')
193 )
194 expect(() => worker.addTaskFunction('default', fn2)).toThrowError(
195 new Error('Cannot add a task function with the default reserved name')
196 )
197 worker.addTaskFunction('fn2', fn2)
198 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
199 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
200 expect(worker.taskFunctions.get('fn2')).toBeInstanceOf(Function)
201 expect(worker.taskFunctions.size).toBe(3)
202 expect(worker.taskFunctions.get('default')).toStrictEqual(
203 worker.taskFunctions.get('fn1')
204 )
205 worker.addTaskFunction('fn1', fn1Replacement)
206 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
207 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
208 expect(worker.taskFunctions.get('fn2')).toBeInstanceOf(Function)
209 expect(worker.taskFunctions.size).toBe(3)
210 expect(worker.taskFunctions.get('default')).toStrictEqual(
211 worker.taskFunctions.get('fn1')
212 )
213 })
214
215 it('Verify that removeTaskFunction() works', () => {
216 const fn1 = () => {
217 return 1
218 }
219 const fn2 = () => {
220 return 2
221 }
135f2a9f 222 const worker = new ClusterWorker({ fn1, fn2 })
2a69b8c5
JB
223 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
224 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
225 expect(worker.taskFunctions.get('fn2')).toBeInstanceOf(Function)
226 expect(worker.taskFunctions.size).toBe(3)
227 expect(worker.taskFunctions.get('default')).toStrictEqual(
228 worker.taskFunctions.get('fn1')
229 )
230 expect(() => worker.removeTaskFunction('default')).toThrowError(
231 new Error(
232 'Cannot remove the task function with the default reserved name'
233 )
234 )
235 expect(() => worker.removeTaskFunction('fn1')).toThrowError(
236 new Error(
237 'Cannot remove the task function used as the default task function'
238 )
239 )
240 worker.removeTaskFunction('fn2')
241 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
242 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
243 expect(worker.taskFunctions.get('fn2')).toBeUndefined()
244 expect(worker.taskFunctions.size).toBe(2)
245 })
246
c50b93fb
JB
247 it('Verify that listTaskFunctions() works', () => {
248 const fn1 = () => {
249 return 1
250 }
251 const fn2 = () => {
252 return 2
253 }
254 const worker = new ClusterWorker({ fn1, fn2 })
255 expect(worker.listTaskFunctions()).toStrictEqual(['default', 'fn1', 'fn2'])
256 })
257
2a69b8c5
JB
258 it('Verify that setDefaultTaskFunction() works', () => {
259 const fn1 = () => {
260 return 1
261 }
262 const fn2 = () => {
263 return 2
264 }
265 const worker = new ThreadWorker({ fn1, fn2 })
266 expect(worker.taskFunctions.get('default')).toBeInstanceOf(Function)
267 expect(worker.taskFunctions.get('fn1')).toBeInstanceOf(Function)
268 expect(worker.taskFunctions.get('fn2')).toBeInstanceOf(Function)
269 expect(worker.taskFunctions.size).toBe(3)
270 expect(worker.taskFunctions.get('default')).toStrictEqual(
271 worker.taskFunctions.get('fn1')
272 )
273 expect(() => worker.setDefaultTaskFunction('default')).toThrowError(
274 new Error(
275 'Cannot set the default task function reserved name as the default task function'
276 )
277 )
278 worker.setDefaultTaskFunction('fn1')
279 expect(worker.taskFunctions.get('default')).toStrictEqual(
280 worker.taskFunctions.get('fn1')
281 )
282 worker.setDefaultTaskFunction('fn2')
283 expect(worker.taskFunctions.get('default')).toStrictEqual(
284 worker.taskFunctions.get('fn2')
285 )
286 })
c510fea7 287})