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