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