Merge pull request #875 from poolifier/dependabot/npm_and_yarn/examples/typescript...
[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(
4ba8492f
JB
118 new TypeError(
119 'Worker node key chosen is null or undefined after 6 retries'
120 )
fa418e12
JB
121 )
122 workerChoiceStrategyContext.workerChoiceStrategies.set(
123 workerChoiceStrategyContext.workerChoiceStrategy,
124 WorkerChoiceStrategyNullStub
527e715f
JB
125 )
126 expect(() => workerChoiceStrategyContext.execute()).toThrowError(
4ba8492f
JB
127 new TypeError(
128 'Worker node key chosen is null or undefined after 6 retries'
129 )
527e715f
JB
130 )
131 })
132
40ad1d27
JB
133 it('Verify that execute() return the worker chosen by the strategy with dynamic pool', () => {
134 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
135 dynamicPool
136 )
137 const WorkerChoiceStrategyStub = sinon.createStubInstance(
138 RoundRobinWorkerChoiceStrategy,
139 {
c923ce56 140 choose: sinon.stub().returns(0)
40ad1d27
JB
141 }
142 )
d710242d 143 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
95c83464
JB
144 WorkerChoiceStrategies.ROUND_ROBIN
145 )
146 workerChoiceStrategyContext.workerChoiceStrategies.set(
d710242d 147 workerChoiceStrategyContext.workerChoiceStrategy,
95c83464
JB
148 WorkerChoiceStrategyStub
149 )
c923ce56 150 const chosenWorkerKey = workerChoiceStrategyContext.execute()
40ad1d27 151 expect(
95c83464 152 workerChoiceStrategyContext.workerChoiceStrategies.get(
d710242d 153 workerChoiceStrategyContext.workerChoiceStrategy
95c83464 154 ).choose.calledOnce
40ad1d27 155 ).toBe(true)
c923ce56 156 expect(chosenWorkerKey).toBe(0)
40ad1d27
JB
157 })
158
159 it('Verify that setWorkerChoiceStrategy() works with ROUND_ROBIN and fixed pool', () => {
594bfb84 160 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
40ad1d27
JB
161 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
162 fixedPool
163 )
95c83464
JB
164 expect(
165 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 166 workerChoiceStrategy
95c83464
JB
167 )
168 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 169 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 170 workerChoiceStrategy
40ad1d27 171 )
594bfb84 172 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
173 expect(
174 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 175 workerChoiceStrategy
95c83464
JB
176 )
177 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 178 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 179 workerChoiceStrategy
b2b1d84e 180 )
40ad1d27
JB
181 })
182
23ff945a 183 it('Verify that setWorkerChoiceStrategy() works with ROUND_ROBIN and dynamic pool', () => {
594bfb84 184 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
40ad1d27
JB
185 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
186 dynamicPool
187 )
95c83464
JB
188 expect(
189 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 190 workerChoiceStrategy
95c83464
JB
191 )
192 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 193 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 194 workerChoiceStrategy
40ad1d27 195 )
594bfb84 196 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
197 expect(
198 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 199 workerChoiceStrategy
95c83464
JB
200 )
201 ).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
d710242d 202 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 203 workerChoiceStrategy
b2b1d84e 204 )
40ad1d27
JB
205 })
206
e4543b14
JB
207 it('Verify that setWorkerChoiceStrategy() works with LEAST_USED and fixed pool', () => {
208 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
40ad1d27
JB
209 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
210 fixedPool
211 )
594bfb84 212 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
213 expect(
214 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 215 workerChoiceStrategy
95c83464 216 )
e4543b14 217 ).toBeInstanceOf(LeastUsedWorkerChoiceStrategy)
d710242d 218 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 219 workerChoiceStrategy
b2b1d84e 220 )
40ad1d27
JB
221 })
222
e4543b14
JB
223 it('Verify that setWorkerChoiceStrategy() works with LEAST_USED and dynamic pool', () => {
224 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
40ad1d27
JB
225 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
226 dynamicPool
227 )
594bfb84 228 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
229 expect(
230 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 231 workerChoiceStrategy
95c83464 232 )
e4543b14 233 ).toBeInstanceOf(LeastUsedWorkerChoiceStrategy)
d710242d 234 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 235 workerChoiceStrategy
b2b1d84e 236 )
168c526f
JB
237 })
238
e4543b14
JB
239 it('Verify that setWorkerChoiceStrategy() works with LEAST_BUSY and fixed pool', () => {
240 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
168c526f
JB
241 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
242 fixedPool
243 )
594bfb84 244 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
245 expect(
246 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 247 workerChoiceStrategy
95c83464 248 )
e4543b14 249 ).toBeInstanceOf(LeastBusyWorkerChoiceStrategy)
d710242d 250 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 251 workerChoiceStrategy
b2b1d84e 252 )
168c526f
JB
253 })
254
e4543b14
JB
255 it('Verify that setWorkerChoiceStrategy() works with LEAST_BUSY and dynamic pool', () => {
256 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
168c526f
JB
257 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
258 dynamicPool
259 )
594bfb84 260 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
261 expect(
262 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 263 workerChoiceStrategy
95c83464 264 )
e4543b14 265 ).toBeInstanceOf(LeastBusyWorkerChoiceStrategy)
d710242d 266 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 267 workerChoiceStrategy
b2b1d84e 268 )
40ad1d27 269 })
23ff945a 270
a1c82d5d
JB
271 it('Verify that setWorkerChoiceStrategy() works with LEAST_ELU and fixed pool', () => {
272 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
273 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
274 fixedPool
275 )
276 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
277 expect(
278 workerChoiceStrategyContext.workerChoiceStrategies.get(
279 workerChoiceStrategy
280 )
281 ).toBeInstanceOf(LeastEluWorkerChoiceStrategy)
282 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
283 workerChoiceStrategy
284 )
285 })
286
287 it('Verify that setWorkerChoiceStrategy() works with LEAST_ELU and dynamic pool', () => {
288 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
289 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
290 dynamicPool
291 )
292 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
293 expect(
294 workerChoiceStrategyContext.workerChoiceStrategies.get(
295 workerChoiceStrategy
296 )
297 ).toBeInstanceOf(LeastEluWorkerChoiceStrategy)
298 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
299 workerChoiceStrategy
300 )
301 })
302
23ff945a 303 it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and fixed pool', () => {
594bfb84 304 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
23ff945a
JB
305 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
306 fixedPool
307 )
594bfb84 308 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
309 expect(
310 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 311 workerChoiceStrategy
95c83464
JB
312 )
313 ).toBeInstanceOf(FairShareWorkerChoiceStrategy)
d710242d 314 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 315 workerChoiceStrategy
b2b1d84e 316 )
23ff945a
JB
317 })
318
319 it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and dynamic pool', () => {
594bfb84 320 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
23ff945a
JB
321 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
322 dynamicPool
323 )
594bfb84 324 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
325 expect(
326 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 327 workerChoiceStrategy
95c83464
JB
328 )
329 ).toBeInstanceOf(FairShareWorkerChoiceStrategy)
d710242d 330 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 331 workerChoiceStrategy
b2b1d84e 332 )
23ff945a
JB
333 })
334
c15273f2 335 it('Verify that setWorkerChoiceStrategy() works with WEIGHTED_ROUND_ROBIN and fixed pool', () => {
594bfb84 336 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
c15273f2
JB
337 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
338 fixedPool
339 )
594bfb84 340 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
341 expect(
342 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 343 workerChoiceStrategy
95c83464
JB
344 )
345 ).toBeInstanceOf(WeightedRoundRobinWorkerChoiceStrategy)
d710242d 346 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 347 workerChoiceStrategy
b2b1d84e 348 )
c15273f2 349 })
23ff945a 350
c15273f2 351 it('Verify that setWorkerChoiceStrategy() works with WEIGHTED_ROUND_ROBIN and dynamic pool', () => {
594bfb84 352 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
c15273f2
JB
353 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
354 dynamicPool
355 )
594bfb84 356 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
95c83464
JB
357 expect(
358 workerChoiceStrategyContext.workerChoiceStrategies.get(
594bfb84 359 workerChoiceStrategy
95c83464
JB
360 )
361 ).toBeInstanceOf(WeightedRoundRobinWorkerChoiceStrategy)
d710242d 362 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
594bfb84 363 workerChoiceStrategy
b2b1d84e 364 )
c15273f2 365 })
2fc5cae3 366
8beab0d3
JB
367 it('Verify that setWorkerChoiceStrategy() works with INTERLEAVED_WEIGHTED_ROUND_ROBIN and fixed pool', () => {
368 const workerChoiceStrategy =
369 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
370 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
371 fixedPool
372 )
373 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
374 expect(
375 workerChoiceStrategyContext.workerChoiceStrategies.get(
376 workerChoiceStrategy
377 )
378 ).toBeInstanceOf(InterleavedWeightedRoundRobinWorkerChoiceStrategy)
379 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
380 workerChoiceStrategy
381 )
382 })
383
384 it('Verify that setWorkerChoiceStrategy() works with INTERLEAVED_WEIGHTED_ROUND_ROBIN and dynamic pool', () => {
385 const workerChoiceStrategy =
386 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
387 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
388 dynamicPool
389 )
390 workerChoiceStrategyContext.setWorkerChoiceStrategy(workerChoiceStrategy)
391 expect(
392 workerChoiceStrategyContext.workerChoiceStrategies.get(
393 workerChoiceStrategy
394 )
395 ).toBeInstanceOf(InterleavedWeightedRoundRobinWorkerChoiceStrategy)
396 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
397 workerChoiceStrategy
398 )
399 })
400
9e45c2c4 401 it('Verify that worker choice strategy options enable median runtime pool statistics', () => {
2fc5cae3
JB
402 const wwrWorkerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
403 let workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
404 fixedPool,
405 wwrWorkerChoiceStrategy,
406 {
932fc8be 407 runTime: { median: true }
2fc5cae3
JB
408 }
409 )
87de9ff5 410 expect(
932fc8be
JB
411 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
412 .average
87de9ff5
JB
413 ).toBe(false)
414 expect(
932fc8be 415 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 416 ).toBe(true)
2fc5cae3
JB
417 workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
418 dynamicPool,
419 wwrWorkerChoiceStrategy,
420 {
932fc8be 421 runTime: { median: true }
2fc5cae3
JB
422 }
423 )
87de9ff5 424 expect(
932fc8be
JB
425 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
426 .average
87de9ff5
JB
427 ).toBe(false)
428 expect(
932fc8be 429 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 430 ).toBe(true)
2fc5cae3
JB
431 const fsWorkerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
432 workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
433 fixedPool,
434 fsWorkerChoiceStrategy,
435 {
932fc8be 436 runTime: { median: true }
2fc5cae3
JB
437 }
438 )
87de9ff5 439 expect(
932fc8be
JB
440 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
441 .average
87de9ff5
JB
442 ).toBe(false)
443 expect(
932fc8be 444 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 445 ).toBe(true)
2fc5cae3
JB
446 workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
447 dynamicPool,
448 fsWorkerChoiceStrategy,
449 {
932fc8be 450 runTime: { median: true }
2fc5cae3
JB
451 }
452 )
87de9ff5 453 expect(
932fc8be
JB
454 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime
455 .average
87de9ff5
JB
456 ).toBe(false)
457 expect(
932fc8be 458 workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime.median
87de9ff5 459 ).toBe(true)
2fc5cae3 460 })
40ad1d27 461})