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