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