feat: add version to pool information
[poolifier.git] / tests / pools / abstract / abstract-pool.test.js
1 const { expect } = require('expect')
2 const {
3 DynamicClusterPool,
4 DynamicThreadPool,
5 FixedClusterPool,
6 FixedThreadPool,
7 PoolEvents,
8 WorkerChoiceStrategies,
9 PoolTypes,
10 WorkerTypes
11 } = require('../../../lib')
12 const { CircularArray } = require('../../../lib/circular-array')
13 const { Queue } = require('../../../lib/queue')
14 const { version } = require('../../../package.json')
15
16 describe('Abstract pool test suite', () => {
17 const numberOfWorkers = 2
18 class StubPoolWithRemoveAllWorker extends FixedThreadPool {
19 removeAllWorker () {
20 this.workerNodes = []
21 this.promiseResponseMap.clear()
22 }
23 }
24 class StubPoolWithIsMain extends FixedThreadPool {
25 isMain () {
26 return false
27 }
28 }
29
30 it('Simulate pool creation from a non main thread/process', () => {
31 expect(
32 () =>
33 new StubPoolWithIsMain(
34 numberOfWorkers,
35 './tests/worker-files/thread/testWorker.js',
36 {
37 errorHandler: e => console.error(e)
38 }
39 )
40 ).toThrowError('Cannot start a pool from a worker!')
41 })
42
43 it('Verify that filePath is checked', () => {
44 const expectedError = new Error(
45 'Please specify a file with a worker implementation'
46 )
47 expect(() => new FixedThreadPool(numberOfWorkers)).toThrowError(
48 expectedError
49 )
50 expect(() => new FixedThreadPool(numberOfWorkers, '')).toThrowError(
51 expectedError
52 )
53 })
54
55 it('Verify that numberOfWorkers is checked', () => {
56 expect(() => new FixedThreadPool()).toThrowError(
57 'Cannot instantiate a pool without specifying the number of workers'
58 )
59 })
60
61 it('Verify that a negative number of workers is checked', () => {
62 expect(
63 () =>
64 new FixedClusterPool(-1, './tests/worker-files/cluster/testWorker.js')
65 ).toThrowError(
66 new RangeError(
67 'Cannot instantiate a pool with a negative number of workers'
68 )
69 )
70 })
71
72 it('Verify that a non integer number of workers is checked', () => {
73 expect(
74 () =>
75 new FixedThreadPool(0.25, './tests/worker-files/thread/testWorker.js')
76 ).toThrowError(
77 new TypeError(
78 'Cannot instantiate a pool with a non safe integer number of workers'
79 )
80 )
81 })
82
83 it('Verify that pool options are checked', async () => {
84 let pool = new FixedThreadPool(
85 numberOfWorkers,
86 './tests/worker-files/thread/testWorker.js'
87 )
88 expect(pool.emitter).toBeDefined()
89 expect(pool.opts.enableEvents).toBe(true)
90 expect(pool.opts.restartWorkerOnError).toBe(true)
91 expect(pool.opts.enableTasksQueue).toBe(false)
92 expect(pool.opts.tasksQueueOptions).toBeUndefined()
93 expect(pool.opts.workerChoiceStrategy).toBe(
94 WorkerChoiceStrategies.ROUND_ROBIN
95 )
96 expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({
97 runTime: { median: false },
98 waitTime: { median: false },
99 elu: { median: false }
100 })
101 expect(pool.opts.messageHandler).toBeUndefined()
102 expect(pool.opts.errorHandler).toBeUndefined()
103 expect(pool.opts.onlineHandler).toBeUndefined()
104 expect(pool.opts.exitHandler).toBeUndefined()
105 await pool.destroy()
106 const testHandler = () => console.log('test handler executed')
107 pool = new FixedThreadPool(
108 numberOfWorkers,
109 './tests/worker-files/thread/testWorker.js',
110 {
111 workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED,
112 workerChoiceStrategyOptions: {
113 runTime: { median: true },
114 weights: { 0: 300, 1: 200 }
115 },
116 enableEvents: false,
117 restartWorkerOnError: false,
118 enableTasksQueue: true,
119 tasksQueueOptions: { concurrency: 2 },
120 messageHandler: testHandler,
121 errorHandler: testHandler,
122 onlineHandler: testHandler,
123 exitHandler: testHandler
124 }
125 )
126 expect(pool.emitter).toBeUndefined()
127 expect(pool.opts.enableEvents).toBe(false)
128 expect(pool.opts.restartWorkerOnError).toBe(false)
129 expect(pool.opts.enableTasksQueue).toBe(true)
130 expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 2 })
131 expect(pool.opts.workerChoiceStrategy).toBe(
132 WorkerChoiceStrategies.LEAST_USED
133 )
134 expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({
135 runTime: { median: true },
136 weights: { 0: 300, 1: 200 }
137 })
138 expect(pool.opts.messageHandler).toStrictEqual(testHandler)
139 expect(pool.opts.errorHandler).toStrictEqual(testHandler)
140 expect(pool.opts.onlineHandler).toStrictEqual(testHandler)
141 expect(pool.opts.exitHandler).toStrictEqual(testHandler)
142 await pool.destroy()
143 })
144
145 it('Verify that pool options are validated', async () => {
146 expect(
147 () =>
148 new FixedThreadPool(
149 numberOfWorkers,
150 './tests/worker-files/thread/testWorker.js',
151 {
152 workerChoiceStrategy: 'invalidStrategy'
153 }
154 )
155 ).toThrowError("Invalid worker choice strategy 'invalidStrategy'")
156 expect(
157 () =>
158 new FixedThreadPool(
159 numberOfWorkers,
160 './tests/worker-files/thread/testWorker.js',
161 {
162 workerChoiceStrategyOptions: 'invalidOptions'
163 }
164 )
165 ).toThrowError(
166 'Invalid worker choice strategy options: must be a plain object'
167 )
168 expect(
169 () =>
170 new FixedThreadPool(
171 numberOfWorkers,
172 './tests/worker-files/thread/testWorker.js',
173 {
174 workerChoiceStrategyOptions: { weights: {} }
175 }
176 )
177 ).toThrowError(
178 'Invalid worker choice strategy options: must have a weight for each worker node'
179 )
180 expect(
181 () =>
182 new FixedThreadPool(
183 numberOfWorkers,
184 './tests/worker-files/thread/testWorker.js',
185 {
186 workerChoiceStrategyOptions: { measurement: 'invalidMeasurement' }
187 }
188 )
189 ).toThrowError(
190 "Invalid worker choice strategy options: invalid measurement 'invalidMeasurement'"
191 )
192 expect(
193 () =>
194 new FixedThreadPool(
195 numberOfWorkers,
196 './tests/worker-files/thread/testWorker.js',
197 {
198 enableTasksQueue: true,
199 tasksQueueOptions: { concurrency: 0 }
200 }
201 )
202 ).toThrowError("Invalid worker tasks concurrency '0'")
203 expect(
204 () =>
205 new FixedThreadPool(
206 numberOfWorkers,
207 './tests/worker-files/thread/testWorker.js',
208 {
209 enableTasksQueue: true,
210 tasksQueueOptions: 'invalidTasksQueueOptions'
211 }
212 )
213 ).toThrowError('Invalid tasks queue options: must be a plain object')
214 expect(
215 () =>
216 new FixedThreadPool(
217 numberOfWorkers,
218 './tests/worker-files/thread/testWorker.js',
219 {
220 enableTasksQueue: true,
221 tasksQueueOptions: { concurrency: 0.2 }
222 }
223 )
224 ).toThrowError('Invalid worker tasks concurrency: must be an integer')
225 })
226
227 it('Verify that worker choice strategy options can be set', async () => {
228 const pool = new FixedThreadPool(
229 numberOfWorkers,
230 './tests/worker-files/thread/testWorker.js',
231 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
232 )
233 expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({
234 runTime: { median: false },
235 waitTime: { median: false },
236 elu: { median: false }
237 })
238 for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
239 .workerChoiceStrategies) {
240 expect(workerChoiceStrategy.opts).toStrictEqual({
241 runTime: { median: false },
242 waitTime: { median: false },
243 elu: { median: false }
244 })
245 }
246 expect(
247 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
248 ).toStrictEqual({
249 runTime: {
250 aggregate: true,
251 average: true,
252 median: false
253 },
254 waitTime: {
255 aggregate: false,
256 average: false,
257 median: false
258 },
259 elu: {
260 aggregate: true,
261 average: true,
262 median: false
263 }
264 })
265 pool.setWorkerChoiceStrategyOptions({
266 runTime: { median: true },
267 elu: { median: true }
268 })
269 expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({
270 runTime: { median: true },
271 elu: { median: true }
272 })
273 for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
274 .workerChoiceStrategies) {
275 expect(workerChoiceStrategy.opts).toStrictEqual({
276 runTime: { median: true },
277 elu: { median: true }
278 })
279 }
280 expect(
281 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
282 ).toStrictEqual({
283 runTime: {
284 aggregate: true,
285 average: false,
286 median: true
287 },
288 waitTime: {
289 aggregate: false,
290 average: false,
291 median: false
292 },
293 elu: {
294 aggregate: true,
295 average: false,
296 median: true
297 }
298 })
299 pool.setWorkerChoiceStrategyOptions({
300 runTime: { median: false },
301 elu: { median: false }
302 })
303 expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({
304 runTime: { median: false },
305 elu: { median: false }
306 })
307 for (const [, workerChoiceStrategy] of pool.workerChoiceStrategyContext
308 .workerChoiceStrategies) {
309 expect(workerChoiceStrategy.opts).toStrictEqual({
310 runTime: { median: false },
311 elu: { median: false }
312 })
313 }
314 expect(
315 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
316 ).toStrictEqual({
317 runTime: {
318 aggregate: true,
319 average: true,
320 median: false
321 },
322 waitTime: {
323 aggregate: false,
324 average: false,
325 median: false
326 },
327 elu: {
328 aggregate: true,
329 average: true,
330 median: false
331 }
332 })
333 expect(() =>
334 pool.setWorkerChoiceStrategyOptions('invalidWorkerChoiceStrategyOptions')
335 ).toThrowError(
336 'Invalid worker choice strategy options: must be a plain object'
337 )
338 expect(() =>
339 pool.setWorkerChoiceStrategyOptions({ weights: {} })
340 ).toThrowError(
341 'Invalid worker choice strategy options: must have a weight for each worker node'
342 )
343 expect(() =>
344 pool.setWorkerChoiceStrategyOptions({ measurement: 'invalidMeasurement' })
345 ).toThrowError(
346 "Invalid worker choice strategy options: invalid measurement 'invalidMeasurement'"
347 )
348 await pool.destroy()
349 })
350
351 it('Verify that tasks queue can be enabled/disabled', async () => {
352 const pool = new FixedThreadPool(
353 numberOfWorkers,
354 './tests/worker-files/thread/testWorker.js'
355 )
356 expect(pool.opts.enableTasksQueue).toBe(false)
357 expect(pool.opts.tasksQueueOptions).toBeUndefined()
358 pool.enableTasksQueue(true)
359 expect(pool.opts.enableTasksQueue).toBe(true)
360 expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 1 })
361 pool.enableTasksQueue(true, { concurrency: 2 })
362 expect(pool.opts.enableTasksQueue).toBe(true)
363 expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 2 })
364 pool.enableTasksQueue(false)
365 expect(pool.opts.enableTasksQueue).toBe(false)
366 expect(pool.opts.tasksQueueOptions).toBeUndefined()
367 await pool.destroy()
368 })
369
370 it('Verify that tasks queue options can be set', async () => {
371 const pool = new FixedThreadPool(
372 numberOfWorkers,
373 './tests/worker-files/thread/testWorker.js',
374 { enableTasksQueue: true }
375 )
376 expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 1 })
377 pool.setTasksQueueOptions({ concurrency: 2 })
378 expect(pool.opts.tasksQueueOptions).toStrictEqual({ concurrency: 2 })
379 expect(() =>
380 pool.setTasksQueueOptions('invalidTasksQueueOptions')
381 ).toThrowError('Invalid tasks queue options: must be a plain object')
382 expect(() => pool.setTasksQueueOptions({ concurrency: 0 })).toThrowError(
383 "Invalid worker tasks concurrency '0'"
384 )
385 expect(() => pool.setTasksQueueOptions({ concurrency: 0.2 })).toThrowError(
386 'Invalid worker tasks concurrency: must be an integer'
387 )
388 await pool.destroy()
389 })
390
391 it('Verify that pool info is set', async () => {
392 let pool = new FixedThreadPool(
393 numberOfWorkers,
394 './tests/worker-files/thread/testWorker.js'
395 )
396 expect(pool.info).toStrictEqual({
397 version,
398 type: PoolTypes.fixed,
399 worker: WorkerTypes.thread,
400 minSize: numberOfWorkers,
401 maxSize: numberOfWorkers,
402 workerNodes: numberOfWorkers,
403 idleWorkerNodes: numberOfWorkers,
404 busyWorkerNodes: 0,
405 executedTasks: 0,
406 executingTasks: 0,
407 queuedTasks: 0,
408 maxQueuedTasks: 0,
409 failedTasks: 0
410 })
411 await pool.destroy()
412 pool = new DynamicClusterPool(
413 numberOfWorkers,
414 numberOfWorkers * 2,
415 './tests/worker-files/cluster/testWorker.js'
416 )
417 expect(pool.info).toStrictEqual({
418 version,
419 type: PoolTypes.dynamic,
420 worker: WorkerTypes.cluster,
421 minSize: numberOfWorkers,
422 maxSize: numberOfWorkers * 2,
423 workerNodes: numberOfWorkers,
424 idleWorkerNodes: numberOfWorkers,
425 busyWorkerNodes: 0,
426 executedTasks: 0,
427 executingTasks: 0,
428 queuedTasks: 0,
429 maxQueuedTasks: 0,
430 failedTasks: 0
431 })
432 await pool.destroy()
433 })
434
435 it('Simulate worker not found', async () => {
436 const pool = new StubPoolWithRemoveAllWorker(
437 numberOfWorkers,
438 './tests/worker-files/thread/testWorker.js',
439 {
440 errorHandler: e => console.error(e)
441 }
442 )
443 expect(pool.workerNodes.length).toBe(numberOfWorkers)
444 // Simulate worker not found.
445 pool.removeAllWorker()
446 expect(pool.workerNodes.length).toBe(0)
447 await pool.destroy()
448 })
449
450 it('Verify that worker pool tasks usage are initialized', async () => {
451 const pool = new FixedClusterPool(
452 numberOfWorkers,
453 './tests/worker-files/cluster/testWorker.js'
454 )
455 for (const workerNode of pool.workerNodes) {
456 expect(workerNode.usage).toStrictEqual({
457 tasks: {
458 executed: 0,
459 executing: 0,
460 queued: 0,
461 maxQueued: 0,
462 failed: 0
463 },
464 runTime: {
465 aggregate: 0,
466 average: 0,
467 median: 0,
468 history: expect.any(CircularArray)
469 },
470 waitTime: {
471 aggregate: 0,
472 average: 0,
473 median: 0,
474 history: expect.any(CircularArray)
475 },
476 elu: {
477 idle: {
478 aggregate: 0,
479 average: 0,
480 median: 0,
481 history: expect.any(CircularArray)
482 },
483 active: {
484 aggregate: 0,
485 average: 0,
486 median: 0,
487 history: expect.any(CircularArray)
488 },
489 utilization: 0
490 }
491 })
492 }
493 await pool.destroy()
494 })
495
496 it('Verify that worker pool tasks queue are initialized', async () => {
497 const pool = new FixedClusterPool(
498 numberOfWorkers,
499 './tests/worker-files/cluster/testWorker.js'
500 )
501 for (const workerNode of pool.workerNodes) {
502 expect(workerNode.tasksQueue).toBeDefined()
503 expect(workerNode.tasksQueue).toBeInstanceOf(Queue)
504 expect(workerNode.tasksQueue.size).toBe(0)
505 expect(workerNode.tasksQueue.maxSize).toBe(0)
506 }
507 await pool.destroy()
508 })
509
510 it('Verify that worker pool tasks usage are computed', async () => {
511 const pool = new FixedClusterPool(
512 numberOfWorkers,
513 './tests/worker-files/cluster/testWorker.js'
514 )
515 const promises = new Set()
516 const maxMultiplier = 2
517 for (let i = 0; i < numberOfWorkers * maxMultiplier; i++) {
518 promises.add(pool.execute())
519 }
520 for (const workerNode of pool.workerNodes) {
521 expect(workerNode.usage).toStrictEqual({
522 tasks: {
523 executed: 0,
524 executing: maxMultiplier,
525 queued: 0,
526 maxQueued: 0,
527 failed: 0
528 },
529 runTime: {
530 aggregate: 0,
531 average: 0,
532 median: 0,
533 history: expect.any(CircularArray)
534 },
535 waitTime: {
536 aggregate: 0,
537 average: 0,
538 median: 0,
539 history: expect.any(CircularArray)
540 },
541 elu: {
542 idle: {
543 aggregate: 0,
544 average: 0,
545 median: 0,
546 history: expect.any(CircularArray)
547 },
548 active: {
549 aggregate: 0,
550 average: 0,
551 median: 0,
552 history: expect.any(CircularArray)
553 },
554 utilization: 0
555 }
556 })
557 }
558 await Promise.all(promises)
559 for (const workerNode of pool.workerNodes) {
560 expect(workerNode.usage).toStrictEqual({
561 tasks: {
562 executed: maxMultiplier,
563 executing: 0,
564 queued: 0,
565 maxQueued: 0,
566 failed: 0
567 },
568 runTime: {
569 aggregate: 0,
570 average: 0,
571 median: 0,
572 history: expect.any(CircularArray)
573 },
574 waitTime: {
575 aggregate: 0,
576 average: 0,
577 median: 0,
578 history: expect.any(CircularArray)
579 },
580 elu: {
581 idle: {
582 aggregate: 0,
583 average: 0,
584 median: 0,
585 history: expect.any(CircularArray)
586 },
587 active: {
588 aggregate: 0,
589 average: 0,
590 median: 0,
591 history: expect.any(CircularArray)
592 },
593 utilization: 0
594 }
595 })
596 }
597 await pool.destroy()
598 })
599
600 it('Verify that worker pool tasks usage are reset at worker choice strategy change', async () => {
601 const pool = new DynamicThreadPool(
602 numberOfWorkers,
603 numberOfWorkers,
604 './tests/worker-files/thread/testWorker.js'
605 )
606 const promises = new Set()
607 const maxMultiplier = 2
608 for (let i = 0; i < numberOfWorkers * maxMultiplier; i++) {
609 promises.add(pool.execute())
610 }
611 await Promise.all(promises)
612 for (const workerNode of pool.workerNodes) {
613 expect(workerNode.usage).toStrictEqual({
614 tasks: {
615 executed: expect.any(Number),
616 executing: 0,
617 queued: 0,
618 maxQueued: 0,
619 failed: 0
620 },
621 runTime: {
622 aggregate: 0,
623 average: 0,
624 median: 0,
625 history: expect.any(CircularArray)
626 },
627 waitTime: {
628 aggregate: 0,
629 average: 0,
630 median: 0,
631 history: expect.any(CircularArray)
632 },
633 elu: {
634 idle: {
635 aggregate: 0,
636 average: 0,
637 median: 0,
638 history: expect.any(CircularArray)
639 },
640 active: {
641 aggregate: 0,
642 average: 0,
643 median: 0,
644 history: expect.any(CircularArray)
645 },
646 utilization: 0
647 }
648 })
649 expect(workerNode.usage.tasks.executed).toBeGreaterThan(0)
650 expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(maxMultiplier)
651 }
652 pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE)
653 for (const workerNode of pool.workerNodes) {
654 expect(workerNode.usage).toStrictEqual({
655 tasks: {
656 executed: 0,
657 executing: 0,
658 queued: 0,
659 maxQueued: 0,
660 failed: 0
661 },
662 runTime: {
663 aggregate: 0,
664 average: 0,
665 median: 0,
666 history: expect.any(CircularArray)
667 },
668 waitTime: {
669 aggregate: 0,
670 average: 0,
671 median: 0,
672 history: expect.any(CircularArray)
673 },
674 elu: {
675 idle: {
676 aggregate: 0,
677 average: 0,
678 median: 0,
679 history: expect.any(CircularArray)
680 },
681 active: {
682 aggregate: 0,
683 average: 0,
684 median: 0,
685 history: expect.any(CircularArray)
686 },
687 utilization: 0
688 }
689 })
690 expect(workerNode.usage.runTime.history.length).toBe(0)
691 expect(workerNode.usage.waitTime.history.length).toBe(0)
692 }
693 await pool.destroy()
694 })
695
696 it("Verify that pool event emitter 'full' event can register a callback", async () => {
697 const pool = new DynamicThreadPool(
698 numberOfWorkers,
699 numberOfWorkers,
700 './tests/worker-files/thread/testWorker.js'
701 )
702 const promises = new Set()
703 let poolFull = 0
704 let poolInfo
705 pool.emitter.on(PoolEvents.full, info => {
706 ++poolFull
707 poolInfo = info
708 })
709 for (let i = 0; i < numberOfWorkers * 2; i++) {
710 promises.add(pool.execute())
711 }
712 await Promise.all(promises)
713 // The `full` event is triggered when the number of submitted tasks at once reach the max number of workers in the dynamic pool.
714 // So in total numberOfWorkers * 2 times for a loop submitting up to numberOfWorkers * 2 tasks to the dynamic pool with min = max = numberOfWorkers.
715 expect(poolFull).toBe(numberOfWorkers * 2)
716 expect(poolInfo).toStrictEqual({
717 version,
718 type: PoolTypes.dynamic,
719 worker: WorkerTypes.thread,
720 minSize: expect.any(Number),
721 maxSize: expect.any(Number),
722 workerNodes: expect.any(Number),
723 idleWorkerNodes: expect.any(Number),
724 busyWorkerNodes: expect.any(Number),
725 executedTasks: expect.any(Number),
726 executingTasks: expect.any(Number),
727 queuedTasks: expect.any(Number),
728 maxQueuedTasks: expect.any(Number),
729 failedTasks: expect.any(Number)
730 })
731 await pool.destroy()
732 })
733
734 it("Verify that pool event emitter 'busy' event can register a callback", async () => {
735 const pool = new FixedThreadPool(
736 numberOfWorkers,
737 './tests/worker-files/thread/testWorker.js'
738 )
739 const promises = new Set()
740 let poolBusy = 0
741 let poolInfo
742 pool.emitter.on(PoolEvents.busy, info => {
743 ++poolBusy
744 poolInfo = info
745 })
746 for (let i = 0; i < numberOfWorkers * 2; i++) {
747 promises.add(pool.execute())
748 }
749 await Promise.all(promises)
750 // The `busy` event is triggered when the number of submitted tasks at once reach the number of fixed pool workers.
751 // So in total numberOfWorkers + 1 times for a loop submitting up to numberOfWorkers * 2 tasks to the fixed pool.
752 expect(poolBusy).toBe(numberOfWorkers + 1)
753 expect(poolInfo).toStrictEqual({
754 version,
755 type: PoolTypes.fixed,
756 worker: WorkerTypes.thread,
757 minSize: expect.any(Number),
758 maxSize: expect.any(Number),
759 workerNodes: expect.any(Number),
760 idleWorkerNodes: expect.any(Number),
761 busyWorkerNodes: expect.any(Number),
762 executedTasks: expect.any(Number),
763 executingTasks: expect.any(Number),
764 queuedTasks: expect.any(Number),
765 maxQueuedTasks: expect.any(Number),
766 failedTasks: expect.any(Number)
767 })
768 await pool.destroy()
769 })
770
771 it('Verify that multiple tasks worker is working', async () => {
772 const pool = new DynamicClusterPool(
773 numberOfWorkers,
774 numberOfWorkers * 2,
775 './tests/worker-files/cluster/testMultiTasksWorker.js'
776 )
777 const data = { n: 10 }
778 const result0 = await pool.execute(data)
779 expect(result0).toBe(false)
780 const result1 = await pool.execute(data, 'jsonIntegerSerialization')
781 expect(result1).toBe(false)
782 const result2 = await pool.execute(data, 'factorial')
783 expect(result2).toBe(3628800)
784 const result3 = await pool.execute(data, 'fibonacci')
785 expect(result3).toBe(55)
786 })
787 })