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