refactor: factor out task function validation
[poolifier.git] / tests / pools / abstract / worker-node.test.js
1 const { MessageChannel, Worker } = require('worker_threads')
2 const cluster = require('cluster')
3 const { expect } = require('expect')
4 const { WorkerNode } = require('../../../lib/pools/worker-node')
5 const { WorkerTypes } = require('../../../lib')
6 const { CircularArray } = require('../../../lib/circular-array')
7 const { Deque } = require('../../../lib/deque')
8 const { DEFAULT_TASK_NAME } = require('../../../lib/utils')
9
10 describe('Worker node test suite', () => {
11 const threadWorker = new Worker('./tests/worker-files/thread/testWorker.js')
12 const clusterWorker = cluster.fork()
13 const threadWorkerNode = new WorkerNode(threadWorker, 12)
14 const clusterWorkerNode = new WorkerNode(clusterWorker, 12)
15
16 it('Worker node instantiation', () => {
17 expect(() => new WorkerNode()).toThrowError(
18 new TypeError('Cannot construct a worker node without a worker')
19 )
20 expect(() => new WorkerNode(threadWorker)).toThrowError(
21 new TypeError(
22 'Cannot construct a worker node without a tasks queue back pressure size'
23 )
24 )
25 expect(
26 () => new WorkerNode(threadWorker, 'invalidTasksQueueBackPressureSize')
27 ).toThrowError(
28 new TypeError(
29 'Cannot construct a worker node with a tasks queue back pressure size that is not an integer'
30 )
31 )
32 expect(threadWorkerNode).toBeInstanceOf(WorkerNode)
33 expect(threadWorkerNode.worker).toBe(threadWorker)
34 expect(threadWorkerNode.info).toStrictEqual({
35 id: threadWorker.threadId,
36 type: WorkerTypes.thread,
37 dynamic: false,
38 ready: false
39 })
40 expect(threadWorkerNode.usage).toStrictEqual({
41 tasks: {
42 executed: 0,
43 executing: 0,
44 queued: 0,
45 maxQueued: 0,
46 stolen: 0,
47 failed: 0
48 },
49 runTime: {
50 history: expect.any(CircularArray)
51 },
52 waitTime: {
53 history: expect.any(CircularArray)
54 },
55 elu: {
56 idle: {
57 history: expect.any(CircularArray)
58 },
59 active: {
60 history: expect.any(CircularArray)
61 }
62 }
63 })
64 expect(threadWorkerNode.messageChannel).toBeInstanceOf(MessageChannel)
65 expect(threadWorkerNode.tasksQueueBackPressureSize).toBe(12)
66 expect(threadWorkerNode.tasksQueue).toBeInstanceOf(Deque)
67 expect(threadWorkerNode.tasksQueue.size).toBe(0)
68 expect(threadWorkerNode.taskFunctionsUsage).toBeInstanceOf(Map)
69
70 expect(clusterWorkerNode).toBeInstanceOf(WorkerNode)
71 expect(clusterWorkerNode.worker).toBe(clusterWorker)
72 expect(clusterWorkerNode.info).toStrictEqual({
73 id: clusterWorker.id,
74 type: WorkerTypes.cluster,
75 dynamic: false,
76 ready: false
77 })
78 expect(clusterWorkerNode.usage).toStrictEqual({
79 tasks: {
80 executed: 0,
81 executing: 0,
82 queued: 0,
83 maxQueued: 0,
84 stolen: 0,
85 failed: 0
86 },
87 runTime: {
88 history: expect.any(CircularArray)
89 },
90 waitTime: {
91 history: expect.any(CircularArray)
92 },
93 elu: {
94 idle: {
95 history: expect.any(CircularArray)
96 },
97 active: {
98 history: expect.any(CircularArray)
99 }
100 }
101 })
102 expect(clusterWorkerNode.messageChannel).toBeUndefined()
103 expect(clusterWorkerNode.tasksQueueBackPressureSize).toBe(12)
104 expect(clusterWorkerNode.tasksQueue).toBeInstanceOf(Deque)
105 expect(clusterWorkerNode.tasksQueue.size).toBe(0)
106 expect(clusterWorkerNode.taskFunctionsUsage).toBeInstanceOf(Map)
107 })
108
109 it('Worker node getTaskFunctionWorkerUsage()', () => {
110 expect(() =>
111 threadWorkerNode.getTaskFunctionWorkerUsage('invalidTaskFunction')
112 ).toThrowError(
113 new TypeError(
114 "Cannot get task function worker usage for task function name 'invalidTaskFunction' when task function names list is not yet defined"
115 )
116 )
117 threadWorkerNode.info.taskFunctions = [DEFAULT_TASK_NAME, 'fn1']
118 expect(() =>
119 threadWorkerNode.getTaskFunctionWorkerUsage('invalidTaskFunction')
120 ).toThrowError(
121 new TypeError(
122 "Cannot get task function worker usage for task function name 'invalidTaskFunction' when task function names list has less than 3 elements"
123 )
124 )
125 threadWorkerNode.info.taskFunctions = [DEFAULT_TASK_NAME, 'fn1', 'fn2']
126 expect(
127 threadWorkerNode.getTaskFunctionWorkerUsage(DEFAULT_TASK_NAME)
128 ).toStrictEqual({
129 tasks: {
130 executed: 0,
131 executing: 0,
132 queued: 0,
133 stolen: 0,
134 failed: 0
135 },
136 runTime: {
137 history: expect.any(CircularArray)
138 },
139 waitTime: {
140 history: expect.any(CircularArray)
141 },
142 elu: {
143 idle: {
144 history: expect.any(CircularArray)
145 },
146 active: {
147 history: expect.any(CircularArray)
148 }
149 }
150 })
151 expect(threadWorkerNode.getTaskFunctionWorkerUsage('fn1')).toStrictEqual({
152 tasks: {
153 executed: 0,
154 executing: 0,
155 queued: 0,
156 stolen: 0,
157 failed: 0
158 },
159 runTime: {
160 history: expect.any(CircularArray)
161 },
162 waitTime: {
163 history: expect.any(CircularArray)
164 },
165 elu: {
166 idle: {
167 history: expect.any(CircularArray)
168 },
169 active: {
170 history: expect.any(CircularArray)
171 }
172 }
173 })
174 expect(threadWorkerNode.getTaskFunctionWorkerUsage('fn2')).toStrictEqual({
175 tasks: {
176 executed: 0,
177 executing: 0,
178 queued: 0,
179 stolen: 0,
180 failed: 0
181 },
182 runTime: {
183 history: expect.any(CircularArray)
184 },
185 waitTime: {
186 history: expect.any(CircularArray)
187 },
188 elu: {
189 idle: {
190 history: expect.any(CircularArray)
191 },
192 active: {
193 history: expect.any(CircularArray)
194 }
195 }
196 })
197 expect(threadWorkerNode.taskFunctionsUsage.size).toBe(2)
198 })
199 })