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