refactor: cleanup error type
[poolifier.git] / tests / pools / selection-strategies / worker-choice-strategy-context.test.js
CommitLineData
40ad1d27
JB
1const { expect } = require('expect')
2const sinon = require('sinon')
3const {
4 FixedThreadPool,
5 DynamicThreadPool,
6 WorkerChoiceStrategies
cdace0e5 7} = require('../../../lib')
23ff945a
JB
8const {
9 WorkerChoiceStrategyContext
10} = require('../../../lib/pools/selection-strategies/worker-choice-strategy-context')
40ad1d27
JB
11const {
12 RoundRobinWorkerChoiceStrategy
13} = require('../../../lib/pools/selection-strategies/round-robin-worker-choice-strategy')
14const {
e4543b14
JB
15 LeastUsedWorkerChoiceStrategy
16} = require('../../../lib/pools/selection-strategies/least-used-worker-choice-strategy')
168c526f 17const {
e4543b14
JB
18 LeastBusyWorkerChoiceStrategy
19} = require('../../../lib/pools/selection-strategies/least-busy-worker-choice-strategy')
a1c82d5d
JB
20const {
21 LeastEluWorkerChoiceStrategy
22} = require('../../../lib/pools/selection-strategies/least-elu-worker-choice-strategy')
40ad1d27 23const {
23ff945a
JB
24 FairShareWorkerChoiceStrategy
25} = require('../../../lib/pools/selection-strategies/fair-share-worker-choice-strategy')
c15273f2
JB
26const {
27 WeightedRoundRobinWorkerChoiceStrategy
fa6f1296 28} = require('../../../lib/pools/selection-strategies/weighted-round-robin-worker-choice-strategy')
8beab0d3
JB
29const {
30 InterleavedWeightedRoundRobinWorkerChoiceStrategy
31} = require('../../../lib/pools/selection-strategies/interleaved-weighted-round-robin-worker-choice-strategy')
40ad1d27
JB
32
33describe('Worker choice strategy context test suite', () => {
c15273f2
JB
34 const min = 1
35 const max = 3
40ad1d27 36 let fixedPool, dynamicPool
c15273f2
JB
37
38 before(() => {
39 fixedPool = new FixedThreadPool(
40 max,
41 './tests/worker-files/thread/testWorker.js'
42 )
43 dynamicPool = new DynamicThreadPool(
44 min,
45 max,
46 './tests/worker-files/thread/testWorker.js'
47 )
40ad1d27
JB
48 })
49
50 afterEach(() => {
51 sinon.restore()
52 })
53
fd7ebd49
JB
54 after(async () => {
55 await fixedPool.destroy()
56 await dynamicPool.destroy()
c15273f2
JB
57 })
58
2285a040
JB
59 it('Verify that constructor() initializes the context with all the available worker choice strategies', () => {
60 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
61 fixedPool
62 )
63 expect(workerChoiceStrategyContext.workerChoiceStrategies.size).toBe(
64 Object.keys(WorkerChoiceStrategies).length
65 )
66 })
67
40ad1d27
JB
68 it('Verify that execute() return the worker chosen by the strategy with fixed pool', () => {
69 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
70 fixedPool
71 )
72 const WorkerChoiceStrategyStub = sinon.createStubInstance(
73 RoundRobinWorkerChoiceStrategy,
74 {
c923ce56 75 choose: sinon.stub().returns(0)
40ad1d27
JB
76 }
77 )
d710242d 78 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
95c83464
JB
79 WorkerChoiceStrategies.ROUND_ROBIN
80 )
81 workerChoiceStrategyContext.workerChoiceStrategies.set(
d710242d 82 workerChoiceStrategyContext.workerChoiceStrategy,
95c83464
JB
83 WorkerChoiceStrategyStub
84 )
c923ce56 85 const chosenWorkerKey = workerChoiceStrategyContext.execute()
40ad1d27 86 expect(
95c83464 87 workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 88 workerChoiceStrategyContext.workerChoiceStrategy
95c83464 89 ).choose.calledOnce
40ad1d27 90 ).toBe(true)
c923ce56 91 expect(chosenWorkerKey).toBe(0)
40ad1d27
JB
92 })
93
4ba8492f 94 it('Verify that execute() throws error if null or undefined is returned after retries', () => {
527e715f
JB
95 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
96 fixedPool
97 )
fa418e12 98 const WorkerChoiceStrategyUndefinedStub = sinon.createStubInstance(
527e715f
JB
99 RoundRobinWorkerChoiceStrategy,
100 {
101 choose: sinon.stub().returns(undefined)
102 }
103 )
fa418e12
JB
104 const WorkerChoiceStrategyNullStub = sinon.createStubInstance(
105 RoundRobinWorkerChoiceStrategy,
106 {
107 choose: sinon.stub().returns(null)
108 }
109 )
527e715f
JB
110 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
111 WorkerChoiceStrategies.ROUND_ROBIN
112 )
113 workerChoiceStrategyContext.workerChoiceStrategies.set(
114 workerChoiceStrategyContext.workerChoiceStrategy,
fa418e12
JB
115 WorkerChoiceStrategyUndefinedStub
116 )
117 expect(() => workerChoiceStrategyContext.execute()).toThrowError(
e695d66f 118 new Error('Worker node key chosen is null or undefined after 6 retries')
fa418e12
JB
119 )
120 workerChoiceStrategyContext.workerChoiceStrategies.set(
121 workerChoiceStrategyContext.workerChoiceStrategy,
122 WorkerChoiceStrategyNullStub
527e715f
JB
123 )
124 expect(() => workerChoiceStrategyContext.execute()).toThrowError(
e695d66f 125 new Error('Worker node key chosen is null or undefined after 6 retries')
527e715f
JB
126 )
127 })
128
40ad1d27
JB
129 it('Verify that execute() return the worker chosen by the strategy with dynamic pool', () => {
130 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
131 dynamicPool
132 )
133 const WorkerChoiceStrategyStub = sinon.createStubInstance(
134 RoundRobinWorkerChoiceStrategy,
135 {
c923ce56 136 choose: sinon.stub().returns(0)
40ad1d27
JB
137 }
138 )
d710242d 139 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
95c83464
JB
140 WorkerChoiceStrategies.ROUND_ROBIN
141 )
142 workerChoiceStrategyContext.workerChoiceStrategies.set(
d710242d 143 workerChoiceStrategyContext.workerChoiceStrategy,
95c83464
JB
144 WorkerChoiceStrategyStub
145 )
c923ce56 146 const chosenWorkerKey = workerChoiceStrategyContext.execute()
40ad1d27 147 expect(
95c83464 148 workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 149 workerChoiceStrategyContext.workerChoiceStrategy
95c83464 150 ).choose.calledOnce
40ad1d27 151 ).toBe(true)
c923ce56 152 expect(chosenWorkerKey).toBe(0)
40ad1d27
JB
153 })
154
155 it('Verify that setWorkerChoiceStrategy() works with ROUND_ROBIN and fixed pool', () => {
594bfb84 156 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
40ad1d27
JB
157 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
158 fixedPool
159 )
95c83464
JB
160 expect(
161 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 162 workerChoiceStrategy
95c83464
JB
163 )
164 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 165 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 166 workerChoiceStrategy
40ad1d27 167 )
594bfb84 168 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
169 expect(
170 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 171 workerChoiceStrategy
95c83464
JB
172 )
173 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 174 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 175 workerChoiceStrategy
b2b1d84e 176 )
40ad1d27
JB
177 })
178
23ff945a 179 it('Verify that setWorkerChoiceStrategy() works with ROUND_ROBIN and dynamic pool', () => {
594bfb84 180 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
40ad1d27
JB
181 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
182 dynamicPool
183 )
95c83464
JB
184 expect(
185 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 186 workerChoiceStrategy
95c83464
JB
187 )
188 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 189 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 190 workerChoiceStrategy
40ad1d27 191 )
594bfb84 192 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
193 expect(
194 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 195 workerChoiceStrategy
95c83464
JB
196 )
197 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 198 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 199 workerChoiceStrategy
b2b1d84e 200 )
40ad1d27
JB
201 })
202
e4543b14
JB
203 it('Verify that setWorkerChoiceStrategy() works with LEAST_USED and fixed pool', () => {
204 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
40ad1d27
JB
205 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
206 fixedPool
207 )
594bfb84 208 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
209 expect(
210 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 211 workerChoiceStrategy
95c83464 212 )
e4543b14 213 ).toBeInstanceOf(LeastUsedWorkerChoiceStrategy)
d710242d 214 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 215 workerChoiceStrategy
b2b1d84e 216 )
40ad1d27
JB
217 })
218
e4543b14
JB
219 it('Verify that setWorkerChoiceStrategy() works with LEAST_USED and dynamic pool', () => {
220 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
40ad1d27
JB
221 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
222 dynamicPool
223 )
594bfb84 224 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
225 expect(
226 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 227 workerChoiceStrategy
95c83464 228 )
e4543b14 229 ).toBeInstanceOf(LeastUsedWorkerChoiceStrategy)
d710242d 230 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 231 workerChoiceStrategy
b2b1d84e 232 )
168c526f
JB
233 })
234
e4543b14
JB
235 it('Verify that setWorkerChoiceStrategy() works with LEAST_BUSY and fixed pool', () => {
236 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
168c526f
JB
237 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
238 fixedPool
239 )
594bfb84 240 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
241 expect(
242 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 243 workerChoiceStrategy
95c83464 244 )
e4543b14 245 ).toBeInstanceOf(LeastBusyWorkerChoiceStrategy)
d710242d 246 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 247 workerChoiceStrategy
b2b1d84e 248 )
168c526f
JB
249 })
250
e4543b14
JB
251 it('Verify that setWorkerChoiceStrategy() works with LEAST_BUSY and dynamic pool', () => {
252 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
168c526f
JB
253 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
254 dynamicPool
255 )
594bfb84 256 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
257 expect(
258 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 259 workerChoiceStrategy
95c83464 260 )
e4543b14 261 ).toBeInstanceOf(LeastBusyWorkerChoiceStrategy)
d710242d 262 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 263 workerChoiceStrategy
b2b1d84e 264 )
40ad1d27 265 })
23ff945a 266
a1c82d5d
JB
267 it('Verify that setWorkerChoiceStrategy() works with LEAST_ELU and fixed pool', () => {
268 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
269 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
270 fixedPool
271 )
272 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
273 expect(
274 workerChoiceStrategyContext.workerChoiceStrategies.get(
275 workerChoiceStrategy
276 )
277 ).toBeInstanceOf(LeastEluWorkerChoiceStrategy)
278 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
279 workerChoiceStrategy
280 )
281 })
282
283 it('Verify that setWorkerChoiceStrategy() works with LEAST_ELU and dynamic pool', () => {
284 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
285 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
286 dynamicPool
287 )
288 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
289 expect(
290 workerChoiceStrategyContext.workerChoiceStrategies.get(
291 workerChoiceStrategy
292 )
293 ).toBeInstanceOf(LeastEluWorkerChoiceStrategy)
294 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
295 workerChoiceStrategy
296 )
297 })
298
23ff945a 299 it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and fixed pool', () => {
594bfb84 300 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
23ff945a
JB
301 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
302 fixedPool
303 )
594bfb84 304 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
305 expect(
306 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 307 workerChoiceStrategy
95c83464
JB
308 )
309 ).toBeInstanceOf(FairShareWorkerChoiceStrategy)
d710242d 310 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 311 workerChoiceStrategy
b2b1d84e 312 )
23ff945a
JB
313 })
314
315 it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and dynamic pool', () => {
594bfb84 316 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
23ff945a
JB
317 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
318 dynamicPool
319 )
594bfb84 320 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
321 expect(
322 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 323 workerChoiceStrategy
95c83464
JB
324 )
325 ).toBeInstanceOf(FairShareWorkerChoiceStrategy)
d710242d 326 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 327 workerChoiceStrategy
b2b1d84e 328 )
23ff945a
JB
329 })
330
c15273f2 331 it('Verify that setWorkerChoiceStrategy() works with WEIGHTED_ROUND_ROBIN and fixed pool', () => {
594bfb84 332 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
c15273f2
JB
333 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
334 fixedPool
335 )
594bfb84 336 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
337 expect(
338 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 339 workerChoiceStrategy
95c83464
JB
340 )
341 ).toBeInstanceOf(WeightedRoundRobinWorkerChoiceStrategy)
d710242d 342 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 343 workerChoiceStrategy
b2b1d84e 344 )
c15273f2 345 })
23ff945a 346
c15273f2 347 it('Verify that setWorkerChoiceStrategy() works with WEIGHTED_ROUND_ROBIN and dynamic pool', () => {
594bfb84 348 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
c15273f2
JB
349 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
350 dynamicPool
351 )
594bfb84 352 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
353 expect(
354 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 355 workerChoiceStrategy
95c83464
JB
356 )
357 ).toBeInstanceOf(WeightedRoundRobinWorkerChoiceStrategy)
d710242d 358 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 359 workerChoiceStrategy
b2b1d84e 360 )
c15273f2 361 })
2fc5cae3 362
8beab0d3
JB
363 it('Verify that setWorkerChoiceStrategy() works with INTERLEAVED_WEIGHTED_ROUND_ROBIN and fixed pool', () => {
364 const workerChoiceStrategy =
365 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
366 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
367 fixedPool
368 )
369 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
370 expect(
371 workerChoiceStrategyContext.workerChoiceStrategies.get(
372 workerChoiceStrategy
373 )
374 ).toBeInstanceOf(InterleavedWeightedRoundRobinWorkerChoiceStrategy)
375 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
376 workerChoiceStrategy
377 )
378 })
379
380 it('Verify that setWorkerChoiceStrategy() works with INTERLEAVED_WEIGHTED_ROUND_ROBIN and dynamic pool', () => {
381 const workerChoiceStrategy =
382 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
383 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
384 dynamicPool
385 )
386 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
387 expect(
388 workerChoiceStrategyContext.workerChoiceStrategies.get(
389 workerChoiceStrategy
390 )
391 ).toBeInstanceOf(InterleavedWeightedRoundRobinWorkerChoiceStrategy)
392 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
393 workerChoiceStrategy
394 )
395 })
396
9e45c2c4 397 it('Verify that worker choice strategy options enable median runtime pool statistics', () => {
2fc5cae3
JB
398 const wwrWorkerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
399 let workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
400 fixedPool,
401 wwrWorkerChoiceStrategy,
402 {
932fc8be 403 runTime: { median: true }
2fc5cae3
JB
404 }
405 )
87de9ff5 406 expect(
932fc8be
JB
407 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
408 .average
87de9ff5
JB
409 ).toBe(false)
410 expect(
932fc8be 411 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 412 ).toBe(true)
2fc5cae3
JB
413 workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
414 dynamicPool,
415 wwrWorkerChoiceStrategy,
416 {
932fc8be 417 runTime: { median: true }
2fc5cae3
JB
418 }
419 )
87de9ff5 420 expect(
932fc8be
JB
421 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
422 .average
87de9ff5
JB
423 ).toBe(false)
424 expect(
932fc8be 425 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 426 ).toBe(true)
2fc5cae3
JB
427 const fsWorkerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
428 workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
429 fixedPool,
430 fsWorkerChoiceStrategy,
431 {
932fc8be 432 runTime: { median: true }
2fc5cae3
JB
433 }
434 )
87de9ff5 435 expect(
932fc8be
JB
436 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
437 .average
87de9ff5
JB
438 ).toBe(false)
439 expect(
932fc8be 440 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 441 ).toBe(true)
2fc5cae3
JB
442 workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
443 dynamicPool,
444 fsWorkerChoiceStrategy,
445 {
932fc8be 446 runTime: { median: true }
2fc5cae3
JB
447 }
448 )
87de9ff5 449 expect(
932fc8be
JB
450 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
451 .average
87de9ff5
JB
452 ).toBe(false)
453 expect(
932fc8be 454 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 455 ).toBe(true)
2fc5cae3 456 })
40ad1d27 457})