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