From 9eae3c69ca545dc5e4807e2ae059f850e2bd6f9f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Mon, 18 Sep 2023 21:56:50 +0200 Subject: [PATCH] test: cover new pool methods MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- docs/api.md | 23 +++ src/pools/abstract-pool.ts | 5 + src/worker/abstract-worker.ts | 3 +- tests/pools/abstract/abstract-pool.test.js | 154 ++++++++++++++++++--- tests/worker/abstract-worker.test.js | 12 +- 5 files changed, 167 insertions(+), 30 deletions(-) diff --git a/docs/api.md b/docs/api.md index 8e9d59cd..8e3c7707 100644 --- a/docs/api.md +++ b/docs/api.md @@ -8,7 +8,11 @@ - [`pool.execute(data, name, transferList)`](#poolexecutedata-name-transferlist) - [`pool.start()`](#poolstart) - [`pool.destroy()`](#pooldestroy) + - [`pool.hasTaskFunction(name)`](#poolhastaskfunctionname) + - [`pool.addTaskFunction(name, fn)`](#pooladdtaskfunctionname-fn) + - [`pool.removeTaskFunction(name)`](#poolremovetaskfunctionname) - [`pool.listTaskFunctionNames()`](#poollisttaskfunctionnames) + - [`pool.setDefaultTaskFunction(name)`](#poolsetdefaulttaskfunctionname) - [`PoolOptions`](#pooloptions) - [`ThreadPoolOptions extends PoolOptions`](#threadpooloptions-extends-pooloptions) - [`ClusterPoolOptions extends PoolOptions`](#clusterpooloptions-extends-pooloptions) @@ -57,10 +61,29 @@ This method is available on both pool implementations and will call the terminat This method is available on both pool implementations and returns a boolean. +### `pool.addTaskFunction(name, fn)` + +`name` (mandatory) The task function name. +`fn` (mandatory) The task function. + +This method is available on both pool implementations and returns a boolean promise. + +### `pool.removeTaskFunction(name)` + +`name` (mandatory) The task function name. + +This method is available on both pool implementations and returns a boolean promise. + ### `pool.listTaskFunctionNames()` This method is available on both pool implementations and returns an array of the task function names. +### `pool.setDefaultTaskFunction(name)` + +`name` (mandatory) The task function name. + +This method is available on both pool implementations and returns a boolean promise. + ### `PoolOptions` An object with these properties: diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index 3d10391c..7be2cef5 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -858,6 +858,11 @@ export abstract class AbstractPool< /** @inheritDoc */ public async removeTaskFunction (name: string): Promise { + if (!this.taskFunctions.has(name)) { + throw new Error( + 'Cannot remove a task function that does not exist on the pool side' + ) + } this.taskFunctions.delete(name) return await this.sendTaskFunctionOperationToWorkers({ taskFunctionOperation: 'remove', diff --git a/src/worker/abstract-worker.ts b/src/worker/abstract-worker.ts index bc62ade5..8bbd07a7 100644 --- a/src/worker/abstract-worker.ts +++ b/src/worker/abstract-worker.ts @@ -326,6 +326,7 @@ export abstract class AbstractWorker< DEFAULT_TASK_NAME, this.taskFunctions.get(name) as TaskFunction ) + this.sendTaskFunctionNamesToMainWorker() return { status: true } } catch (error) { return { status: false, error: error as Error } @@ -376,7 +377,7 @@ export abstract class AbstractWorker< protected handleTaskFunctionOperationMessage ( message: MessageValue ): void { - const { taskFunctionOperation, taskFunction, taskFunctionName } = message + const { taskFunctionOperation, taskFunctionName, taskFunction } = message let response!: TaskFunctionOperationReturnType if (taskFunctionOperation === 'add') { response = this.addTaskFunction( diff --git a/tests/pools/abstract/abstract-pool.test.js b/tests/pools/abstract/abstract-pool.test.js index 9dca322e..5c27a4b6 100644 --- a/tests/pools/abstract/abstract-pool.test.js +++ b/tests/pools/abstract/abstract-pool.test.js @@ -1243,6 +1243,111 @@ describe('Abstract pool test suite', () => { await pool.destroy() }) + it('Verify that hasTaskFunction() is working', async () => { + const dynamicThreadPool = new DynamicThreadPool( + Math.floor(numberOfWorkers / 2), + numberOfWorkers, + './tests/worker-files/thread/testMultipleTaskFunctionsWorker.js' + ) + await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1) + expect(dynamicThreadPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true) + expect(dynamicThreadPool.hasTaskFunction('jsonIntegerSerialization')).toBe( + true + ) + expect(dynamicThreadPool.hasTaskFunction('factorial')).toBe(true) + expect(dynamicThreadPool.hasTaskFunction('fibonacci')).toBe(true) + expect(dynamicThreadPool.hasTaskFunction('unknown')).toBe(false) + await dynamicThreadPool.destroy() + const fixedClusterPool = new FixedClusterPool( + numberOfWorkers, + './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js' + ) + await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1) + expect(fixedClusterPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true) + expect(fixedClusterPool.hasTaskFunction('jsonIntegerSerialization')).toBe( + true + ) + expect(fixedClusterPool.hasTaskFunction('factorial')).toBe(true) + expect(fixedClusterPool.hasTaskFunction('fibonacci')).toBe(true) + expect(fixedClusterPool.hasTaskFunction('unknown')).toBe(false) + await fixedClusterPool.destroy() + }) + + it('Verify that addTaskFunction() is working', async () => { + const dynamicThreadPool = new DynamicThreadPool( + Math.floor(numberOfWorkers / 2), + numberOfWorkers, + './tests/worker-files/thread/testWorker.js' + ) + await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1) + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'test' + ]) + const echoTaskFunction = data => { + return data + } + await expect( + dynamicThreadPool.addTaskFunction('echo', echoTaskFunction) + ).resolves.toBe(true) + expect(dynamicThreadPool.taskFunctions.size).toBe(1) + expect(dynamicThreadPool.taskFunctions.get('echo')).toStrictEqual( + echoTaskFunction + ) + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'test', + 'echo' + ]) + const taskFunctionData = { test: 'test' } + const echoResult = await dynamicThreadPool.execute(taskFunctionData, 'echo') + expect(echoResult).toStrictEqual(taskFunctionData) + await dynamicThreadPool.destroy() + }) + + it('Verify that removeTaskFunction() is working', async () => { + const dynamicThreadPool = new DynamicThreadPool( + Math.floor(numberOfWorkers / 2), + numberOfWorkers, + './tests/worker-files/thread/testWorker.js' + ) + await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1) + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'test' + ]) + await expect( + dynamicThreadPool.removeTaskFunction('test') + ).rejects.toThrowError( + new Error( + 'Cannot remove a task function that does not exist on the pool side' + ) + ) + const echoTaskFunction = data => { + return data + } + await dynamicThreadPool.addTaskFunction('echo', echoTaskFunction) + expect(dynamicThreadPool.taskFunctions.size).toBe(1) + expect(dynamicThreadPool.taskFunctions.get('echo')).toStrictEqual( + echoTaskFunction + ) + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'test', + 'echo' + ]) + await expect(dynamicThreadPool.removeTaskFunction('echo')).resolves.toBe( + true + ) + expect(dynamicThreadPool.taskFunctions.size).toBe(0) + expect(dynamicThreadPool.taskFunctions.get('echo')).toBeUndefined() + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'test' + ]) + await dynamicThreadPool.destroy() + }) + it('Verify that listTaskFunctionNames() is working', async () => { const dynamicThreadPool = new DynamicThreadPool( Math.floor(numberOfWorkers / 2), @@ -1256,6 +1361,7 @@ describe('Abstract pool test suite', () => { 'factorial', 'fibonacci' ]) + await dynamicThreadPool.destroy() const fixedClusterPool = new FixedClusterPool( numberOfWorkers, './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js' @@ -1267,38 +1373,40 @@ describe('Abstract pool test suite', () => { 'factorial', 'fibonacci' ]) - await dynamicThreadPool.destroy() await fixedClusterPool.destroy() }) - it('Verify that hasTaskFunction() is working', async () => { + it('Verify that setDefaultTaskFunction() is working', async () => { const dynamicThreadPool = new DynamicThreadPool( Math.floor(numberOfWorkers / 2), numberOfWorkers, './tests/worker-files/thread/testMultipleTaskFunctionsWorker.js' ) await waitPoolEvents(dynamicThreadPool, PoolEvents.ready, 1) - expect(dynamicThreadPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true) - expect(dynamicThreadPool.hasTaskFunction('jsonIntegerSerialization')).toBe( - true - ) - expect(dynamicThreadPool.hasTaskFunction('factorial')).toBe(true) - expect(dynamicThreadPool.hasTaskFunction('fibonacci')).toBe(true) - expect(dynamicThreadPool.hasTaskFunction('unknown')).toBe(false) - const fixedClusterPool = new FixedClusterPool( - numberOfWorkers, - './tests/worker-files/cluster/testMultipleTaskFunctionsWorker.js' - ) - await waitPoolEvents(fixedClusterPool, PoolEvents.ready, 1) - expect(dynamicThreadPool.hasTaskFunction(DEFAULT_TASK_NAME)).toBe(true) - expect(dynamicThreadPool.hasTaskFunction('jsonIntegerSerialization')).toBe( - true - ) - expect(dynamicThreadPool.hasTaskFunction('factorial')).toBe(true) - expect(dynamicThreadPool.hasTaskFunction('fibonacci')).toBe(true) - expect(dynamicThreadPool.hasTaskFunction('unknown')).toBe(false) - await dynamicThreadPool.destroy() - await fixedClusterPool.destroy() + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'jsonIntegerSerialization', + 'factorial', + 'fibonacci' + ]) + await expect( + dynamicThreadPool.setDefaultTaskFunction('factorial') + ).resolves.toBe(true) + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'factorial', + 'jsonIntegerSerialization', + 'fibonacci' + ]) + await expect( + dynamicThreadPool.setDefaultTaskFunction('fibonacci') + ).resolves.toBe(true) + expect(dynamicThreadPool.listTaskFunctionNames()).toStrictEqual([ + DEFAULT_TASK_NAME, + 'fibonacci', + 'jsonIntegerSerialization', + 'factorial' + ]) }) it('Verify that multiple task functions worker is working', async () => { diff --git a/tests/worker/abstract-worker.test.js b/tests/worker/abstract-worker.test.js index 13f3ae17..200b05ac 100644 --- a/tests/worker/abstract-worker.test.js +++ b/tests/worker/abstract-worker.test.js @@ -200,7 +200,7 @@ describe('Abstract worker test suite', () => { expect(killHandlerStub.calledOnce).toBe(true) }) - it('Verify that handleError() method works properly', () => { + it('Verify that handleError() method is working properly', () => { const error = new Error('Error as an error') const worker = new ClusterWorker(() => {}) expect(worker.handleError(error)).not.toBeInstanceOf(Error) @@ -215,7 +215,7 @@ describe('Abstract worker test suite', () => { ).toThrowError('Main worker not set') }) - it('Verify that hasTaskFunction() works', () => { + it('Verify that hasTaskFunction() is working', () => { const fn1 = () => { return 1 } @@ -239,7 +239,7 @@ describe('Abstract worker test suite', () => { expect(worker.hasTaskFunction('fn3')).toStrictEqual({ status: false }) }) - it('Verify that addTaskFunction() works', () => { + it('Verify that addTaskFunction() is working', () => { const fn1 = () => { return 1 } @@ -292,7 +292,7 @@ describe('Abstract worker test suite', () => { ) }) - it('Verify that removeTaskFunction() works', () => { + it('Verify that removeTaskFunction() is working', () => { const fn1 = () => { return 1 } @@ -339,7 +339,7 @@ describe('Abstract worker test suite', () => { expect(worker.getMainWorker().send.calledOnce).toBe(true) }) - it('Verify that listTaskFunctionNames() works', () => { + it('Verify that listTaskFunctionNames() is working', () => { const fn1 = () => { return 1 } @@ -354,7 +354,7 @@ describe('Abstract worker test suite', () => { ]) }) - it('Verify that setDefaultTaskFunction() works', () => { + it('Verify that setDefaultTaskFunction() is working', () => { const fn1 = () => { return 1 } -- 2.34.1