Commit | Line | Data |
---|---|---|
a61a0724 | 1 | const { expect } = require('expect') |
a35560ba S |
2 | const { |
3 | WorkerChoiceStrategies, | |
4 | DynamicThreadPool, | |
2ced693a JB |
5 | FixedThreadPool, |
6 | FixedClusterPool | |
15d56315 | 7 | } = require('../../../lib/index') |
a35560ba S |
8 | |
9 | describe('Selection strategies test suite', () => { | |
e1ffb94f JB |
10 | const min = 0 |
11 | const max = 3 | |
12 | ||
a35560ba S |
13 | it('Verify that WorkerChoiceStrategies enumeration provides string values', () => { |
14 | expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN') | |
737c6d97 | 15 | expect(WorkerChoiceStrategies.LESS_USED).toBe('LESS_USED') |
168c526f | 16 | expect(WorkerChoiceStrategies.LESS_BUSY).toBe('LESS_BUSY') |
23ff945a | 17 | expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE') |
b3432a63 JB |
18 | expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe( |
19 | 'WEIGHTED_ROUND_ROBIN' | |
20 | ) | |
a35560ba S |
21 | }) |
22 | ||
e843b904 | 23 | it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => { |
e843b904 JB |
24 | const pool = new DynamicThreadPool( |
25 | min, | |
26 | max, | |
27 | './tests/worker-files/thread/testWorker.js' | |
28 | ) | |
29 | expect(pool.opts.workerChoiceStrategy).toBe( | |
30 | WorkerChoiceStrategies.ROUND_ROBIN | |
31 | ) | |
32 | // We need to clean up the resources after our test | |
33 | await pool.destroy() | |
34 | }) | |
35 | ||
d2f7b7a2 JB |
36 | it('Verify ROUND_ROBIN strategy is taken at pool creation', async () => { |
37 | const pool = new FixedThreadPool( | |
38 | max, | |
39 | './tests/worker-files/thread/testWorker.js', | |
40 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
41 | ) | |
42 | expect(pool.opts.workerChoiceStrategy).toBe( | |
43 | WorkerChoiceStrategies.ROUND_ROBIN | |
44 | ) | |
45 | expect( | |
95c83464 JB |
46 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
47 | WorkerChoiceStrategies.ROUND_ROBIN | |
f06e48d8 | 48 | ).nextWorkerNodeId |
d2f7b7a2 JB |
49 | ).toBe(0) |
50 | // We need to clean up the resources after our test | |
51 | await pool.destroy() | |
52 | }) | |
53 | ||
e843b904 | 54 | it('Verify ROUND_ROBIN strategy can be set after pool creation', async () => { |
e843b904 JB |
55 | const pool = new DynamicThreadPool( |
56 | min, | |
57 | max, | |
58 | './tests/worker-files/thread/testWorker.js' | |
59 | ) | |
60 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) | |
61 | expect(pool.opts.workerChoiceStrategy).toBe( | |
62 | WorkerChoiceStrategies.ROUND_ROBIN | |
63 | ) | |
64 | // We need to clean up the resources after our test | |
65 | await pool.destroy() | |
66 | }) | |
67 | ||
10fcfaf4 | 68 | it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => { |
10fcfaf4 JB |
69 | let pool = new FixedThreadPool( |
70 | max, | |
71 | './tests/worker-files/thread/testWorker.js' | |
72 | ) | |
73 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) | |
74 | expect( | |
97a2abc3 | 75 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 76 | ).toBe(false) |
c6bd2650 JB |
77 | expect( |
78 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
79 | ).toBe(false) | |
78099a15 JB |
80 | expect( |
81 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
82 | ).toBe(false) | |
fd7ebd49 | 83 | await pool.destroy() |
10fcfaf4 JB |
84 | pool = new DynamicThreadPool( |
85 | min, | |
86 | max, | |
87 | './tests/worker-files/thread/testWorker.js' | |
88 | ) | |
89 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) | |
90 | expect( | |
97a2abc3 | 91 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 92 | ).toBe(false) |
c6bd2650 JB |
93 | expect( |
94 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
95 | ).toBe(false) | |
78099a15 JB |
96 | expect( |
97 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
98 | ).toBe(false) | |
10fcfaf4 JB |
99 | // We need to clean up the resources after our test |
100 | await pool.destroy() | |
101 | }) | |
102 | ||
bdaf31cd | 103 | it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
bdaf31cd JB |
104 | const pool = new FixedThreadPool( |
105 | max, | |
106 | './tests/worker-files/thread/testWorker.js', | |
107 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
108 | ) | |
109 | expect(pool.opts.workerChoiceStrategy).toBe( | |
110 | WorkerChoiceStrategies.ROUND_ROBIN | |
111 | ) | |
112 | // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` | |
113 | const promises = [] | |
114 | for (let i = 0; i < max * 2; i++) { | |
6db75ad9 | 115 | promises.push(pool.execute()) |
bdaf31cd JB |
116 | } |
117 | await Promise.all(promises) | |
118 | // We need to clean up the resources after our test | |
119 | await pool.destroy() | |
120 | }) | |
121 | ||
122 | it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
bdaf31cd JB |
123 | const pool = new DynamicThreadPool( |
124 | min, | |
125 | max, | |
126 | './tests/worker-files/thread/testWorker.js', | |
127 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
128 | ) | |
129 | expect(pool.opts.workerChoiceStrategy).toBe( | |
130 | WorkerChoiceStrategies.ROUND_ROBIN | |
131 | ) | |
132 | // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` | |
133 | const promises = [] | |
134 | for (let i = 0; i < max * 2; i++) { | |
6db75ad9 | 135 | promises.push(pool.execute()) |
bdaf31cd JB |
136 | } |
137 | await Promise.all(promises) | |
138 | // We need to clean up the resources after our test | |
139 | await pool.destroy() | |
140 | }) | |
141 | ||
2ced693a JB |
142 | it('Verify ROUND_ROBIN strategy runtime behavior', async () => { |
143 | let pool = new FixedClusterPool( | |
144 | max, | |
145 | './tests/worker-files/cluster/testWorker.js' | |
146 | ) | |
147 | let results = new Set() | |
148 | for (let i = 0; i < max; i++) { | |
adc3c320 | 149 | results.add(pool.chooseWorkerNode()[1].worker.id) |
2ced693a JB |
150 | } |
151 | expect(results.size).toBe(max) | |
152 | await pool.destroy() | |
153 | pool = new FixedThreadPool(max, './tests/worker-files/thread/testWorker.js') | |
154 | results = new Set() | |
155 | for (let i = 0; i < max; i++) { | |
adc3c320 | 156 | results.add(pool.chooseWorkerNode()[1].worker.threadId) |
2ced693a JB |
157 | } |
158 | expect(results.size).toBe(max) | |
159 | await pool.destroy() | |
160 | }) | |
161 | ||
a6f7f1b4 JB |
162 | it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => { |
163 | let pool = new FixedThreadPool( | |
164 | max, | |
165 | './tests/worker-files/thread/testWorker.js', | |
166 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
167 | ) | |
38f6e859 | 168 | expect( |
95c83464 JB |
169 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
170 | WorkerChoiceStrategies.ROUND_ROBIN | |
f06e48d8 | 171 | ).nextWorkerNodeId |
b529c323 | 172 | ).toBeDefined() |
a6f7f1b4 JB |
173 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) |
174 | expect( | |
95c83464 JB |
175 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
176 | WorkerChoiceStrategies.ROUND_ROBIN | |
f06e48d8 | 177 | ).nextWorkerNodeId |
a6f7f1b4 JB |
178 | ).toBe(0) |
179 | await pool.destroy() | |
180 | pool = new DynamicThreadPool( | |
181 | min, | |
182 | max, | |
183 | './tests/worker-files/thread/testWorker.js', | |
184 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
185 | ) | |
38f6e859 | 186 | expect( |
95c83464 JB |
187 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
188 | WorkerChoiceStrategies.ROUND_ROBIN | |
f06e48d8 | 189 | ).nextWorkerNodeId |
b529c323 | 190 | ).toBeDefined() |
a6f7f1b4 JB |
191 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.ROUND_ROBIN) |
192 | expect( | |
95c83464 JB |
193 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
194 | WorkerChoiceStrategies.ROUND_ROBIN | |
f06e48d8 | 195 | ).nextWorkerNodeId |
a6f7f1b4 JB |
196 | ).toBe(0) |
197 | // We need to clean up the resources after our test | |
198 | await pool.destroy() | |
199 | }) | |
200 | ||
737c6d97 | 201 | it('Verify LESS_USED strategy is taken at pool creation', async () => { |
a35560ba S |
202 | const pool = new FixedThreadPool( |
203 | max, | |
204 | './tests/worker-files/thread/testWorker.js', | |
737c6d97 | 205 | { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } |
a35560ba | 206 | ) |
b98ec2e6 | 207 | expect(pool.opts.workerChoiceStrategy).toBe( |
737c6d97 | 208 | WorkerChoiceStrategies.LESS_USED |
b98ec2e6 JB |
209 | ) |
210 | // We need to clean up the resources after our test | |
211 | await pool.destroy() | |
212 | }) | |
a35560ba | 213 | |
737c6d97 | 214 | it('Verify LESS_USED strategy can be set after pool creation', async () => { |
b98ec2e6 JB |
215 | const pool = new FixedThreadPool( |
216 | max, | |
217 | './tests/worker-files/thread/testWorker.js' | |
218 | ) | |
737c6d97 | 219 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED) |
a35560ba | 220 | expect(pool.opts.workerChoiceStrategy).toBe( |
737c6d97 | 221 | WorkerChoiceStrategies.LESS_USED |
a35560ba | 222 | ) |
b98ec2e6 JB |
223 | // We need to clean up the resources after our test |
224 | await pool.destroy() | |
225 | }) | |
a35560ba | 226 | |
737c6d97 | 227 | it('Verify LESS_USED strategy default tasks usage statistics requirements', async () => { |
10fcfaf4 JB |
228 | let pool = new FixedThreadPool( |
229 | max, | |
230 | './tests/worker-files/thread/testWorker.js' | |
231 | ) | |
737c6d97 | 232 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED) |
10fcfaf4 | 233 | expect( |
97a2abc3 | 234 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 235 | ).toBe(false) |
c6bd2650 JB |
236 | expect( |
237 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
238 | ).toBe(false) | |
78099a15 JB |
239 | expect( |
240 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
241 | ).toBe(false) | |
fd7ebd49 | 242 | await pool.destroy() |
10fcfaf4 JB |
243 | pool = new DynamicThreadPool( |
244 | min, | |
245 | max, | |
246 | './tests/worker-files/thread/testWorker.js' | |
247 | ) | |
737c6d97 | 248 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_USED) |
10fcfaf4 | 249 | expect( |
97a2abc3 | 250 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 251 | ).toBe(false) |
c6bd2650 JB |
252 | expect( |
253 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
254 | ).toBe(false) | |
78099a15 JB |
255 | expect( |
256 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
257 | ).toBe(false) | |
10fcfaf4 JB |
258 | // We need to clean up the resources after our test |
259 | await pool.destroy() | |
260 | }) | |
261 | ||
737c6d97 | 262 | it('Verify LESS_USED strategy can be run in a fixed pool', async () => { |
b98ec2e6 JB |
263 | const pool = new FixedThreadPool( |
264 | max, | |
265 | './tests/worker-files/thread/testWorker.js', | |
737c6d97 | 266 | { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } |
b98ec2e6 | 267 | ) |
168c526f | 268 | // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` |
a35560ba S |
269 | const promises = [] |
270 | for (let i = 0; i < max * 2; i++) { | |
6db75ad9 | 271 | promises.push(pool.execute()) |
a35560ba S |
272 | } |
273 | await Promise.all(promises) | |
a35560ba S |
274 | // We need to clean up the resources after our test |
275 | await pool.destroy() | |
276 | }) | |
277 | ||
737c6d97 | 278 | it('Verify LESS_USED strategy can be run in a dynamic pool', async () => { |
ff5e76e1 JB |
279 | const pool = new DynamicThreadPool( |
280 | min, | |
281 | max, | |
282 | './tests/worker-files/thread/testWorker.js', | |
737c6d97 | 283 | { workerChoiceStrategy: WorkerChoiceStrategies.LESS_USED } |
ff5e76e1 | 284 | ) |
168c526f JB |
285 | // TODO: Create a better test to cover `LessUsedWorkerChoiceStrategy#choose` |
286 | const promises = [] | |
287 | for (let i = 0; i < max * 2; i++) { | |
288 | promises.push(pool.execute()) | |
289 | } | |
290 | await Promise.all(promises) | |
291 | // We need to clean up the resources after our test | |
292 | await pool.destroy() | |
293 | }) | |
294 | ||
295 | it('Verify LESS_BUSY strategy is taken at pool creation', async () => { | |
296 | const pool = new FixedThreadPool( | |
297 | max, | |
298 | './tests/worker-files/thread/testWorker.js', | |
299 | { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } | |
300 | ) | |
301 | expect(pool.opts.workerChoiceStrategy).toBe( | |
302 | WorkerChoiceStrategies.LESS_BUSY | |
303 | ) | |
304 | // We need to clean up the resources after our test | |
305 | await pool.destroy() | |
306 | }) | |
307 | ||
308 | it('Verify LESS_BUSY strategy can be set after pool creation', async () => { | |
309 | const pool = new FixedThreadPool( | |
310 | max, | |
311 | './tests/worker-files/thread/testWorker.js' | |
312 | ) | |
313 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) | |
314 | expect(pool.opts.workerChoiceStrategy).toBe( | |
315 | WorkerChoiceStrategies.LESS_BUSY | |
316 | ) | |
317 | // We need to clean up the resources after our test | |
318 | await pool.destroy() | |
319 | }) | |
320 | ||
321 | it('Verify LESS_BUSY strategy default tasks usage statistics requirements', async () => { | |
322 | let pool = new FixedThreadPool( | |
323 | max, | |
324 | './tests/worker-files/thread/testWorker.js' | |
325 | ) | |
326 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) | |
327 | expect( | |
97a2abc3 | 328 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
168c526f | 329 | ).toBe(true) |
c6bd2650 JB |
330 | expect( |
331 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
332 | ).toBe(false) | |
78099a15 JB |
333 | expect( |
334 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
335 | ).toBe(false) | |
168c526f JB |
336 | await pool.destroy() |
337 | pool = new DynamicThreadPool( | |
338 | min, | |
339 | max, | |
340 | './tests/worker-files/thread/testWorker.js' | |
341 | ) | |
342 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.LESS_BUSY) | |
343 | expect( | |
97a2abc3 | 344 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
168c526f | 345 | ).toBe(true) |
c6bd2650 JB |
346 | expect( |
347 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
348 | ).toBe(false) | |
78099a15 JB |
349 | expect( |
350 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
351 | ).toBe(false) | |
168c526f JB |
352 | // We need to clean up the resources after our test |
353 | await pool.destroy() | |
354 | }) | |
355 | ||
356 | it('Verify LESS_BUSY strategy can be run in a fixed pool', async () => { | |
357 | const pool = new FixedThreadPool( | |
358 | max, | |
359 | './tests/worker-files/thread/testWorker.js', | |
360 | { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } | |
361 | ) | |
362 | // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` | |
363 | const promises = [] | |
364 | for (let i = 0; i < max * 2; i++) { | |
365 | promises.push(pool.execute()) | |
366 | } | |
367 | await Promise.all(promises) | |
368 | // We need to clean up the resources after our test | |
369 | await pool.destroy() | |
370 | }) | |
371 | ||
372 | it('Verify LESS_BUSY strategy can be run in a dynamic pool', async () => { | |
373 | const pool = new DynamicThreadPool( | |
374 | min, | |
375 | max, | |
376 | './tests/worker-files/thread/testWorker.js', | |
377 | { workerChoiceStrategy: WorkerChoiceStrategies.LESS_BUSY } | |
378 | ) | |
379 | // TODO: Create a better test to cover `LessBusyWorkerChoiceStrategy#choose` | |
ff5e76e1 JB |
380 | const promises = [] |
381 | for (let i = 0; i < max * 2; i++) { | |
6db75ad9 | 382 | promises.push(pool.execute()) |
ff5e76e1 JB |
383 | } |
384 | await Promise.all(promises) | |
ff5e76e1 JB |
385 | // We need to clean up the resources after our test |
386 | await pool.destroy() | |
387 | }) | |
388 | ||
23ff945a | 389 | it('Verify FAIR_SHARE strategy is taken at pool creation', async () => { |
23ff945a JB |
390 | const pool = new FixedThreadPool( |
391 | max, | |
392 | './tests/worker-files/thread/testWorker.js', | |
393 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
394 | ) | |
395 | expect(pool.opts.workerChoiceStrategy).toBe( | |
396 | WorkerChoiceStrategies.FAIR_SHARE | |
397 | ) | |
f06e48d8 | 398 | for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies |
95c83464 JB |
399 | .get(WorkerChoiceStrategies.FAIR_SHARE) |
400 | .workerLastVirtualTaskTimestamp.keys()) { | |
6e7fa401 | 401 | expect( |
95c83464 JB |
402 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
403 | .get(WorkerChoiceStrategies.FAIR_SHARE) | |
f06e48d8 | 404 | .workerLastVirtualTaskTimestamp.get(workerNodeKey).start |
6e7fa401 JB |
405 | ).toBe(0) |
406 | expect( | |
95c83464 JB |
407 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
408 | .get(WorkerChoiceStrategies.FAIR_SHARE) | |
f06e48d8 | 409 | .workerLastVirtualTaskTimestamp.get(workerNodeKey).end |
6e7fa401 JB |
410 | ).toBe(0) |
411 | } | |
23ff945a JB |
412 | // We need to clean up the resources after our test |
413 | await pool.destroy() | |
414 | }) | |
415 | ||
416 | it('Verify FAIR_SHARE strategy can be set after pool creation', async () => { | |
23ff945a JB |
417 | const pool = new FixedThreadPool( |
418 | max, | |
419 | './tests/worker-files/thread/testWorker.js' | |
420 | ) | |
421 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) | |
422 | expect(pool.opts.workerChoiceStrategy).toBe( | |
423 | WorkerChoiceStrategies.FAIR_SHARE | |
424 | ) | |
425 | // We need to clean up the resources after our test | |
426 | await pool.destroy() | |
427 | }) | |
428 | ||
10fcfaf4 | 429 | it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => { |
10fcfaf4 JB |
430 | let pool = new FixedThreadPool( |
431 | max, | |
432 | './tests/worker-files/thread/testWorker.js' | |
433 | ) | |
434 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) | |
435 | expect( | |
97a2abc3 | 436 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 437 | ).toBe(true) |
c6bd2650 JB |
438 | expect( |
439 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
440 | ).toBe(true) | |
78099a15 JB |
441 | expect( |
442 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
443 | ).toBe(false) | |
fd7ebd49 | 444 | await pool.destroy() |
10fcfaf4 JB |
445 | pool = new DynamicThreadPool( |
446 | min, | |
447 | max, | |
448 | './tests/worker-files/thread/testWorker.js' | |
449 | ) | |
450 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) | |
451 | expect( | |
97a2abc3 | 452 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 453 | ).toBe(true) |
c6bd2650 JB |
454 | expect( |
455 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
456 | ).toBe(true) | |
78099a15 JB |
457 | expect( |
458 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
459 | ).toBe(false) | |
10fcfaf4 JB |
460 | // We need to clean up the resources after our test |
461 | await pool.destroy() | |
462 | }) | |
463 | ||
23ff945a | 464 | it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => { |
23ff945a JB |
465 | const pool = new FixedThreadPool( |
466 | max, | |
467 | './tests/worker-files/thread/testWorker.js', | |
468 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
469 | ) | |
470 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
471 | const promises = [] | |
472 | for (let i = 0; i < max * 2; i++) { | |
6db75ad9 | 473 | promises.push(pool.execute()) |
23ff945a JB |
474 | } |
475 | await Promise.all(promises) | |
97a2abc3 | 476 | expect( |
95c83464 JB |
477 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
478 | WorkerChoiceStrategies.FAIR_SHARE | |
479 | ).workerLastVirtualTaskTimestamp.size | |
f06e48d8 | 480 | ).toBe(pool.workerNodes.length) |
23ff945a JB |
481 | // We need to clean up the resources after our test |
482 | await pool.destroy() | |
483 | }) | |
484 | ||
485 | it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => { | |
23ff945a JB |
486 | const pool = new DynamicThreadPool( |
487 | min, | |
488 | max, | |
489 | './tests/worker-files/thread/testWorker.js', | |
490 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
491 | ) | |
492 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
493 | const promises = [] | |
f7070eee | 494 | const maxMultiplier = 2 |
804a889e | 495 | for (let i = 0; i < max * maxMultiplier; i++) { |
6db75ad9 | 496 | promises.push(pool.execute()) |
23ff945a JB |
497 | } |
498 | await Promise.all(promises) | |
f7070eee JB |
499 | // if (process.platform !== 'win32') { |
500 | // expect( | |
95c83464 JB |
501 | // pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
502 | // WorkerChoiceStrategies.FAIR_SHARE | |
503 | // ).workerLastVirtualTaskTimestamp.size | |
f06e48d8 | 504 | // ).toBe(pool.workerNodes.length) |
f7070eee | 505 | // } |
23ff945a JB |
506 | // We need to clean up the resources after our test |
507 | await pool.destroy() | |
508 | }) | |
509 | ||
a6f7f1b4 | 510 | it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => { |
f0829c53 | 511 | let pool = new FixedThreadPool( |
caeb9817 JB |
512 | max, |
513 | './tests/worker-files/thread/testWorker.js' | |
514 | ) | |
515 | expect( | |
95c83464 JB |
516 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
517 | WorkerChoiceStrategies.FAIR_SHARE | |
b529c323 JB |
518 | ).workerLastVirtualTaskTimestamp |
519 | ).toBeDefined() | |
caeb9817 | 520 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) |
f06e48d8 | 521 | for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies |
95c83464 JB |
522 | .get(WorkerChoiceStrategies.FAIR_SHARE) |
523 | .workerLastVirtualTaskTimestamp.keys()) { | |
caeb9817 | 524 | expect( |
95c83464 JB |
525 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
526 | .get(WorkerChoiceStrategies.FAIR_SHARE) | |
f06e48d8 | 527 | .workerLastVirtualTaskTimestamp.get(workerNodeKey).start |
caeb9817 JB |
528 | ).toBe(0) |
529 | expect( | |
95c83464 JB |
530 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
531 | .get(WorkerChoiceStrategies.FAIR_SHARE) | |
f06e48d8 | 532 | .workerLastVirtualTaskTimestamp.get(workerNodeKey).end |
caeb9817 JB |
533 | ).toBe(0) |
534 | } | |
f0829c53 JB |
535 | await pool.destroy() |
536 | pool = new DynamicThreadPool( | |
537 | min, | |
538 | max, | |
539 | './tests/worker-files/thread/testWorker.js' | |
540 | ) | |
541 | expect( | |
95c83464 JB |
542 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
543 | WorkerChoiceStrategies.FAIR_SHARE | |
b529c323 JB |
544 | ).workerLastVirtualTaskTimestamp |
545 | ).toBeDefined() | |
f0829c53 | 546 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.FAIR_SHARE) |
f06e48d8 | 547 | for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies |
95c83464 JB |
548 | .get(WorkerChoiceStrategies.FAIR_SHARE) |
549 | .workerLastVirtualTaskTimestamp.keys()) { | |
f0829c53 | 550 | expect( |
95c83464 JB |
551 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
552 | .get(WorkerChoiceStrategies.FAIR_SHARE) | |
f06e48d8 | 553 | .workerLastVirtualTaskTimestamp.get(workerNodeKey).start |
f0829c53 JB |
554 | ).toBe(0) |
555 | expect( | |
95c83464 JB |
556 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
557 | .get(WorkerChoiceStrategies.FAIR_SHARE) | |
f06e48d8 | 558 | .workerLastVirtualTaskTimestamp.get(workerNodeKey).end |
f0829c53 JB |
559 | ).toBe(0) |
560 | } | |
caeb9817 JB |
561 | // We need to clean up the resources after our test |
562 | await pool.destroy() | |
563 | }) | |
564 | ||
b3432a63 | 565 | it('Verify WEIGHTED_ROUND_ROBIN strategy is taken at pool creation', async () => { |
b3432a63 JB |
566 | const pool = new FixedThreadPool( |
567 | max, | |
568 | './tests/worker-files/thread/testWorker.js', | |
569 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
570 | ) | |
571 | expect(pool.opts.workerChoiceStrategy).toBe( | |
572 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
573 | ) | |
d2f7b7a2 | 574 | expect( |
95c83464 JB |
575 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
576 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
f06e48d8 | 577 | ).currentWorkerNodeId |
d2f7b7a2 JB |
578 | ).toBe(0) |
579 | expect( | |
95c83464 JB |
580 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
581 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
582 | ).defaultWorkerWeight | |
d2f7b7a2 | 583 | ).toBeGreaterThan(0) |
f06e48d8 | 584 | for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies |
95c83464 JB |
585 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) |
586 | .workersTaskRunTime.keys()) { | |
d2f7b7a2 | 587 | expect( |
95c83464 JB |
588 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
589 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
f06e48d8 | 590 | .workersTaskRunTime.get(workerNodeKey).weight |
d2f7b7a2 | 591 | ).toBeGreaterThan(0) |
6e7fa401 | 592 | expect( |
95c83464 JB |
593 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
594 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
f06e48d8 | 595 | .workersTaskRunTime.get(workerNodeKey).runTime |
6e7fa401 JB |
596 | ).toBe(0) |
597 | } | |
b3432a63 JB |
598 | // We need to clean up the resources after our test |
599 | await pool.destroy() | |
600 | }) | |
601 | ||
602 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be set after pool creation', async () => { | |
b3432a63 JB |
603 | const pool = new FixedThreadPool( |
604 | max, | |
605 | './tests/worker-files/thread/testWorker.js' | |
606 | ) | |
607 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
608 | expect(pool.opts.workerChoiceStrategy).toBe( | |
609 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
610 | ) | |
611 | // We need to clean up the resources after our test | |
612 | await pool.destroy() | |
613 | }) | |
614 | ||
10fcfaf4 | 615 | it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => { |
10fcfaf4 JB |
616 | let pool = new FixedThreadPool( |
617 | max, | |
618 | './tests/worker-files/thread/testWorker.js' | |
619 | ) | |
620 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
621 | expect( | |
97a2abc3 | 622 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 623 | ).toBe(true) |
c6bd2650 JB |
624 | expect( |
625 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
626 | ).toBe(true) | |
78099a15 JB |
627 | expect( |
628 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
629 | ).toBe(false) | |
fd7ebd49 | 630 | await pool.destroy() |
10fcfaf4 JB |
631 | pool = new DynamicThreadPool( |
632 | min, | |
633 | max, | |
634 | './tests/worker-files/thread/testWorker.js' | |
635 | ) | |
636 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
637 | expect( | |
97a2abc3 | 638 | pool.workerChoiceStrategyContext.getRequiredStatistics().runTime |
10fcfaf4 | 639 | ).toBe(true) |
c6bd2650 JB |
640 | expect( |
641 | pool.workerChoiceStrategyContext.getRequiredStatistics().avgRunTime | |
642 | ).toBe(true) | |
78099a15 JB |
643 | expect( |
644 | pool.workerChoiceStrategyContext.getRequiredStatistics().medRunTime | |
645 | ).toBe(false) | |
10fcfaf4 JB |
646 | // We need to clean up the resources after our test |
647 | await pool.destroy() | |
648 | }) | |
649 | ||
b3432a63 | 650 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
b3432a63 JB |
651 | const pool = new FixedThreadPool( |
652 | max, | |
653 | './tests/worker-files/thread/testWorker.js', | |
654 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
655 | ) | |
656 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
657 | const promises = [] | |
658 | for (let i = 0; i < max * 2; i++) { | |
6db75ad9 | 659 | promises.push(pool.execute()) |
b3432a63 JB |
660 | } |
661 | await Promise.all(promises) | |
97a2abc3 | 662 | expect( |
95c83464 JB |
663 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
664 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
665 | ).workersTaskRunTime.size | |
f06e48d8 | 666 | ).toBe(pool.workerNodes.length) |
b3432a63 JB |
667 | // We need to clean up the resources after our test |
668 | await pool.destroy() | |
669 | }) | |
670 | ||
671 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
b3432a63 JB |
672 | const pool = new DynamicThreadPool( |
673 | min, | |
674 | max, | |
675 | './tests/worker-files/thread/testWorker.js', | |
676 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
677 | ) | |
678 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
679 | const promises = [] | |
5502c07c | 680 | const maxMultiplier = |
95c83464 JB |
681 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
682 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
8da9e84d | 683 | ).defaultWorkerWeight * 50 |
5502c07c | 684 | for (let i = 0; i < max * maxMultiplier; i++) { |
6db75ad9 | 685 | promises.push(pool.execute()) |
b3432a63 JB |
686 | } |
687 | await Promise.all(promises) | |
9f34a585 JB |
688 | if (process.platform !== 'win32') { |
689 | expect( | |
95c83464 JB |
690 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
691 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
692 | ).workersTaskRunTime.size | |
f06e48d8 | 693 | ).toBe(pool.workerNodes.length) |
9f34a585 | 694 | } |
b3432a63 JB |
695 | // We need to clean up the resources after our test |
696 | await pool.destroy() | |
697 | }) | |
698 | ||
a6f7f1b4 | 699 | it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => { |
f0829c53 | 700 | let pool = new FixedThreadPool( |
caeb9817 JB |
701 | max, |
702 | './tests/worker-files/thread/testWorker.js' | |
703 | ) | |
38f6e859 | 704 | expect( |
95c83464 JB |
705 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
706 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
f06e48d8 | 707 | ).currentWorkerNodeId |
b529c323 | 708 | ).toBeDefined() |
38f6e859 | 709 | expect( |
95c83464 JB |
710 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
711 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
b529c323 JB |
712 | ).defaultWorkerWeight |
713 | ).toBeDefined() | |
caeb9817 | 714 | expect( |
95c83464 JB |
715 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
716 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
b529c323 JB |
717 | ).workersTaskRunTime |
718 | ).toBeDefined() | |
caeb9817 | 719 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) |
a6f7f1b4 | 720 | expect( |
95c83464 JB |
721 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
722 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
f06e48d8 | 723 | ).currentWorkerNodeId |
a6f7f1b4 JB |
724 | ).toBe(0) |
725 | expect( | |
95c83464 JB |
726 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
727 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
728 | ).defaultWorkerWeight | |
a6f7f1b4 | 729 | ).toBeGreaterThan(0) |
f06e48d8 | 730 | for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies |
95c83464 JB |
731 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) |
732 | .workersTaskRunTime.keys()) { | |
caeb9817 | 733 | expect( |
95c83464 JB |
734 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
735 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
f06e48d8 | 736 | .workersTaskRunTime.get(workerNodeKey).runTime |
caeb9817 JB |
737 | ).toBe(0) |
738 | } | |
f0829c53 JB |
739 | await pool.destroy() |
740 | pool = new DynamicThreadPool( | |
741 | min, | |
742 | max, | |
743 | './tests/worker-files/thread/testWorker.js' | |
744 | ) | |
38f6e859 | 745 | expect( |
95c83464 JB |
746 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
747 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
f06e48d8 | 748 | ).currentWorkerNodeId |
b529c323 | 749 | ).toBeDefined() |
38f6e859 | 750 | expect( |
95c83464 JB |
751 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
752 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
b529c323 JB |
753 | ).defaultWorkerWeight |
754 | ).toBeDefined() | |
f0829c53 | 755 | expect( |
95c83464 JB |
756 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
757 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
b529c323 JB |
758 | ).workersTaskRunTime |
759 | ).toBeDefined() | |
f0829c53 | 760 | pool.setWorkerChoiceStrategy(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) |
a6f7f1b4 | 761 | expect( |
95c83464 JB |
762 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
763 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
f06e48d8 | 764 | ).currentWorkerNodeId |
a6f7f1b4 JB |
765 | ).toBe(0) |
766 | expect( | |
95c83464 JB |
767 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
768 | WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
769 | ).defaultWorkerWeight | |
a6f7f1b4 | 770 | ).toBeGreaterThan(0) |
f06e48d8 | 771 | for (const workerNodeKey of pool.workerChoiceStrategyContext.workerChoiceStrategies |
95c83464 JB |
772 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) |
773 | .workersTaskRunTime.keys()) { | |
f0829c53 | 774 | expect( |
95c83464 JB |
775 | pool.workerChoiceStrategyContext.workerChoiceStrategies |
776 | .get(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN) | |
f06e48d8 | 777 | .workersTaskRunTime.get(workerNodeKey).runTime |
f0829c53 JB |
778 | ).toBe(0) |
779 | } | |
caeb9817 JB |
780 | // We need to clean up the resources after our test |
781 | await pool.destroy() | |
782 | }) | |
783 | ||
a35560ba | 784 | it('Verify unknown strategies throw error', () => { |
a35560ba S |
785 | expect( |
786 | () => | |
787 | new DynamicThreadPool( | |
788 | min, | |
789 | max, | |
790 | './tests/worker-files/thread/testWorker.js', | |
1927ee67 | 791 | { workerChoiceStrategy: 'UNKNOWN_STRATEGY' } |
a35560ba S |
792 | ) |
793 | ).toThrowError( | |
b529c323 | 794 | new Error("Invalid worker choice strategy 'UNKNOWN_STRATEGY'") |
a35560ba S |
795 | ) |
796 | }) | |
797 | }) |