Commit | Line | Data |
---|---|---|
a61a0724 | 1 | const { expect } = require('expect') |
a35560ba | 2 | const { |
a35560ba | 3 | DynamicThreadPool, |
3d6dd312 | 4 | FixedClusterPool, |
2ced693a | 5 | FixedThreadPool, |
3d6dd312 | 6 | WorkerChoiceStrategies |
cdace0e5 | 7 | } = require('../../../lib') |
86bf340d | 8 | const { CircularArray } = require('../../../lib/circular-array') |
a35560ba S |
9 | |
10 | describe('Selection strategies test suite', () => { | |
e1ffb94f JB |
11 | const min = 0 |
12 | const max = 3 | |
13 | ||
a35560ba S |
14 | it('Verify that WorkerChoiceStrategies enumeration provides string values', () => { |
15 | expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN') | |
e4543b14 JB |
16 | expect(WorkerChoiceStrategies.LEAST_USED).toBe('LEAST_USED') |
17 | expect(WorkerChoiceStrategies.LEAST_BUSY).toBe('LEAST_BUSY') | |
a7bbf44a | 18 | expect(WorkerChoiceStrategies.LEAST_ELU).toBe('LEAST_ELU') |
23ff945a | 19 | expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE') |
b3432a63 JB |
20 | expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe( |
21 | 'WEIGHTED_ROUND_ROBIN' | |
22 | ) | |
feec6e8c JB |
23 | expect(WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN).toBe( |
24 | 'INTERLEAVED_WEIGHTED_ROUND_ROBIN' | |
25 | ) | |
a35560ba S |
26 | }) |
27 | ||
e843b904 | 28 | it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => { |
e843b904 JB |
29 | const pool = new DynamicThreadPool( |
30 | min, | |
31 | max, | |
32 | './tests/worker-files/thread/testWorker.js' | |
33 | ) | |
34 | expect(pool.opts.workerChoiceStrategy).toBe( | |
35 | WorkerChoiceStrategies.ROUND_ROBIN | |
36 | ) | |
37 | // We need to clean up the resources after our test | |
38 | await pool.destroy() | |
39 | }) | |
40 | ||
594bfb84 JB |
41 | it('Verify available strategies are taken at pool creation', async () => { |
42 | for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { | |
43 | const pool = new FixedThreadPool( | |
44 | max, | |
45 | './tests/worker-files/thread/testWorker.js', | |
46 | { workerChoiceStrategy } | |
47 | ) | |
48 | expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy) | |
49 | expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe( | |
50 | workerChoiceStrategy | |
51 | ) | |
52 | await pool.destroy() | |
53 | } | |
d2f7b7a2 JB |
54 | }) |
55 | ||
594bfb84 JB |
56 | it('Verify available strategies can be set after pool creation', async () => { |
57 | for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { | |
58 | const pool = new DynamicThreadPool( | |
59 | min, | |
60 | max, | |
ec82cfa1 | 61 | './tests/worker-files/thread/testWorker.js' |
594bfb84 JB |
62 | ) |
63 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) | |
64 | expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy) | |
65 | expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe( | |
66 | workerChoiceStrategy | |
67 | ) | |
68 | await pool.destroy() | |
69 | } | |
70 | }) | |
71 | ||
72 | it('Verify available strategies default internals at pool creation', async () => { | |
73 | const pool = new FixedThreadPool( | |
e843b904 JB |
74 | max, |
75 | './tests/worker-files/thread/testWorker.js' | |
76 | ) | |
594bfb84 JB |
77 | for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { |
78 | if (workerChoiceStrategy === WorkerChoiceStrategies.ROUND_ROBIN) { | |
79 | expect( | |
80 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
81 | workerChoiceStrategy | |
9b106837 | 82 | ).nextWorkerNodeKey |
594bfb84 JB |
83 | ).toBe(0) |
84 | } else if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) { | |
08f3f44c JB |
85 | expect( |
86 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
87 | workerChoiceStrategy | |
b0d6ed8f | 88 | ).workersVirtualTaskEndTimestamp |
08f3f44c JB |
89 | ).toBeInstanceOf(Array) |
90 | expect( | |
91 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
92 | workerChoiceStrategy | |
b0d6ed8f | 93 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 94 | ).toBe(0) |
594bfb84 JB |
95 | } else if ( |
96 | workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
97 | ) { | |
98 | expect( | |
99 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
100 | workerChoiceStrategy | |
9b106837 | 101 | ).nextWorkerNodeKey |
594bfb84 JB |
102 | ).toBe(0) |
103 | expect( | |
104 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
105 | workerChoiceStrategy | |
106 | ).defaultWorkerWeight | |
107 | ).toBeGreaterThan(0) | |
08f3f44c JB |
108 | expect( |
109 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
110 | workerChoiceStrategy | |
111 | ).workerVirtualTaskRunTime | |
112 | ).toBe(0) | |
594bfb84 JB |
113 | } |
114 | } | |
e843b904 JB |
115 | await pool.destroy() |
116 | }) | |
117 | ||
6c6afb84 JB |
118 | it('Verify ROUND_ROBIN strategy default policy', async () => { |
119 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN | |
120 | let pool = new FixedThreadPool( | |
121 | max, | |
122 | './tests/worker-files/thread/testWorker.js', | |
123 | { workerChoiceStrategy } | |
124 | ) | |
125 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
94407def | 126 | dynamicWorkerUsage: false, |
b1aae695 | 127 | dynamicWorkerReady: true |
6c6afb84 JB |
128 | }) |
129 | await pool.destroy() | |
130 | pool = new DynamicThreadPool( | |
131 | min, | |
132 | max, | |
133 | './tests/worker-files/thread/testWorker.js', | |
134 | { workerChoiceStrategy } | |
135 | ) | |
136 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
94407def | 137 | dynamicWorkerUsage: false, |
b1aae695 | 138 | dynamicWorkerReady: true |
6c6afb84 JB |
139 | }) |
140 | // We need to clean up the resources after our test | |
141 | await pool.destroy() | |
142 | }) | |
143 | ||
144 | it('Verify ROUND_ROBIN strategy default tasks statistics requirements', async () => { | |
594bfb84 | 145 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN |
10fcfaf4 JB |
146 | let pool = new FixedThreadPool( |
147 | max, | |
d710242d | 148 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 149 | { workerChoiceStrategy } |
10fcfaf4 | 150 | ) |
87de9ff5 JB |
151 | expect( |
152 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
153 | ).toStrictEqual({ | |
932fc8be JB |
154 | runTime: { |
155 | aggregate: false, | |
156 | average: false, | |
157 | median: false | |
158 | }, | |
159 | waitTime: { | |
160 | aggregate: false, | |
161 | average: false, | |
162 | median: false | |
163 | }, | |
5df69fab JB |
164 | elu: { |
165 | aggregate: false, | |
166 | average: false, | |
167 | median: false | |
168 | } | |
86bf340d | 169 | }) |
fd7ebd49 | 170 | await pool.destroy() |
10fcfaf4 JB |
171 | pool = new DynamicThreadPool( |
172 | min, | |
173 | max, | |
d710242d | 174 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 175 | { workerChoiceStrategy } |
10fcfaf4 | 176 | ) |
87de9ff5 JB |
177 | expect( |
178 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
179 | ).toStrictEqual({ | |
932fc8be JB |
180 | runTime: { |
181 | aggregate: false, | |
182 | average: false, | |
183 | median: false | |
184 | }, | |
185 | waitTime: { | |
186 | aggregate: false, | |
187 | average: false, | |
188 | median: false | |
189 | }, | |
5df69fab JB |
190 | elu: { |
191 | aggregate: false, | |
192 | average: false, | |
193 | median: false | |
194 | } | |
86bf340d | 195 | }) |
10fcfaf4 JB |
196 | // We need to clean up the resources after our test |
197 | await pool.destroy() | |
198 | }) | |
199 | ||
bdaf31cd | 200 | it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
bdaf31cd JB |
201 | const pool = new FixedThreadPool( |
202 | max, | |
203 | './tests/worker-files/thread/testWorker.js', | |
204 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
205 | ) | |
bdaf31cd | 206 | // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` |
ee9f5295 | 207 | const promises = new Set() |
a20f0ba5 JB |
208 | const maxMultiplier = 2 |
209 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 210 | promises.add(pool.execute()) |
e211bc18 JB |
211 | } |
212 | await Promise.all(promises) | |
213 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 214 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
215 | tasks: { |
216 | executed: maxMultiplier, | |
217 | executing: 0, | |
218 | queued: 0, | |
df593701 | 219 | maxQueued: 0, |
a4e07f72 JB |
220 | failed: 0 |
221 | }, | |
222 | runTime: { | |
a4e07f72 JB |
223 | history: expect.any(CircularArray) |
224 | }, | |
225 | waitTime: { | |
a4e07f72 JB |
226 | history: expect.any(CircularArray) |
227 | }, | |
5df69fab JB |
228 | elu: { |
229 | idle: { | |
5df69fab JB |
230 | history: expect.any(CircularArray) |
231 | }, | |
232 | active: { | |
5df69fab | 233 | history: expect.any(CircularArray) |
71514351 | 234 | } |
5df69fab | 235 | } |
e211bc18 | 236 | }) |
bdaf31cd | 237 | } |
9458090a JB |
238 | expect( |
239 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
240 | WorkerChoiceStrategies.ROUND_ROBIN | |
9b106837 | 241 | ).nextWorkerNodeKey |
9458090a | 242 | ).toBe(0) |
bdaf31cd JB |
243 | // We need to clean up the resources after our test |
244 | await pool.destroy() | |
245 | }) | |
246 | ||
247 | it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
bdaf31cd JB |
248 | const pool = new DynamicThreadPool( |
249 | min, | |
250 | max, | |
251 | './tests/worker-files/thread/testWorker.js', | |
252 | { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } | |
253 | ) | |
bdaf31cd | 254 | // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` |
ee9f5295 | 255 | const promises = new Set() |
a20f0ba5 JB |
256 | const maxMultiplier = 2 |
257 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 258 | promises.add(pool.execute()) |
e211bc18 JB |
259 | } |
260 | await Promise.all(promises) | |
261 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 262 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 263 | tasks: { |
94407def | 264 | executed: expect.any(Number), |
a4e07f72 JB |
265 | executing: 0, |
266 | queued: 0, | |
df593701 | 267 | maxQueued: 0, |
a4e07f72 JB |
268 | failed: 0 |
269 | }, | |
270 | runTime: { | |
a4e07f72 JB |
271 | history: expect.any(CircularArray) |
272 | }, | |
273 | waitTime: { | |
a4e07f72 JB |
274 | history: expect.any(CircularArray) |
275 | }, | |
5df69fab JB |
276 | elu: { |
277 | idle: { | |
5df69fab JB |
278 | history: expect.any(CircularArray) |
279 | }, | |
280 | active: { | |
5df69fab | 281 | history: expect.any(CircularArray) |
71514351 | 282 | } |
5df69fab | 283 | } |
e211bc18 | 284 | }) |
94407def JB |
285 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
286 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
287 | max * maxMultiplier | |
288 | ) | |
bdaf31cd | 289 | } |
9458090a JB |
290 | expect( |
291 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
292 | WorkerChoiceStrategies.ROUND_ROBIN | |
9b106837 | 293 | ).nextWorkerNodeKey |
9458090a | 294 | ).toBe(0) |
bdaf31cd JB |
295 | // We need to clean up the resources after our test |
296 | await pool.destroy() | |
297 | }) | |
298 | ||
2ced693a | 299 | it('Verify ROUND_ROBIN strategy runtime behavior', async () => { |
594bfb84 | 300 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN |
2ced693a JB |
301 | let pool = new FixedClusterPool( |
302 | max, | |
594bfb84 JB |
303 | './tests/worker-files/cluster/testWorker.js', |
304 | { workerChoiceStrategy } | |
2ced693a JB |
305 | ) |
306 | let results = new Set() | |
307 | for (let i = 0; i < max; i++) { | |
20dcad1a | 308 | results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.id) |
2ced693a JB |
309 | } |
310 | expect(results.size).toBe(max) | |
311 | await pool.destroy() | |
594bfb84 JB |
312 | pool = new FixedThreadPool( |
313 | max, | |
314 | './tests/worker-files/thread/testWorker.js', | |
315 | { workerChoiceStrategy } | |
316 | ) | |
2ced693a JB |
317 | results = new Set() |
318 | for (let i = 0; i < max; i++) { | |
20dcad1a | 319 | results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.threadId) |
2ced693a JB |
320 | } |
321 | expect(results.size).toBe(max) | |
322 | await pool.destroy() | |
323 | }) | |
324 | ||
a6f7f1b4 | 325 | it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => { |
594bfb84 | 326 | const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN |
a6f7f1b4 JB |
327 | let pool = new FixedThreadPool( |
328 | max, | |
329 | './tests/worker-files/thread/testWorker.js', | |
330 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
331 | ) | |
38f6e859 | 332 | expect( |
95c83464 | 333 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 334 | workerChoiceStrategy |
9b106837 | 335 | ).nextWorkerNodeKey |
b529c323 | 336 | ).toBeDefined() |
594bfb84 | 337 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 338 | expect( |
95c83464 | 339 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 340 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 341 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
342 | ).toBe(0) |
343 | await pool.destroy() | |
344 | pool = new DynamicThreadPool( | |
345 | min, | |
346 | max, | |
347 | './tests/worker-files/thread/testWorker.js', | |
348 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
349 | ) | |
38f6e859 | 350 | expect( |
95c83464 | 351 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 352 | workerChoiceStrategy |
9b106837 | 353 | ).nextWorkerNodeKey |
b529c323 | 354 | ).toBeDefined() |
594bfb84 | 355 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 356 | expect( |
95c83464 | 357 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 358 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 359 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
360 | ).toBe(0) |
361 | // We need to clean up the resources after our test | |
362 | await pool.destroy() | |
363 | }) | |
364 | ||
6c6afb84 JB |
365 | it('Verify LEAST_USED strategy default policy', async () => { |
366 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED | |
367 | let pool = new FixedThreadPool( | |
368 | max, | |
369 | './tests/worker-files/thread/testWorker.js', | |
370 | { workerChoiceStrategy } | |
371 | ) | |
372 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
373 | dynamicWorkerUsage: false, |
374 | dynamicWorkerReady: true | |
6c6afb84 JB |
375 | }) |
376 | await pool.destroy() | |
377 | pool = new DynamicThreadPool( | |
378 | min, | |
379 | max, | |
380 | './tests/worker-files/thread/testWorker.js', | |
381 | { workerChoiceStrategy } | |
382 | ) | |
383 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
384 | dynamicWorkerUsage: false, |
385 | dynamicWorkerReady: true | |
6c6afb84 JB |
386 | }) |
387 | // We need to clean up the resources after our test | |
388 | await pool.destroy() | |
389 | }) | |
390 | ||
391 | it('Verify LEAST_USED strategy default tasks statistics requirements', async () => { | |
e4543b14 | 392 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED |
10fcfaf4 JB |
393 | let pool = new FixedThreadPool( |
394 | max, | |
d710242d | 395 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 396 | { workerChoiceStrategy } |
10fcfaf4 | 397 | ) |
87de9ff5 JB |
398 | expect( |
399 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
400 | ).toStrictEqual({ | |
932fc8be JB |
401 | runTime: { |
402 | aggregate: false, | |
403 | average: false, | |
404 | median: false | |
405 | }, | |
406 | waitTime: { | |
407 | aggregate: false, | |
408 | average: false, | |
409 | median: false | |
410 | }, | |
5df69fab JB |
411 | elu: { |
412 | aggregate: false, | |
413 | average: false, | |
414 | median: false | |
415 | } | |
86bf340d | 416 | }) |
fd7ebd49 | 417 | await pool.destroy() |
10fcfaf4 JB |
418 | pool = new DynamicThreadPool( |
419 | min, | |
420 | max, | |
d710242d | 421 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 422 | { workerChoiceStrategy } |
10fcfaf4 | 423 | ) |
87de9ff5 JB |
424 | expect( |
425 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
426 | ).toStrictEqual({ | |
932fc8be JB |
427 | runTime: { |
428 | aggregate: false, | |
429 | average: false, | |
430 | median: false | |
431 | }, | |
432 | waitTime: { | |
433 | aggregate: false, | |
434 | average: false, | |
435 | median: false | |
436 | }, | |
5df69fab JB |
437 | elu: { |
438 | aggregate: false, | |
439 | average: false, | |
440 | median: false | |
441 | } | |
86bf340d | 442 | }) |
10fcfaf4 JB |
443 | // We need to clean up the resources after our test |
444 | await pool.destroy() | |
445 | }) | |
446 | ||
e4543b14 | 447 | it('Verify LEAST_USED strategy can be run in a fixed pool', async () => { |
b98ec2e6 JB |
448 | const pool = new FixedThreadPool( |
449 | max, | |
450 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 451 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED } |
b98ec2e6 | 452 | ) |
e4543b14 | 453 | // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose` |
ee9f5295 | 454 | const promises = new Set() |
a20f0ba5 JB |
455 | const maxMultiplier = 2 |
456 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 457 | promises.add(pool.execute()) |
e211bc18 JB |
458 | } |
459 | await Promise.all(promises) | |
460 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 461 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 462 | tasks: { |
76407b8e | 463 | executed: expect.any(Number), |
a4e07f72 JB |
464 | executing: 0, |
465 | queued: 0, | |
df593701 | 466 | maxQueued: 0, |
a4e07f72 JB |
467 | failed: 0 |
468 | }, | |
469 | runTime: { | |
a4e07f72 JB |
470 | history: expect.any(CircularArray) |
471 | }, | |
472 | waitTime: { | |
a4e07f72 JB |
473 | history: expect.any(CircularArray) |
474 | }, | |
5df69fab JB |
475 | elu: { |
476 | idle: { | |
5df69fab JB |
477 | history: expect.any(CircularArray) |
478 | }, | |
479 | active: { | |
5df69fab | 480 | history: expect.any(CircularArray) |
71514351 | 481 | } |
5df69fab | 482 | } |
e211bc18 | 483 | }) |
465b2940 JB |
484 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
485 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
76407b8e JB |
486 | max * maxMultiplier |
487 | ) | |
a35560ba | 488 | } |
a35560ba S |
489 | // We need to clean up the resources after our test |
490 | await pool.destroy() | |
491 | }) | |
492 | ||
e4543b14 | 493 | it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => { |
ff5e76e1 JB |
494 | const pool = new DynamicThreadPool( |
495 | min, | |
496 | max, | |
497 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 498 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED } |
ff5e76e1 | 499 | ) |
e4543b14 | 500 | // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose` |
ee9f5295 | 501 | const promises = new Set() |
a20f0ba5 JB |
502 | const maxMultiplier = 2 |
503 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 504 | promises.add(pool.execute()) |
e211bc18 JB |
505 | } |
506 | await Promise.all(promises) | |
507 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 508 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 509 | tasks: { |
76407b8e | 510 | executed: expect.any(Number), |
a4e07f72 JB |
511 | executing: 0, |
512 | queued: 0, | |
df593701 | 513 | maxQueued: 0, |
a4e07f72 JB |
514 | failed: 0 |
515 | }, | |
516 | runTime: { | |
a4e07f72 JB |
517 | history: expect.any(CircularArray) |
518 | }, | |
519 | waitTime: { | |
a4e07f72 JB |
520 | history: expect.any(CircularArray) |
521 | }, | |
5df69fab JB |
522 | elu: { |
523 | idle: { | |
5df69fab JB |
524 | history: expect.any(CircularArray) |
525 | }, | |
526 | active: { | |
5df69fab | 527 | history: expect.any(CircularArray) |
71514351 | 528 | } |
5df69fab | 529 | } |
e211bc18 | 530 | }) |
465b2940 JB |
531 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
532 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
76407b8e JB |
533 | max * maxMultiplier |
534 | ) | |
168c526f | 535 | } |
168c526f JB |
536 | // We need to clean up the resources after our test |
537 | await pool.destroy() | |
538 | }) | |
539 | ||
6c6afb84 JB |
540 | it('Verify LEAST_BUSY strategy default policy', async () => { |
541 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY | |
542 | let pool = new FixedThreadPool( | |
543 | max, | |
544 | './tests/worker-files/thread/testWorker.js', | |
545 | { workerChoiceStrategy } | |
546 | ) | |
547 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
548 | dynamicWorkerUsage: false, |
549 | dynamicWorkerReady: true | |
6c6afb84 JB |
550 | }) |
551 | await pool.destroy() | |
552 | pool = new DynamicThreadPool( | |
553 | min, | |
554 | max, | |
555 | './tests/worker-files/thread/testWorker.js', | |
556 | { workerChoiceStrategy } | |
557 | ) | |
558 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
559 | dynamicWorkerUsage: false, |
560 | dynamicWorkerReady: true | |
6c6afb84 JB |
561 | }) |
562 | // We need to clean up the resources after our test | |
563 | await pool.destroy() | |
564 | }) | |
565 | ||
566 | it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => { | |
e4543b14 | 567 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY |
168c526f JB |
568 | let pool = new FixedThreadPool( |
569 | max, | |
d710242d | 570 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 571 | { workerChoiceStrategy } |
168c526f | 572 | ) |
87de9ff5 JB |
573 | expect( |
574 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
575 | ).toStrictEqual({ | |
932fc8be JB |
576 | runTime: { |
577 | aggregate: true, | |
578 | average: false, | |
579 | median: false | |
580 | }, | |
581 | waitTime: { | |
582 | aggregate: true, | |
583 | average: false, | |
584 | median: false | |
585 | }, | |
5df69fab JB |
586 | elu: { |
587 | aggregate: false, | |
588 | average: false, | |
589 | median: false | |
590 | } | |
86bf340d | 591 | }) |
168c526f JB |
592 | await pool.destroy() |
593 | pool = new DynamicThreadPool( | |
594 | min, | |
595 | max, | |
d710242d | 596 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 597 | { workerChoiceStrategy } |
168c526f | 598 | ) |
87de9ff5 JB |
599 | expect( |
600 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
601 | ).toStrictEqual({ | |
932fc8be JB |
602 | runTime: { |
603 | aggregate: true, | |
604 | average: false, | |
605 | median: false | |
606 | }, | |
607 | waitTime: { | |
608 | aggregate: true, | |
609 | average: false, | |
610 | median: false | |
611 | }, | |
5df69fab JB |
612 | elu: { |
613 | aggregate: false, | |
614 | average: false, | |
615 | median: false | |
616 | } | |
86bf340d | 617 | }) |
168c526f JB |
618 | // We need to clean up the resources after our test |
619 | await pool.destroy() | |
620 | }) | |
621 | ||
e4543b14 | 622 | it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => { |
168c526f JB |
623 | const pool = new FixedThreadPool( |
624 | max, | |
625 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 626 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY } |
168c526f | 627 | ) |
e4543b14 | 628 | // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose` |
ee9f5295 | 629 | const promises = new Set() |
a20f0ba5 JB |
630 | const maxMultiplier = 2 |
631 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 632 | promises.add(pool.execute()) |
e211bc18 JB |
633 | } |
634 | await Promise.all(promises) | |
635 | for (const workerNode of pool.workerNodes) { | |
19dbc45b | 636 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 JB |
637 | tasks: { |
638 | executed: expect.any(Number), | |
639 | executing: 0, | |
640 | queued: 0, | |
df593701 | 641 | maxQueued: 0, |
a4e07f72 JB |
642 | failed: 0 |
643 | }, | |
644 | runTime: { | |
a4e07f72 JB |
645 | history: expect.any(CircularArray) |
646 | }, | |
647 | waitTime: { | |
a4e07f72 JB |
648 | history: expect.any(CircularArray) |
649 | }, | |
5df69fab JB |
650 | elu: { |
651 | idle: { | |
5df69fab JB |
652 | history: expect.any(CircularArray) |
653 | }, | |
654 | active: { | |
5df69fab | 655 | history: expect.any(CircularArray) |
71514351 | 656 | } |
5df69fab | 657 | } |
e211bc18 | 658 | }) |
465b2940 JB |
659 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
660 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
661 | max * maxMultiplier |
662 | ) | |
19dbc45b JB |
663 | if (workerNode.usage.runTime.aggregate == null) { |
664 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
665 | } else { | |
666 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
667 | } | |
668 | if (workerNode.usage.waitTime.aggregate == null) { | |
669 | expect(workerNode.usage.waitTime.aggregate).toBeUndefined() | |
670 | } else { | |
671 | expect(workerNode.usage.waitTime.aggregate).toBeGreaterThan(0) | |
672 | } | |
168c526f | 673 | } |
168c526f JB |
674 | // We need to clean up the resources after our test |
675 | await pool.destroy() | |
676 | }) | |
677 | ||
e4543b14 | 678 | it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => { |
168c526f JB |
679 | const pool = new DynamicThreadPool( |
680 | min, | |
681 | max, | |
682 | './tests/worker-files/thread/testWorker.js', | |
e4543b14 | 683 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY } |
168c526f | 684 | ) |
e4543b14 | 685 | // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose` |
ee9f5295 | 686 | const promises = new Set() |
a20f0ba5 JB |
687 | const maxMultiplier = 2 |
688 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 689 | promises.add(pool.execute()) |
e211bc18 JB |
690 | } |
691 | await Promise.all(promises) | |
692 | for (const workerNode of pool.workerNodes) { | |
19dbc45b | 693 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 JB |
694 | tasks: { |
695 | executed: expect.any(Number), | |
696 | executing: 0, | |
697 | queued: 0, | |
df593701 | 698 | maxQueued: 0, |
a4e07f72 JB |
699 | failed: 0 |
700 | }, | |
701 | runTime: { | |
a4e07f72 JB |
702 | history: expect.any(CircularArray) |
703 | }, | |
704 | waitTime: { | |
a4e07f72 JB |
705 | history: expect.any(CircularArray) |
706 | }, | |
5df69fab JB |
707 | elu: { |
708 | idle: { | |
5df69fab JB |
709 | history: expect.any(CircularArray) |
710 | }, | |
711 | active: { | |
5df69fab | 712 | history: expect.any(CircularArray) |
71514351 | 713 | } |
5df69fab | 714 | } |
e211bc18 | 715 | }) |
465b2940 JB |
716 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
717 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
718 | max * maxMultiplier |
719 | ) | |
19dbc45b JB |
720 | if (workerNode.usage.runTime.aggregate == null) { |
721 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
722 | } else { | |
723 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
724 | } | |
725 | if (workerNode.usage.waitTime.aggregate == null) { | |
726 | expect(workerNode.usage.waitTime.aggregate).toBeUndefined() | |
727 | } else { | |
728 | expect(workerNode.usage.waitTime.aggregate).toBeGreaterThan(0) | |
729 | } | |
ff5e76e1 | 730 | } |
ff5e76e1 JB |
731 | // We need to clean up the resources after our test |
732 | await pool.destroy() | |
733 | }) | |
734 | ||
6c6afb84 JB |
735 | it('Verify LEAST_ELU strategy default policy', async () => { |
736 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU | |
737 | let pool = new FixedThreadPool( | |
738 | max, | |
739 | './tests/worker-files/thread/testWorker.js', | |
740 | { workerChoiceStrategy } | |
741 | ) | |
742 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
743 | dynamicWorkerUsage: false, |
744 | dynamicWorkerReady: true | |
6c6afb84 JB |
745 | }) |
746 | await pool.destroy() | |
747 | pool = new DynamicThreadPool( | |
748 | min, | |
749 | max, | |
750 | './tests/worker-files/thread/testWorker.js', | |
751 | { workerChoiceStrategy } | |
752 | ) | |
753 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
754 | dynamicWorkerUsage: false, |
755 | dynamicWorkerReady: true | |
6c6afb84 JB |
756 | }) |
757 | // We need to clean up the resources after our test | |
758 | await pool.destroy() | |
759 | }) | |
760 | ||
761 | it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => { | |
a7bbf44a JB |
762 | const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU |
763 | let pool = new FixedThreadPool( | |
764 | max, | |
765 | './tests/worker-files/thread/testWorker.js', | |
766 | { workerChoiceStrategy } | |
767 | ) | |
05302647 JB |
768 | expect( |
769 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
770 | ).toStrictEqual({ | |
e460940e JB |
771 | runTime: { |
772 | aggregate: false, | |
773 | average: false, | |
774 | median: false | |
775 | }, | |
776 | waitTime: { | |
777 | aggregate: false, | |
778 | average: false, | |
779 | median: false | |
780 | }, | |
5df69fab JB |
781 | elu: { |
782 | aggregate: true, | |
783 | average: false, | |
784 | median: false | |
785 | } | |
a7bbf44a JB |
786 | }) |
787 | await pool.destroy() | |
788 | pool = new DynamicThreadPool( | |
789 | min, | |
790 | max, | |
791 | './tests/worker-files/thread/testWorker.js', | |
792 | { workerChoiceStrategy } | |
793 | ) | |
05302647 JB |
794 | expect( |
795 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
796 | ).toStrictEqual({ | |
e460940e JB |
797 | runTime: { |
798 | aggregate: false, | |
799 | average: false, | |
800 | median: false | |
801 | }, | |
802 | waitTime: { | |
803 | aggregate: false, | |
804 | average: false, | |
805 | median: false | |
806 | }, | |
5df69fab JB |
807 | elu: { |
808 | aggregate: true, | |
809 | average: false, | |
810 | median: false | |
811 | } | |
a7bbf44a JB |
812 | }) |
813 | // We need to clean up the resources after our test | |
814 | await pool.destroy() | |
815 | }) | |
816 | ||
ae9cf3c8 | 817 | it('Verify LEAST_ELU strategy can be run in a fixed pool', async () => { |
c5ad42cd JB |
818 | const pool = new FixedThreadPool( |
819 | max, | |
820 | './tests/worker-files/thread/testWorker.js', | |
821 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_ELU } | |
822 | ) | |
823 | // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose` | |
dd38581f | 824 | const promises = new Set() |
c5ad42cd JB |
825 | const maxMultiplier = 2 |
826 | for (let i = 0; i < max * maxMultiplier; i++) { | |
dd38581f | 827 | promises.add(pool.execute()) |
c5ad42cd | 828 | } |
dd38581f | 829 | await Promise.all(promises) |
c5ad42cd | 830 | for (const workerNode of pool.workerNodes) { |
71514351 | 831 | expect(workerNode.usage).toMatchObject({ |
c5ad42cd JB |
832 | tasks: { |
833 | executed: expect.any(Number), | |
834 | executing: 0, | |
835 | queued: 0, | |
df593701 | 836 | maxQueued: 0, |
c5ad42cd JB |
837 | failed: 0 |
838 | }, | |
839 | runTime: { | |
c5ad42cd | 840 | history: expect.any(CircularArray) |
a1347286 JB |
841 | }, |
842 | waitTime: { | |
a1347286 | 843 | history: expect.any(CircularArray) |
5df69fab JB |
844 | }, |
845 | elu: { | |
71514351 | 846 | idle: expect.objectContaining({ |
5df69fab | 847 | history: expect.any(CircularArray) |
71514351 JB |
848 | }), |
849 | active: expect.objectContaining({ | |
5df69fab | 850 | history: expect.any(CircularArray) |
71514351 | 851 | }) |
a1347286 | 852 | } |
5df69fab | 853 | }) |
465b2940 JB |
854 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
855 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a1347286 JB |
856 | max * maxMultiplier |
857 | ) | |
71514351 JB |
858 | if (workerNode.usage.elu.utilization == null) { |
859 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
860 | } else { | |
861 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
862 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
863 | } | |
a1347286 JB |
864 | } |
865 | // We need to clean up the resources after our test | |
866 | await pool.destroy() | |
867 | }) | |
868 | ||
869 | it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => { | |
870 | const pool = new DynamicThreadPool( | |
871 | min, | |
872 | max, | |
873 | './tests/worker-files/thread/testWorker.js', | |
874 | { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_ELU } | |
875 | ) | |
876 | // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose` | |
dd38581f | 877 | const promises = new Set() |
a1347286 JB |
878 | const maxMultiplier = 2 |
879 | for (let i = 0; i < max * maxMultiplier; i++) { | |
dd38581f | 880 | promises.add(pool.execute()) |
a1347286 | 881 | } |
dd38581f | 882 | await Promise.all(promises) |
a1347286 | 883 | for (const workerNode of pool.workerNodes) { |
71514351 | 884 | expect(workerNode.usage).toMatchObject({ |
a1347286 JB |
885 | tasks: { |
886 | executed: expect.any(Number), | |
887 | executing: 0, | |
888 | queued: 0, | |
df593701 | 889 | maxQueued: 0, |
a1347286 JB |
890 | failed: 0 |
891 | }, | |
892 | runTime: { | |
a1347286 | 893 | history: expect.any(CircularArray) |
c5ad42cd JB |
894 | }, |
895 | waitTime: { | |
c5ad42cd | 896 | history: expect.any(CircularArray) |
5df69fab JB |
897 | }, |
898 | elu: { | |
71514351 | 899 | idle: expect.objectContaining({ |
5df69fab | 900 | history: expect.any(CircularArray) |
71514351 JB |
901 | }), |
902 | active: expect.objectContaining({ | |
5df69fab | 903 | history: expect.any(CircularArray) |
71514351 | 904 | }) |
c5ad42cd | 905 | } |
5df69fab | 906 | }) |
465b2940 JB |
907 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
908 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
c5ad42cd JB |
909 | max * maxMultiplier |
910 | ) | |
71514351 JB |
911 | if (workerNode.usage.elu.utilization == null) { |
912 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
913 | } else { | |
914 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
915 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
916 | } | |
c5ad42cd JB |
917 | } |
918 | // We need to clean up the resources after our test | |
919 | await pool.destroy() | |
920 | }) | |
921 | ||
6c6afb84 JB |
922 | it('Verify FAIR_SHARE strategy default policy', async () => { |
923 | const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE | |
924 | let pool = new FixedThreadPool( | |
925 | max, | |
926 | './tests/worker-files/thread/testWorker.js', | |
927 | { workerChoiceStrategy } | |
928 | ) | |
929 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
930 | dynamicWorkerUsage: false, |
931 | dynamicWorkerReady: true | |
6c6afb84 JB |
932 | }) |
933 | await pool.destroy() | |
934 | pool = new DynamicThreadPool( | |
935 | min, | |
936 | max, | |
937 | './tests/worker-files/thread/testWorker.js', | |
938 | { workerChoiceStrategy } | |
939 | ) | |
940 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
941 | dynamicWorkerUsage: false, |
942 | dynamicWorkerReady: true | |
6c6afb84 JB |
943 | }) |
944 | // We need to clean up the resources after our test | |
945 | await pool.destroy() | |
946 | }) | |
947 | ||
948 | it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => { | |
594bfb84 | 949 | const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE |
10fcfaf4 JB |
950 | let pool = new FixedThreadPool( |
951 | max, | |
d710242d | 952 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 953 | { workerChoiceStrategy } |
10fcfaf4 | 954 | ) |
87de9ff5 JB |
955 | expect( |
956 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
957 | ).toStrictEqual({ | |
932fc8be JB |
958 | runTime: { |
959 | aggregate: true, | |
960 | average: true, | |
961 | median: false | |
962 | }, | |
963 | waitTime: { | |
964 | aggregate: false, | |
965 | average: false, | |
966 | median: false | |
967 | }, | |
5df69fab | 968 | elu: { |
9adcefab JB |
969 | aggregate: true, |
970 | average: true, | |
5df69fab JB |
971 | median: false |
972 | } | |
86bf340d | 973 | }) |
fd7ebd49 | 974 | await pool.destroy() |
10fcfaf4 JB |
975 | pool = new DynamicThreadPool( |
976 | min, | |
977 | max, | |
d710242d | 978 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 979 | { workerChoiceStrategy } |
10fcfaf4 | 980 | ) |
87de9ff5 JB |
981 | expect( |
982 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
983 | ).toStrictEqual({ | |
932fc8be JB |
984 | runTime: { |
985 | aggregate: true, | |
986 | average: true, | |
987 | median: false | |
988 | }, | |
989 | waitTime: { | |
990 | aggregate: false, | |
991 | average: false, | |
992 | median: false | |
993 | }, | |
5df69fab | 994 | elu: { |
9adcefab JB |
995 | aggregate: true, |
996 | average: true, | |
5df69fab JB |
997 | median: false |
998 | } | |
86bf340d | 999 | }) |
10fcfaf4 JB |
1000 | // We need to clean up the resources after our test |
1001 | await pool.destroy() | |
1002 | }) | |
1003 | ||
23ff945a | 1004 | it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => { |
23ff945a JB |
1005 | const pool = new FixedThreadPool( |
1006 | max, | |
1007 | './tests/worker-files/thread/testWorker.js', | |
1008 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
1009 | ) | |
1010 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
ee9f5295 | 1011 | const promises = new Set() |
a20f0ba5 JB |
1012 | const maxMultiplier = 2 |
1013 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1014 | promises.add(pool.execute()) |
23ff945a | 1015 | } |
e211bc18 | 1016 | await Promise.all(promises) |
138d29a8 | 1017 | for (const workerNode of pool.workerNodes) { |
71514351 | 1018 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 | 1019 | tasks: { |
d33be430 | 1020 | executed: expect.any(Number), |
a4e07f72 JB |
1021 | executing: 0, |
1022 | queued: 0, | |
df593701 | 1023 | maxQueued: 0, |
a4e07f72 JB |
1024 | failed: 0 |
1025 | }, | |
71514351 | 1026 | runTime: expect.objectContaining({ |
a4e07f72 | 1027 | history: expect.any(CircularArray) |
71514351 | 1028 | }), |
a4e07f72 | 1029 | waitTime: { |
a4e07f72 JB |
1030 | history: expect.any(CircularArray) |
1031 | }, | |
5df69fab | 1032 | elu: { |
71514351 | 1033 | idle: expect.objectContaining({ |
5df69fab | 1034 | history: expect.any(CircularArray) |
71514351 JB |
1035 | }), |
1036 | active: expect.objectContaining({ | |
5df69fab | 1037 | history: expect.any(CircularArray) |
71514351 | 1038 | }) |
5df69fab | 1039 | } |
86bf340d | 1040 | }) |
465b2940 JB |
1041 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1042 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
d33be430 JB |
1043 | max * maxMultiplier |
1044 | ) | |
71514351 JB |
1045 | if (workerNode.usage.runTime.aggregate == null) { |
1046 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1047 | } else { | |
1048 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1049 | } | |
1050 | if (workerNode.usage.runTime.average == null) { | |
1051 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1052 | } else { | |
1053 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1054 | } | |
1055 | if (workerNode.usage.elu.utilization == null) { | |
1056 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
1057 | } else { | |
1058 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
1059 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
1060 | } | |
138d29a8 | 1061 | } |
97a2abc3 | 1062 | expect( |
95c83464 | 1063 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1064 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
b0d6ed8f | 1065 | ).workersVirtualTaskEndTimestamp.length |
f06e48d8 | 1066 | ).toBe(pool.workerNodes.length) |
23ff945a JB |
1067 | // We need to clean up the resources after our test |
1068 | await pool.destroy() | |
1069 | }) | |
1070 | ||
1071 | it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => { | |
23ff945a JB |
1072 | const pool = new DynamicThreadPool( |
1073 | min, | |
1074 | max, | |
1075 | './tests/worker-files/thread/testWorker.js', | |
1076 | { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE } | |
1077 | ) | |
1078 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
ee9f5295 | 1079 | const promises = new Set() |
f7070eee | 1080 | const maxMultiplier = 2 |
804a889e | 1081 | for (let i = 0; i < max * maxMultiplier; i++) { |
ee9f5295 | 1082 | promises.add(pool.execute()) |
23ff945a | 1083 | } |
e211bc18 | 1084 | await Promise.all(promises) |
138d29a8 | 1085 | for (const workerNode of pool.workerNodes) { |
71514351 | 1086 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 | 1087 | tasks: { |
6c6afb84 | 1088 | executed: expect.any(Number), |
a4e07f72 JB |
1089 | executing: 0, |
1090 | queued: 0, | |
df593701 | 1091 | maxQueued: 0, |
a4e07f72 JB |
1092 | failed: 0 |
1093 | }, | |
71514351 | 1094 | runTime: expect.objectContaining({ |
a4e07f72 | 1095 | history: expect.any(CircularArray) |
71514351 | 1096 | }), |
a4e07f72 | 1097 | waitTime: { |
a4e07f72 JB |
1098 | history: expect.any(CircularArray) |
1099 | }, | |
5df69fab | 1100 | elu: { |
71514351 | 1101 | idle: expect.objectContaining({ |
5df69fab | 1102 | history: expect.any(CircularArray) |
71514351 JB |
1103 | }), |
1104 | active: expect.objectContaining({ | |
5df69fab | 1105 | history: expect.any(CircularArray) |
71514351 | 1106 | }) |
5df69fab | 1107 | } |
86bf340d | 1108 | }) |
465b2940 JB |
1109 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1110 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
6c6afb84 JB |
1111 | max * maxMultiplier |
1112 | ) | |
71514351 JB |
1113 | if (workerNode.usage.runTime.aggregate == null) { |
1114 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1115 | } else { | |
1116 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1117 | } | |
1118 | if (workerNode.usage.runTime.average == null) { | |
1119 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1120 | } else { | |
1121 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1122 | } | |
1123 | if (workerNode.usage.elu.utilization == null) { | |
1124 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
1125 | } else { | |
1126 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
1127 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
1128 | } | |
138d29a8 | 1129 | } |
2b4fddb8 JB |
1130 | expect( |
1131 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1132 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
b0d6ed8f | 1133 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1134 | ).toBe(pool.workerNodes.length) |
23ff945a JB |
1135 | // We need to clean up the resources after our test |
1136 | await pool.destroy() | |
1137 | }) | |
1138 | ||
9e775f96 | 1139 | it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => { |
010d7020 JB |
1140 | const pool = new DynamicThreadPool( |
1141 | min, | |
1142 | max, | |
1143 | './tests/worker-files/thread/testWorker.js', | |
1144 | { | |
1145 | workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE, | |
1146 | workerChoiceStrategyOptions: { | |
932fc8be | 1147 | runTime: { median: true } |
010d7020 JB |
1148 | } |
1149 | } | |
1150 | ) | |
1151 | // TODO: Create a better test to cover `FairShareChoiceStrategy#choose` | |
ee9f5295 | 1152 | const promises = new Set() |
010d7020 JB |
1153 | const maxMultiplier = 2 |
1154 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1155 | promises.add(pool.execute()) |
010d7020 | 1156 | } |
e211bc18 | 1157 | await Promise.all(promises) |
010d7020 | 1158 | for (const workerNode of pool.workerNodes) { |
71514351 | 1159 | expect(workerNode.usage).toMatchObject({ |
a4e07f72 | 1160 | tasks: { |
6c6afb84 | 1161 | executed: expect.any(Number), |
a4e07f72 JB |
1162 | executing: 0, |
1163 | queued: 0, | |
df593701 | 1164 | maxQueued: 0, |
a4e07f72 JB |
1165 | failed: 0 |
1166 | }, | |
71514351 | 1167 | runTime: expect.objectContaining({ |
a4e07f72 | 1168 | history: expect.any(CircularArray) |
71514351 | 1169 | }), |
a4e07f72 | 1170 | waitTime: { |
a4e07f72 JB |
1171 | history: expect.any(CircularArray) |
1172 | }, | |
5df69fab | 1173 | elu: { |
71514351 | 1174 | idle: expect.objectContaining({ |
5df69fab | 1175 | history: expect.any(CircularArray) |
71514351 JB |
1176 | }), |
1177 | active: expect.objectContaining({ | |
5df69fab | 1178 | history: expect.any(CircularArray) |
71514351 | 1179 | }) |
5df69fab | 1180 | } |
86bf340d | 1181 | }) |
465b2940 JB |
1182 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1183 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
6c6afb84 JB |
1184 | max * maxMultiplier |
1185 | ) | |
71514351 JB |
1186 | if (workerNode.usage.runTime.aggregate == null) { |
1187 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1188 | } else { | |
1189 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1190 | } | |
1191 | if (workerNode.usage.runTime.median == null) { | |
1192 | expect(workerNode.usage.runTime.median).toBeUndefined() | |
1193 | } else { | |
1194 | expect(workerNode.usage.runTime.median).toBeGreaterThan(0) | |
1195 | } | |
1196 | if (workerNode.usage.elu.utilization == null) { | |
1197 | expect(workerNode.usage.elu.utilization).toBeUndefined() | |
1198 | } else { | |
1199 | expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) | |
1200 | expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1) | |
1201 | } | |
010d7020 | 1202 | } |
2b4fddb8 JB |
1203 | expect( |
1204 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1205 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
b0d6ed8f | 1206 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1207 | ).toBe(pool.workerNodes.length) |
010d7020 JB |
1208 | // We need to clean up the resources after our test |
1209 | await pool.destroy() | |
1210 | }) | |
1211 | ||
a6f7f1b4 | 1212 | it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => { |
594bfb84 | 1213 | const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE |
f0829c53 | 1214 | let pool = new FixedThreadPool( |
caeb9817 JB |
1215 | max, |
1216 | './tests/worker-files/thread/testWorker.js' | |
1217 | ) | |
1218 | expect( | |
95c83464 | 1219 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1220 | workerChoiceStrategy |
b0d6ed8f | 1221 | ).workersVirtualTaskEndTimestamp |
08f3f44c JB |
1222 | ).toBeInstanceOf(Array) |
1223 | expect( | |
1224 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1225 | workerChoiceStrategy | |
b0d6ed8f | 1226 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 1227 | ).toBe(0) |
2b4fddb8 JB |
1228 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
1229 | workerChoiceStrategy | |
b0d6ed8f | 1230 | ).workersVirtualTaskEndTimestamp[0] = performance.now() |
2b4fddb8 JB |
1231 | expect( |
1232 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1233 | workerChoiceStrategy | |
b0d6ed8f | 1234 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1235 | ).toBe(1) |
594bfb84 | 1236 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
08f3f44c JB |
1237 | expect( |
1238 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1239 | workerChoiceStrategy | |
b0d6ed8f | 1240 | ).workersVirtualTaskEndTimestamp |
08f3f44c | 1241 | ).toBeInstanceOf(Array) |
08f3f44c JB |
1242 | expect( |
1243 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1244 | workerChoiceStrategy | |
b0d6ed8f | 1245 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1246 | ).toBe(0) |
f0829c53 JB |
1247 | await pool.destroy() |
1248 | pool = new DynamicThreadPool( | |
1249 | min, | |
1250 | max, | |
1251 | './tests/worker-files/thread/testWorker.js' | |
1252 | ) | |
1253 | expect( | |
95c83464 | 1254 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1255 | workerChoiceStrategy |
b0d6ed8f | 1256 | ).workersVirtualTaskEndTimestamp |
08f3f44c | 1257 | ).toBeInstanceOf(Array) |
2b4fddb8 JB |
1258 | expect( |
1259 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1260 | workerChoiceStrategy | |
b0d6ed8f | 1261 | ).workersVirtualTaskEndTimestamp.length |
2b4fddb8 | 1262 | ).toBe(0) |
08f3f44c JB |
1263 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
1264 | workerChoiceStrategy | |
b0d6ed8f | 1265 | ).workersVirtualTaskEndTimestamp[0] = performance.now() |
08f3f44c JB |
1266 | expect( |
1267 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1268 | workerChoiceStrategy | |
b0d6ed8f | 1269 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 1270 | ).toBe(1) |
594bfb84 | 1271 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
08f3f44c JB |
1272 | expect( |
1273 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1274 | workerChoiceStrategy | |
b0d6ed8f | 1275 | ).workersVirtualTaskEndTimestamp |
08f3f44c JB |
1276 | ).toBeInstanceOf(Array) |
1277 | expect( | |
1278 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1279 | workerChoiceStrategy | |
b0d6ed8f | 1280 | ).workersVirtualTaskEndTimestamp.length |
08f3f44c | 1281 | ).toBe(0) |
caeb9817 JB |
1282 | // We need to clean up the resources after our test |
1283 | await pool.destroy() | |
1284 | }) | |
1285 | ||
6c6afb84 JB |
1286 | it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => { |
1287 | const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN | |
1288 | let pool = new FixedThreadPool( | |
1289 | max, | |
1290 | './tests/worker-files/thread/testWorker.js', | |
1291 | { workerChoiceStrategy } | |
1292 | ) | |
1293 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1294 | dynamicWorkerUsage: false, |
1295 | dynamicWorkerReady: true | |
6c6afb84 JB |
1296 | }) |
1297 | await pool.destroy() | |
1298 | pool = new DynamicThreadPool( | |
1299 | min, | |
1300 | max, | |
1301 | './tests/worker-files/thread/testWorker.js', | |
1302 | { workerChoiceStrategy } | |
1303 | ) | |
1304 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1305 | dynamicWorkerUsage: false, |
1306 | dynamicWorkerReady: true | |
6c6afb84 JB |
1307 | }) |
1308 | // We need to clean up the resources after our test | |
1309 | await pool.destroy() | |
1310 | }) | |
1311 | ||
1312 | it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => { | |
594bfb84 | 1313 | const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN |
10fcfaf4 JB |
1314 | let pool = new FixedThreadPool( |
1315 | max, | |
d710242d | 1316 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 1317 | { workerChoiceStrategy } |
10fcfaf4 | 1318 | ) |
87de9ff5 JB |
1319 | expect( |
1320 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1321 | ).toStrictEqual({ | |
932fc8be JB |
1322 | runTime: { |
1323 | aggregate: true, | |
1324 | average: true, | |
1325 | median: false | |
1326 | }, | |
1327 | waitTime: { | |
1328 | aggregate: false, | |
1329 | average: false, | |
1330 | median: false | |
1331 | }, | |
5df69fab JB |
1332 | elu: { |
1333 | aggregate: false, | |
1334 | average: false, | |
1335 | median: false | |
1336 | } | |
86bf340d | 1337 | }) |
fd7ebd49 | 1338 | await pool.destroy() |
10fcfaf4 JB |
1339 | pool = new DynamicThreadPool( |
1340 | min, | |
1341 | max, | |
d710242d | 1342 | './tests/worker-files/thread/testWorker.js', |
594bfb84 | 1343 | { workerChoiceStrategy } |
10fcfaf4 | 1344 | ) |
87de9ff5 JB |
1345 | expect( |
1346 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1347 | ).toStrictEqual({ | |
932fc8be JB |
1348 | runTime: { |
1349 | aggregate: true, | |
1350 | average: true, | |
1351 | median: false | |
1352 | }, | |
1353 | waitTime: { | |
1354 | aggregate: false, | |
1355 | average: false, | |
1356 | median: false | |
1357 | }, | |
5df69fab JB |
1358 | elu: { |
1359 | aggregate: false, | |
1360 | average: false, | |
1361 | median: false | |
1362 | } | |
86bf340d | 1363 | }) |
10fcfaf4 JB |
1364 | // We need to clean up the resources after our test |
1365 | await pool.destroy() | |
1366 | }) | |
1367 | ||
b3432a63 | 1368 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
b3432a63 JB |
1369 | const pool = new FixedThreadPool( |
1370 | max, | |
1371 | './tests/worker-files/thread/testWorker.js', | |
1372 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
1373 | ) | |
1374 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
ee9f5295 | 1375 | const promises = new Set() |
a20f0ba5 JB |
1376 | const maxMultiplier = 2 |
1377 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1378 | promises.add(pool.execute()) |
b3432a63 | 1379 | } |
e211bc18 | 1380 | await Promise.all(promises) |
138d29a8 | 1381 | for (const workerNode of pool.workerNodes) { |
465b2940 | 1382 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1383 | tasks: { |
1384 | executed: expect.any(Number), | |
1385 | executing: 0, | |
1386 | queued: 0, | |
df593701 | 1387 | maxQueued: 0, |
a4e07f72 JB |
1388 | failed: 0 |
1389 | }, | |
71514351 | 1390 | runTime: expect.objectContaining({ |
a4e07f72 | 1391 | history: expect.any(CircularArray) |
71514351 | 1392 | }), |
a4e07f72 | 1393 | waitTime: { |
a4e07f72 JB |
1394 | history: expect.any(CircularArray) |
1395 | }, | |
5df69fab JB |
1396 | elu: { |
1397 | idle: { | |
5df69fab JB |
1398 | history: expect.any(CircularArray) |
1399 | }, | |
1400 | active: { | |
5df69fab | 1401 | history: expect.any(CircularArray) |
71514351 | 1402 | } |
5df69fab | 1403 | } |
86bf340d | 1404 | }) |
465b2940 JB |
1405 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1406 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
1407 | max * maxMultiplier |
1408 | ) | |
71514351 JB |
1409 | if (workerNode.usage.runTime.aggregate == null) { |
1410 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1411 | } else { | |
1412 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1413 | } | |
1414 | if (workerNode.usage.runTime.average == null) { | |
1415 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1416 | } else { | |
1417 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1418 | } | |
138d29a8 | 1419 | } |
97a2abc3 | 1420 | expect( |
95c83464 | 1421 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1422 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
08f3f44c JB |
1423 | ).defaultWorkerWeight |
1424 | ).toBeGreaterThan(0) | |
1425 | expect( | |
1426 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1427 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1428 | ).workerVirtualTaskRunTime | |
1429 | ).toBeGreaterThanOrEqual(0) | |
b3432a63 JB |
1430 | // We need to clean up the resources after our test |
1431 | await pool.destroy() | |
1432 | }) | |
1433 | ||
1434 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
b3432a63 JB |
1435 | const pool = new DynamicThreadPool( |
1436 | min, | |
1437 | max, | |
1438 | './tests/worker-files/thread/testWorker.js', | |
1439 | { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN } | |
1440 | ) | |
1441 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
ee9f5295 | 1442 | const promises = new Set() |
138d29a8 | 1443 | const maxMultiplier = 2 |
5502c07c | 1444 | for (let i = 0; i < max * maxMultiplier; i++) { |
ee9f5295 | 1445 | promises.add(pool.execute()) |
b3432a63 | 1446 | } |
e211bc18 | 1447 | await Promise.all(promises) |
138d29a8 | 1448 | for (const workerNode of pool.workerNodes) { |
465b2940 | 1449 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1450 | tasks: { |
1451 | executed: expect.any(Number), | |
1452 | executing: 0, | |
1453 | queued: 0, | |
df593701 | 1454 | maxQueued: 0, |
a4e07f72 JB |
1455 | failed: 0 |
1456 | }, | |
b1aae695 | 1457 | runTime: expect.objectContaining({ |
a4e07f72 | 1458 | history: expect.any(CircularArray) |
b1aae695 | 1459 | }), |
a4e07f72 | 1460 | waitTime: { |
a4e07f72 JB |
1461 | history: expect.any(CircularArray) |
1462 | }, | |
5df69fab JB |
1463 | elu: { |
1464 | idle: { | |
5df69fab JB |
1465 | history: expect.any(CircularArray) |
1466 | }, | |
1467 | active: { | |
5df69fab | 1468 | history: expect.any(CircularArray) |
71514351 | 1469 | } |
5df69fab | 1470 | } |
86bf340d | 1471 | }) |
465b2940 JB |
1472 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1473 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
1474 | max * maxMultiplier |
1475 | ) | |
b1aae695 JB |
1476 | if (workerNode.usage.runTime.aggregate == null) { |
1477 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1478 | } else { | |
1479 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1480 | } | |
1481 | if (workerNode.usage.runTime.average == null) { | |
1482 | expect(workerNode.usage.runTime.average).toBeUndefined() | |
1483 | } else { | |
1484 | expect(workerNode.usage.runTime.average).toBeGreaterThan(0) | |
1485 | } | |
138d29a8 | 1486 | } |
2b4fddb8 JB |
1487 | expect( |
1488 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1489 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1490 | ).defaultWorkerWeight | |
1491 | ).toBeGreaterThan(0) | |
1492 | expect( | |
1493 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1494 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1495 | ).workerVirtualTaskRunTime | |
1496 | ).toBeGreaterThanOrEqual(0) | |
b3432a63 JB |
1497 | // We need to clean up the resources after our test |
1498 | await pool.destroy() | |
1499 | }) | |
1500 | ||
9e775f96 | 1501 | it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => { |
010d7020 JB |
1502 | const pool = new DynamicThreadPool( |
1503 | min, | |
1504 | max, | |
1505 | './tests/worker-files/thread/testWorker.js', | |
1506 | { | |
1507 | workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN, | |
1508 | workerChoiceStrategyOptions: { | |
932fc8be | 1509 | runTime: { median: true } |
010d7020 JB |
1510 | } |
1511 | } | |
1512 | ) | |
1513 | // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose` | |
ee9f5295 | 1514 | const promises = new Set() |
010d7020 JB |
1515 | const maxMultiplier = 2 |
1516 | for (let i = 0; i < max * maxMultiplier; i++) { | |
ee9f5295 | 1517 | promises.add(pool.execute()) |
010d7020 | 1518 | } |
e211bc18 | 1519 | await Promise.all(promises) |
010d7020 | 1520 | for (const workerNode of pool.workerNodes) { |
465b2940 | 1521 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1522 | tasks: { |
1523 | executed: expect.any(Number), | |
1524 | executing: 0, | |
1525 | queued: 0, | |
df593701 | 1526 | maxQueued: 0, |
a4e07f72 JB |
1527 | failed: 0 |
1528 | }, | |
b1aae695 | 1529 | runTime: expect.objectContaining({ |
a4e07f72 | 1530 | history: expect.any(CircularArray) |
b1aae695 | 1531 | }), |
a4e07f72 | 1532 | waitTime: { |
a4e07f72 JB |
1533 | history: expect.any(CircularArray) |
1534 | }, | |
5df69fab JB |
1535 | elu: { |
1536 | idle: { | |
5df69fab JB |
1537 | history: expect.any(CircularArray) |
1538 | }, | |
1539 | active: { | |
5df69fab | 1540 | history: expect.any(CircularArray) |
71514351 | 1541 | } |
5df69fab | 1542 | } |
86bf340d | 1543 | }) |
465b2940 JB |
1544 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1545 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
a4e07f72 JB |
1546 | max * maxMultiplier |
1547 | ) | |
b1aae695 JB |
1548 | if (workerNode.usage.runTime.aggregate == null) { |
1549 | expect(workerNode.usage.runTime.aggregate).toBeUndefined() | |
1550 | } else { | |
1551 | expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) | |
1552 | } | |
1553 | if (workerNode.usage.runTime.median == null) { | |
1554 | expect(workerNode.usage.runTime.median).toBeUndefined() | |
1555 | } else { | |
1556 | expect(workerNode.usage.runTime.median).toBeGreaterThan(0) | |
1557 | } | |
010d7020 | 1558 | } |
08f3f44c JB |
1559 | expect( |
1560 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1561 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1562 | ).defaultWorkerWeight | |
1563 | ).toBeGreaterThan(0) | |
1564 | expect( | |
1565 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1566 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1567 | ).workerVirtualTaskRunTime | |
1568 | ).toBeGreaterThanOrEqual(0) | |
010d7020 JB |
1569 | // We need to clean up the resources after our test |
1570 | await pool.destroy() | |
1571 | }) | |
1572 | ||
a6f7f1b4 | 1573 | it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => { |
594bfb84 | 1574 | const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN |
f0829c53 | 1575 | let pool = new FixedThreadPool( |
caeb9817 JB |
1576 | max, |
1577 | './tests/worker-files/thread/testWorker.js' | |
1578 | ) | |
38f6e859 | 1579 | expect( |
95c83464 | 1580 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1581 | workerChoiceStrategy |
9b106837 | 1582 | ).nextWorkerNodeKey |
b529c323 | 1583 | ).toBeDefined() |
38f6e859 | 1584 | expect( |
95c83464 | 1585 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1586 | workerChoiceStrategy |
b529c323 JB |
1587 | ).defaultWorkerWeight |
1588 | ).toBeDefined() | |
caeb9817 | 1589 | expect( |
95c83464 | 1590 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1591 | workerChoiceStrategy |
08f3f44c | 1592 | ).workerVirtualTaskRunTime |
b529c323 | 1593 | ).toBeDefined() |
594bfb84 | 1594 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 1595 | expect( |
95c83464 | 1596 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1597 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 1598 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
1599 | ).toBe(0) |
1600 | expect( | |
95c83464 | 1601 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1602 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
95c83464 | 1603 | ).defaultWorkerWeight |
a6f7f1b4 | 1604 | ).toBeGreaterThan(0) |
08f3f44c JB |
1605 | expect( |
1606 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1607 | workerChoiceStrategy | |
1608 | ).workerVirtualTaskRunTime | |
1609 | ).toBe(0) | |
f0829c53 JB |
1610 | await pool.destroy() |
1611 | pool = new DynamicThreadPool( | |
1612 | min, | |
1613 | max, | |
1614 | './tests/worker-files/thread/testWorker.js' | |
1615 | ) | |
38f6e859 | 1616 | expect( |
95c83464 | 1617 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1618 | workerChoiceStrategy |
9b106837 | 1619 | ).nextWorkerNodeKey |
b529c323 | 1620 | ).toBeDefined() |
38f6e859 | 1621 | expect( |
95c83464 | 1622 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1623 | workerChoiceStrategy |
b529c323 JB |
1624 | ).defaultWorkerWeight |
1625 | ).toBeDefined() | |
f0829c53 | 1626 | expect( |
95c83464 | 1627 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
594bfb84 | 1628 | workerChoiceStrategy |
08f3f44c | 1629 | ).workerVirtualTaskRunTime |
b529c323 | 1630 | ).toBeDefined() |
594bfb84 | 1631 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) |
a6f7f1b4 | 1632 | expect( |
95c83464 | 1633 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1634 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
9b106837 | 1635 | ).nextWorkerNodeKey |
a6f7f1b4 JB |
1636 | ).toBe(0) |
1637 | expect( | |
95c83464 | 1638 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( |
d710242d | 1639 | pool.workerChoiceStrategyContext.workerChoiceStrategy |
95c83464 | 1640 | ).defaultWorkerWeight |
a6f7f1b4 | 1641 | ).toBeGreaterThan(0) |
08f3f44c JB |
1642 | expect( |
1643 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1644 | workerChoiceStrategy | |
1645 | ).workerVirtualTaskRunTime | |
1646 | ).toBe(0) | |
caeb9817 JB |
1647 | // We need to clean up the resources after our test |
1648 | await pool.destroy() | |
1649 | }) | |
1650 | ||
6c6afb84 JB |
1651 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => { |
1652 | const workerChoiceStrategy = | |
1653 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1654 | let pool = new FixedThreadPool( | |
1655 | max, | |
1656 | './tests/worker-files/thread/testWorker.js', | |
1657 | { workerChoiceStrategy } | |
1658 | ) | |
1659 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1660 | dynamicWorkerUsage: false, |
1661 | dynamicWorkerReady: true | |
6c6afb84 JB |
1662 | }) |
1663 | await pool.destroy() | |
1664 | pool = new DynamicThreadPool( | |
1665 | min, | |
1666 | max, | |
1667 | './tests/worker-files/thread/testWorker.js', | |
1668 | { workerChoiceStrategy } | |
1669 | ) | |
1670 | expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ | |
b1aae695 JB |
1671 | dynamicWorkerUsage: false, |
1672 | dynamicWorkerReady: true | |
6c6afb84 JB |
1673 | }) |
1674 | // We need to clean up the resources after our test | |
1675 | await pool.destroy() | |
1676 | }) | |
1677 | ||
1678 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => { | |
e52fb978 JB |
1679 | const workerChoiceStrategy = |
1680 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1681 | let pool = new FixedThreadPool( | |
1682 | max, | |
1683 | './tests/worker-files/thread/testWorker.js', | |
1684 | { workerChoiceStrategy } | |
1685 | ) | |
87de9ff5 JB |
1686 | expect( |
1687 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1688 | ).toStrictEqual({ | |
932fc8be JB |
1689 | runTime: { |
1690 | aggregate: false, | |
1691 | average: false, | |
1692 | median: false | |
1693 | }, | |
1694 | waitTime: { | |
1695 | aggregate: false, | |
1696 | average: false, | |
1697 | median: false | |
1698 | }, | |
5df69fab JB |
1699 | elu: { |
1700 | aggregate: false, | |
1701 | average: false, | |
1702 | median: false | |
1703 | } | |
e52fb978 JB |
1704 | }) |
1705 | await pool.destroy() | |
1706 | pool = new DynamicThreadPool( | |
1707 | min, | |
1708 | max, | |
1709 | './tests/worker-files/thread/testWorker.js', | |
1710 | { workerChoiceStrategy } | |
1711 | ) | |
87de9ff5 JB |
1712 | expect( |
1713 | pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() | |
1714 | ).toStrictEqual({ | |
932fc8be JB |
1715 | runTime: { |
1716 | aggregate: false, | |
1717 | average: false, | |
1718 | median: false | |
1719 | }, | |
1720 | waitTime: { | |
1721 | aggregate: false, | |
1722 | average: false, | |
1723 | median: false | |
1724 | }, | |
5df69fab JB |
1725 | elu: { |
1726 | aggregate: false, | |
1727 | average: false, | |
1728 | median: false | |
1729 | } | |
e52fb978 JB |
1730 | }) |
1731 | // We need to clean up the resources after our test | |
1732 | await pool.destroy() | |
1733 | }) | |
1734 | ||
e62e7646 JB |
1735 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => { |
1736 | const pool = new FixedThreadPool( | |
1737 | max, | |
1738 | './tests/worker-files/thread/testWorker.js', | |
1739 | { | |
1740 | workerChoiceStrategy: | |
1741 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1742 | } | |
1743 | ) | |
1744 | // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose` | |
1745 | const promises = new Set() | |
1746 | const maxMultiplier = 2 | |
1747 | for (let i = 0; i < max * maxMultiplier; i++) { | |
1748 | promises.add(pool.execute()) | |
1749 | } | |
1750 | await Promise.all(promises) | |
1751 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 1752 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 JB |
1753 | tasks: { |
1754 | executed: maxMultiplier, | |
1755 | executing: 0, | |
1756 | queued: 0, | |
df593701 | 1757 | maxQueued: 0, |
a4e07f72 JB |
1758 | failed: 0 |
1759 | }, | |
1760 | runTime: { | |
a4e07f72 JB |
1761 | history: expect.any(CircularArray) |
1762 | }, | |
1763 | waitTime: { | |
a4e07f72 JB |
1764 | history: expect.any(CircularArray) |
1765 | }, | |
5df69fab JB |
1766 | elu: { |
1767 | idle: { | |
5df69fab JB |
1768 | history: expect.any(CircularArray) |
1769 | }, | |
1770 | active: { | |
5df69fab | 1771 | history: expect.any(CircularArray) |
71514351 | 1772 | } |
5df69fab | 1773 | } |
e62e7646 JB |
1774 | }) |
1775 | } | |
1776 | expect( | |
1777 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1778 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1779 | ).defaultWorkerWeight | |
1780 | ).toBeGreaterThan(0) | |
1781 | expect( | |
1782 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1783 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
d33be430 | 1784 | ).roundId |
e62e7646 JB |
1785 | ).toBe(0) |
1786 | expect( | |
1787 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1788 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1789 | ).nextWorkerNodeKey |
e62e7646 JB |
1790 | ).toBe(0) |
1791 | expect( | |
1792 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1793 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1794 | ).roundWeights | |
1795 | ).toStrictEqual([ | |
1796 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1797 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1798 | ).defaultWorkerWeight | |
1799 | ]) | |
1800 | // We need to clean up the resources after our test | |
1801 | await pool.destroy() | |
1802 | }) | |
1803 | ||
1804 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => { | |
1805 | const pool = new DynamicThreadPool( | |
1806 | min, | |
1807 | max, | |
1808 | './tests/worker-files/thread/testWorker.js', | |
1809 | { | |
1810 | workerChoiceStrategy: | |
1811 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1812 | } | |
1813 | ) | |
1814 | // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose` | |
1815 | const promises = new Set() | |
1816 | const maxMultiplier = 2 | |
1817 | for (let i = 0; i < max * maxMultiplier; i++) { | |
1818 | promises.add(pool.execute()) | |
1819 | } | |
1820 | await Promise.all(promises) | |
1821 | for (const workerNode of pool.workerNodes) { | |
465b2940 | 1822 | expect(workerNode.usage).toStrictEqual({ |
a4e07f72 | 1823 | tasks: { |
b1aae695 | 1824 | executed: expect.any(Number), |
a4e07f72 JB |
1825 | executing: 0, |
1826 | queued: 0, | |
df593701 | 1827 | maxQueued: 0, |
a4e07f72 JB |
1828 | failed: 0 |
1829 | }, | |
1830 | runTime: { | |
a4e07f72 JB |
1831 | history: expect.any(CircularArray) |
1832 | }, | |
1833 | waitTime: { | |
a4e07f72 JB |
1834 | history: expect.any(CircularArray) |
1835 | }, | |
5df69fab JB |
1836 | elu: { |
1837 | idle: { | |
5df69fab JB |
1838 | history: expect.any(CircularArray) |
1839 | }, | |
1840 | active: { | |
5df69fab | 1841 | history: expect.any(CircularArray) |
71514351 | 1842 | } |
5df69fab | 1843 | } |
e62e7646 | 1844 | }) |
e43b8c2d JB |
1845 | expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) |
1846 | expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( | |
1847 | max * maxMultiplier | |
1848 | ) | |
e62e7646 JB |
1849 | } |
1850 | expect( | |
1851 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1852 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1853 | ).defaultWorkerWeight | |
1854 | ).toBeGreaterThan(0) | |
1855 | expect( | |
1856 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1857 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
d33be430 | 1858 | ).roundId |
e62e7646 JB |
1859 | ).toBe(0) |
1860 | expect( | |
1861 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1862 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1863 | ).nextWorkerNodeKey |
d2c73f82 | 1864 | ).toBe(0) |
e62e7646 JB |
1865 | expect( |
1866 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1867 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1868 | ).roundWeights | |
1869 | ).toStrictEqual([ | |
1870 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1871 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1872 | ).defaultWorkerWeight | |
1873 | ]) | |
1874 | // We need to clean up the resources after our test | |
1875 | await pool.destroy() | |
1876 | }) | |
1877 | ||
8c3ec188 JB |
1878 | it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => { |
1879 | const workerChoiceStrategy = | |
1880 | WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN | |
1881 | let pool = new FixedThreadPool( | |
1882 | max, | |
1883 | './tests/worker-files/thread/testWorker.js' | |
1884 | ) | |
1885 | expect( | |
1886 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1887 | workerChoiceStrategy | |
d33be430 | 1888 | ).roundId |
8c3ec188 JB |
1889 | ).toBeDefined() |
1890 | expect( | |
1891 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1892 | workerChoiceStrategy | |
9b106837 | 1893 | ).nextWorkerNodeKey |
8c3ec188 JB |
1894 | ).toBeDefined() |
1895 | expect( | |
1896 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1897 | workerChoiceStrategy | |
1898 | ).defaultWorkerWeight | |
1899 | ).toBeDefined() | |
1900 | expect( | |
1901 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1902 | workerChoiceStrategy | |
1903 | ).roundWeights | |
1904 | ).toBeDefined() | |
1905 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) | |
1906 | expect( | |
1907 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1908 | workerChoiceStrategy | |
d33be430 | 1909 | ).roundId |
8c3ec188 JB |
1910 | ).toBe(0) |
1911 | expect( | |
1912 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1913 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1914 | ).nextWorkerNodeKey |
8c3ec188 JB |
1915 | ).toBe(0) |
1916 | expect( | |
1917 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1918 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1919 | ).defaultWorkerWeight | |
1920 | ).toBeGreaterThan(0) | |
1921 | expect( | |
1922 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1923 | workerChoiceStrategy | |
1924 | ).roundWeights | |
1925 | ).toStrictEqual([ | |
1926 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1927 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1928 | ).defaultWorkerWeight | |
1929 | ]) | |
1930 | await pool.destroy() | |
1931 | pool = new DynamicThreadPool( | |
1932 | min, | |
1933 | max, | |
1934 | './tests/worker-files/thread/testWorker.js' | |
1935 | ) | |
1936 | expect( | |
1937 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1938 | workerChoiceStrategy | |
d33be430 | 1939 | ).roundId |
8c3ec188 JB |
1940 | ).toBeDefined() |
1941 | expect( | |
1942 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1943 | workerChoiceStrategy | |
9b106837 | 1944 | ).nextWorkerNodeKey |
8c3ec188 JB |
1945 | ).toBeDefined() |
1946 | expect( | |
1947 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1948 | workerChoiceStrategy | |
1949 | ).defaultWorkerWeight | |
1950 | ).toBeDefined() | |
1951 | expect( | |
1952 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1953 | workerChoiceStrategy | |
1954 | ).roundWeights | |
1955 | ).toBeDefined() | |
1956 | pool.setWorkerChoiceStrategy(workerChoiceStrategy) | |
1957 | expect( | |
1958 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1959 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
9b106837 | 1960 | ).nextWorkerNodeKey |
8c3ec188 JB |
1961 | ).toBe(0) |
1962 | expect( | |
1963 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1964 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1965 | ).defaultWorkerWeight | |
1966 | ).toBeGreaterThan(0) | |
1967 | expect( | |
1968 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1969 | workerChoiceStrategy | |
1970 | ).roundWeights | |
1971 | ).toStrictEqual([ | |
1972 | pool.workerChoiceStrategyContext.workerChoiceStrategies.get( | |
1973 | pool.workerChoiceStrategyContext.workerChoiceStrategy | |
1974 | ).defaultWorkerWeight | |
1975 | ]) | |
1976 | // We need to clean up the resources after our test | |
1977 | await pool.destroy() | |
1978 | }) | |
1979 | ||
89b09b26 | 1980 | it('Verify unknown strategy throw error', () => { |
a35560ba S |
1981 | expect( |
1982 | () => | |
1983 | new DynamicThreadPool( | |
1984 | min, | |
1985 | max, | |
1986 | './tests/worker-files/thread/testWorker.js', | |
1927ee67 | 1987 | { workerChoiceStrategy: 'UNKNOWN_STRATEGY' } |
a35560ba | 1988 | ) |
d4aeae5a | 1989 | ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'") |
a35560ba S |
1990 | }) |
1991 | }) |