refactor: prepare the code to handle task abstraction at execute
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
CommitLineData
a61a0724 1const { expect } = require('expect')
a35560ba
S
2const {
3 WorkerChoiceStrategies,
4 DynamicThreadPool,
2ced693a
JB
5 FixedThreadPool,
6 FixedClusterPool
15d56315 7} = require('../../../lib/index')
a35560ba
S
8
9describe('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})