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