Merge branch 'master' into elu-strategy
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
1 const { expect } = require('expect')
2 const {
3 WorkerChoiceStrategies,
4 DynamicThreadPool,
5 FixedThreadPool,
6 FixedClusterPool
7 } = require('../../../lib')
8 const { CircularArray } = require('../../../lib/circular-array')
9
10 describe('Selection strategies test suite', () => {
11 const min = 0
12 const max = 3
13
14 it('Verify that WorkerChoiceStrategies enumeration provides string values', () => {
15 expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN')
16 expect(WorkerChoiceStrategies.LEAST_USED).toBe('LEAST_USED')
17 expect(WorkerChoiceStrategies.LEAST_BUSY).toBe('LEAST_BUSY')
18 expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE')
19 expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe(
20 'WEIGHTED_ROUND_ROBIN'
21 )
22 expect(WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN).toBe(
23 'INTERLEAVED_WEIGHTED_ROUND_ROBIN'
24 )
25 })
26
27 it('Verify ROUND_ROBIN strategy is the default at pool creation', async () => {
28 const pool = new DynamicThreadPool(
29 min,
30 max,
31 './tests/worker-files/thread/testWorker.js'
32 )
33 expect(pool.opts.workerChoiceStrategy).toBe(
34 WorkerChoiceStrategies.ROUND_ROBIN
35 )
36 // We need to clean up the resources after our test
37 await pool.destroy()
38 })
39
40 it('Verify available strategies are taken at pool creation', async () => {
41 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
42 const pool = new FixedThreadPool(
43 max,
44 './tests/worker-files/thread/testWorker.js',
45 { workerChoiceStrategy }
46 )
47 expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy)
48 expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe(
49 workerChoiceStrategy
50 )
51 await pool.destroy()
52 }
53 })
54
55 it('Verify available strategies can be set after pool creation', async () => {
56 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
57 const pool = new DynamicThreadPool(
58 min,
59 max,
60 './tests/worker-files/thread/testWorker.js'
61 )
62 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
63 expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy)
64 expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe(
65 workerChoiceStrategy
66 )
67 await pool.destroy()
68 }
69 })
70
71 it('Verify available strategies default internals at pool creation', async () => {
72 const pool = new FixedThreadPool(
73 max,
74 './tests/worker-files/thread/testWorker.js'
75 )
76 for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) {
77 if (workerChoiceStrategy === WorkerChoiceStrategies.ROUND_ROBIN) {
78 expect(
79 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
80 workerChoiceStrategy
81 ).nextWorkerNodeId
82 ).toBe(0)
83 } else if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) {
84 expect(
85 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
86 workerChoiceStrategy
87 ).workersVirtualTaskEndTimestamp
88 ).toBeInstanceOf(Array)
89 expect(
90 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
91 workerChoiceStrategy
92 ).workersVirtualTaskEndTimestamp.length
93 ).toBe(0)
94 } else if (
95 workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
96 ) {
97 expect(
98 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
99 workerChoiceStrategy
100 ).currentWorkerNodeId
101 ).toBe(0)
102 expect(
103 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
104 workerChoiceStrategy
105 ).defaultWorkerWeight
106 ).toBeGreaterThan(0)
107 expect(
108 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
109 workerChoiceStrategy
110 ).workerVirtualTaskRunTime
111 ).toBe(0)
112 }
113 }
114 await pool.destroy()
115 })
116
117 it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
118 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
119 let pool = new FixedThreadPool(
120 max,
121 './tests/worker-files/thread/testWorker.js',
122 { workerChoiceStrategy }
123 )
124 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
125 runTime: false,
126 avgRunTime: false,
127 medRunTime: false,
128 waitTime: false,
129 avgWaitTime: false,
130 medWaitTime: false,
131 elu: false
132 })
133 await pool.destroy()
134 pool = new DynamicThreadPool(
135 min,
136 max,
137 './tests/worker-files/thread/testWorker.js',
138 { workerChoiceStrategy }
139 )
140 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
141 runTime: false,
142 avgRunTime: false,
143 medRunTime: false,
144 waitTime: false,
145 avgWaitTime: false,
146 medWaitTime: false,
147 elu: false
148 })
149 // We need to clean up the resources after our test
150 await pool.destroy()
151 })
152
153 it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => {
154 const pool = new FixedThreadPool(
155 max,
156 './tests/worker-files/thread/testWorker.js',
157 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
158 )
159 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
160 const promises = new Set()
161 const maxMultiplier = 2
162 for (let i = 0; i < max * maxMultiplier; i++) {
163 promises.add(pool.execute())
164 }
165 await Promise.all(promises)
166 for (const workerNode of pool.workerNodes) {
167 expect(workerNode.workerUsage).toStrictEqual({
168 tasks: {
169 executed: maxMultiplier,
170 executing: 0,
171 queued: 0,
172 failed: 0
173 },
174 runTime: {
175 aggregation: 0,
176 average: 0,
177 median: 0,
178 history: expect.any(CircularArray)
179 },
180 waitTime: {
181 aggregation: 0,
182 average: 0,
183 median: 0,
184 history: expect.any(CircularArray)
185 },
186 elu: undefined
187 })
188 }
189 expect(
190 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
191 WorkerChoiceStrategies.ROUND_ROBIN
192 ).nextWorkerNodeId
193 ).toBe(0)
194 // We need to clean up the resources after our test
195 await pool.destroy()
196 })
197
198 it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
199 const pool = new DynamicThreadPool(
200 min,
201 max,
202 './tests/worker-files/thread/testWorker.js',
203 { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN }
204 )
205 // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose`
206 const promises = new Set()
207 const maxMultiplier = 2
208 for (let i = 0; i < max * maxMultiplier; i++) {
209 promises.add(pool.execute())
210 }
211 await Promise.all(promises)
212 for (const workerNode of pool.workerNodes) {
213 expect(workerNode.workerUsage).toStrictEqual({
214 tasks: {
215 executed: maxMultiplier,
216 executing: 0,
217 queued: 0,
218 failed: 0
219 },
220 runTime: {
221 aggregation: 0,
222 average: 0,
223 median: 0,
224 history: expect.any(CircularArray)
225 },
226 waitTime: {
227 aggregation: 0,
228 average: 0,
229 median: 0,
230 history: expect.any(CircularArray)
231 },
232 elu: undefined
233 })
234 }
235 expect(
236 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
237 WorkerChoiceStrategies.ROUND_ROBIN
238 ).nextWorkerNodeId
239 ).toBe(0)
240 // We need to clean up the resources after our test
241 await pool.destroy()
242 })
243
244 it('Verify ROUND_ROBIN strategy runtime behavior', async () => {
245 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
246 let pool = new FixedClusterPool(
247 max,
248 './tests/worker-files/cluster/testWorker.js',
249 { workerChoiceStrategy }
250 )
251 let results = new Set()
252 for (let i = 0; i < max; i++) {
253 results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.id)
254 }
255 expect(results.size).toBe(max)
256 await pool.destroy()
257 pool = new FixedThreadPool(
258 max,
259 './tests/worker-files/thread/testWorker.js',
260 { workerChoiceStrategy }
261 )
262 results = new Set()
263 for (let i = 0; i < max; i++) {
264 results.add(pool.workerNodes[pool.chooseWorkerNode()].worker.threadId)
265 }
266 expect(results.size).toBe(max)
267 await pool.destroy()
268 })
269
270 it('Verify ROUND_ROBIN strategy internals are resets after setting it', async () => {
271 const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
272 let pool = new FixedThreadPool(
273 max,
274 './tests/worker-files/thread/testWorker.js',
275 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
276 )
277 expect(
278 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
279 workerChoiceStrategy
280 ).nextWorkerNodeId
281 ).toBeDefined()
282 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
283 expect(
284 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
285 pool.workerChoiceStrategyContext.workerChoiceStrategy
286 ).nextWorkerNodeId
287 ).toBe(0)
288 await pool.destroy()
289 pool = new DynamicThreadPool(
290 min,
291 max,
292 './tests/worker-files/thread/testWorker.js',
293 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
294 )
295 expect(
296 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
297 workerChoiceStrategy
298 ).nextWorkerNodeId
299 ).toBeDefined()
300 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
301 expect(
302 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
303 pool.workerChoiceStrategyContext.workerChoiceStrategy
304 ).nextWorkerNodeId
305 ).toBe(0)
306 // We need to clean up the resources after our test
307 await pool.destroy()
308 })
309
310 it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
311 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
312 let pool = new FixedThreadPool(
313 max,
314 './tests/worker-files/thread/testWorker.js',
315 { workerChoiceStrategy }
316 )
317 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
318 runTime: false,
319 avgRunTime: false,
320 medRunTime: false,
321 waitTime: false,
322 avgWaitTime: false,
323 medWaitTime: false,
324 elu: false
325 })
326 await pool.destroy()
327 pool = new DynamicThreadPool(
328 min,
329 max,
330 './tests/worker-files/thread/testWorker.js',
331 { workerChoiceStrategy }
332 )
333 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
334 runTime: false,
335 avgRunTime: false,
336 medRunTime: false,
337 waitTime: false,
338 avgWaitTime: false,
339 medWaitTime: false,
340 elu: false
341 })
342 // We need to clean up the resources after our test
343 await pool.destroy()
344 })
345
346 it('Verify LEAST_USED strategy can be run in a fixed pool', async () => {
347 const pool = new FixedThreadPool(
348 max,
349 './tests/worker-files/thread/testWorker.js',
350 { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED }
351 )
352 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
353 const promises = new Set()
354 const maxMultiplier = 2
355 for (let i = 0; i < max * maxMultiplier; i++) {
356 promises.add(pool.execute())
357 }
358 await Promise.all(promises)
359 for (const workerNode of pool.workerNodes) {
360 expect(workerNode.workerUsage).toStrictEqual({
361 tasks: {
362 executed: maxMultiplier,
363 executing: 0,
364 queued: 0,
365 failed: 0
366 },
367 runTime: {
368 aggregation: 0,
369 average: 0,
370 median: 0,
371 history: expect.any(CircularArray)
372 },
373 waitTime: {
374 aggregation: 0,
375 average: 0,
376 median: 0,
377 history: expect.any(CircularArray)
378 },
379 elu: undefined
380 })
381 }
382 // We need to clean up the resources after our test
383 await pool.destroy()
384 })
385
386 it('Verify LEAST_USED strategy can be run in a dynamic pool', async () => {
387 const pool = new DynamicThreadPool(
388 min,
389 max,
390 './tests/worker-files/thread/testWorker.js',
391 { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED }
392 )
393 // TODO: Create a better test to cover `LeastUsedWorkerChoiceStrategy#choose`
394 const promises = new Set()
395 const maxMultiplier = 2
396 for (let i = 0; i < max * maxMultiplier; i++) {
397 promises.add(pool.execute())
398 }
399 await Promise.all(promises)
400 for (const workerNode of pool.workerNodes) {
401 expect(workerNode.workerUsage).toStrictEqual({
402 tasks: {
403 executed: maxMultiplier,
404 executing: 0,
405 queued: 0,
406 failed: 0
407 },
408 runTime: {
409 aggregation: 0,
410 average: 0,
411 median: 0,
412 history: expect.any(CircularArray)
413 },
414 waitTime: {
415 aggregation: 0,
416 average: 0,
417 median: 0,
418 history: expect.any(CircularArray)
419 },
420
421 elu: undefined
422 })
423 }
424 // We need to clean up the resources after our test
425 await pool.destroy()
426 })
427
428 it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
429 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
430 let pool = new FixedThreadPool(
431 max,
432 './tests/worker-files/thread/testWorker.js',
433 { workerChoiceStrategy }
434 )
435 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
436 runTime: true,
437 avgRunTime: false,
438 medRunTime: false,
439 waitTime: false,
440 avgWaitTime: false,
441 medWaitTime: false,
442 elu: false
443 })
444 await pool.destroy()
445 pool = new DynamicThreadPool(
446 min,
447 max,
448 './tests/worker-files/thread/testWorker.js',
449 { workerChoiceStrategy }
450 )
451 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
452 runTime: true,
453 avgRunTime: false,
454 medRunTime: false,
455 waitTime: false,
456 avgWaitTime: false,
457 medWaitTime: false,
458 elu: false
459 })
460 // We need to clean up the resources after our test
461 await pool.destroy()
462 })
463
464 it('Verify LEAST_BUSY strategy can be run in a fixed pool', async () => {
465 const pool = new FixedThreadPool(
466 max,
467 './tests/worker-files/thread/testWorker.js',
468 { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY }
469 )
470 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
471 const promises = new Set()
472 const maxMultiplier = 2
473 for (let i = 0; i < max * maxMultiplier; i++) {
474 promises.add(pool.execute())
475 }
476 await Promise.all(promises)
477 for (const workerNode of pool.workerNodes) {
478 expect(workerNode.workerUsage).toStrictEqual({
479 tasks: {
480 executed: expect.any(Number),
481 executing: 0,
482 queued: 0,
483 failed: 0
484 },
485 runTime: {
486 aggregation: expect.any(Number),
487 average: 0,
488 median: 0,
489 history: expect.any(CircularArray)
490 },
491 waitTime: {
492 aggregation: 0,
493 average: 0,
494 median: 0,
495 history: expect.any(CircularArray)
496 },
497 elu: undefined
498 })
499 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
500 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
501 max * maxMultiplier
502 )
503 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThanOrEqual(
504 0
505 )
506 }
507 // We need to clean up the resources after our test
508 await pool.destroy()
509 })
510
511 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
512 const pool = new DynamicThreadPool(
513 min,
514 max,
515 './tests/worker-files/thread/testWorker.js',
516 { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY }
517 )
518 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
519 const promises = new Set()
520 const maxMultiplier = 2
521 for (let i = 0; i < max * maxMultiplier; i++) {
522 promises.add(pool.execute())
523 }
524 await Promise.all(promises)
525 for (const workerNode of pool.workerNodes) {
526 expect(workerNode.workerUsage).toStrictEqual({
527 tasks: {
528 executed: expect.any(Number),
529 executing: 0,
530 queued: 0,
531 failed: 0
532 },
533 runTime: {
534 aggregation: expect.any(Number),
535 average: 0,
536 median: 0,
537 history: expect.any(CircularArray)
538 },
539 waitTime: {
540 aggregation: 0,
541 average: 0,
542 median: 0,
543 history: expect.any(CircularArray)
544 },
545 elu: undefined
546 })
547 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
548 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
549 max * maxMultiplier
550 )
551 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
552 }
553 // We need to clean up the resources after our test
554 await pool.destroy()
555 })
556
557 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
558 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
559 let pool = new FixedThreadPool(
560 max,
561 './tests/worker-files/thread/testWorker.js',
562 { workerChoiceStrategy }
563 )
564 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
565 runTime: true,
566 avgRunTime: true,
567 medRunTime: false,
568 waitTime: false,
569 avgWaitTime: false,
570 medWaitTime: false,
571 elu: false
572 })
573 await pool.destroy()
574 pool = new DynamicThreadPool(
575 min,
576 max,
577 './tests/worker-files/thread/testWorker.js',
578 { workerChoiceStrategy }
579 )
580 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
581 runTime: true,
582 avgRunTime: true,
583 medRunTime: false,
584 waitTime: false,
585 avgWaitTime: false,
586 medWaitTime: false,
587 elu: false
588 })
589 // We need to clean up the resources after our test
590 await pool.destroy()
591 })
592
593 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
594 const pool = new FixedThreadPool(
595 max,
596 './tests/worker-files/thread/testWorker.js',
597 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
598 )
599 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
600 const promises = new Set()
601 const maxMultiplier = 2
602 for (let i = 0; i < max * maxMultiplier; i++) {
603 promises.add(pool.execute())
604 }
605 await Promise.all(promises)
606 for (const workerNode of pool.workerNodes) {
607 expect(workerNode.workerUsage).toStrictEqual({
608 tasks: {
609 executed: maxMultiplier,
610 executing: 0,
611 queued: 0,
612 failed: 0
613 },
614 runTime: {
615 aggregation: expect.any(Number),
616 average: expect.any(Number),
617 median: 0,
618 history: expect.any(CircularArray)
619 },
620 waitTime: {
621 aggregation: 0,
622 average: 0,
623 median: 0,
624 history: expect.any(CircularArray)
625 },
626 elu: undefined
627 })
628 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
629 expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
630 }
631 expect(
632 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
633 pool.workerChoiceStrategyContext.workerChoiceStrategy
634 ).workersVirtualTaskEndTimestamp.length
635 ).toBe(pool.workerNodes.length)
636 // We need to clean up the resources after our test
637 await pool.destroy()
638 })
639
640 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
641 const pool = new DynamicThreadPool(
642 min,
643 max,
644 './tests/worker-files/thread/testWorker.js',
645 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
646 )
647 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
648 const promises = new Set()
649 const maxMultiplier = 2
650 for (let i = 0; i < max * maxMultiplier; i++) {
651 promises.add(pool.execute())
652 }
653 await Promise.all(promises)
654 for (const workerNode of pool.workerNodes) {
655 expect(workerNode.workerUsage).toStrictEqual({
656 tasks: {
657 executed: maxMultiplier,
658 executing: 0,
659 queued: 0,
660 failed: 0
661 },
662 runTime: {
663 aggregation: expect.any(Number),
664 average: expect.any(Number),
665 median: 0,
666 history: expect.any(CircularArray)
667 },
668 waitTime: {
669 aggregation: 0,
670 average: 0,
671 median: 0,
672 history: expect.any(CircularArray)
673 },
674 elu: undefined
675 })
676 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
677 expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
678 }
679 expect(
680 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
681 pool.workerChoiceStrategyContext.workerChoiceStrategy
682 ).workersVirtualTaskEndTimestamp.length
683 ).toBe(pool.workerNodes.length)
684 // We need to clean up the resources after our test
685 await pool.destroy()
686 })
687
688 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
689 const pool = new DynamicThreadPool(
690 min,
691 max,
692 './tests/worker-files/thread/testWorker.js',
693 {
694 workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE,
695 workerChoiceStrategyOptions: {
696 medRunTime: true
697 }
698 }
699 )
700 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
701 const promises = new Set()
702 const maxMultiplier = 2
703 for (let i = 0; i < max * maxMultiplier; i++) {
704 promises.add(pool.execute())
705 }
706 await Promise.all(promises)
707 for (const workerNode of pool.workerNodes) {
708 expect(workerNode.workerUsage).toStrictEqual({
709 tasks: {
710 executed: maxMultiplier,
711 executing: 0,
712 queued: 0,
713 failed: 0
714 },
715 runTime: {
716 aggregation: expect.any(Number),
717 average: 0,
718 median: expect.any(Number),
719 history: expect.any(CircularArray)
720 },
721 waitTime: {
722 aggregation: 0,
723 average: 0,
724 median: 0,
725 history: expect.any(CircularArray)
726 },
727 elu: undefined
728 })
729 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
730 expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
731 }
732 expect(
733 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
734 pool.workerChoiceStrategyContext.workerChoiceStrategy
735 ).workersVirtualTaskEndTimestamp.length
736 ).toBe(pool.workerNodes.length)
737 // We need to clean up the resources after our test
738 await pool.destroy()
739 })
740
741 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
742 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
743 let pool = new FixedThreadPool(
744 max,
745 './tests/worker-files/thread/testWorker.js'
746 )
747 expect(
748 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
749 workerChoiceStrategy
750 ).workersVirtualTaskEndTimestamp
751 ).toBeInstanceOf(Array)
752 expect(
753 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
754 workerChoiceStrategy
755 ).workersVirtualTaskEndTimestamp.length
756 ).toBe(0)
757 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
758 workerChoiceStrategy
759 ).workersVirtualTaskEndTimestamp[0] = performance.now()
760 expect(
761 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
762 workerChoiceStrategy
763 ).workersVirtualTaskEndTimestamp.length
764 ).toBe(1)
765 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
766 expect(
767 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
768 workerChoiceStrategy
769 ).workersVirtualTaskEndTimestamp
770 ).toBeInstanceOf(Array)
771 expect(
772 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
773 workerChoiceStrategy
774 ).workersVirtualTaskEndTimestamp.length
775 ).toBe(0)
776 await pool.destroy()
777 pool = new DynamicThreadPool(
778 min,
779 max,
780 './tests/worker-files/thread/testWorker.js'
781 )
782 expect(
783 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
784 workerChoiceStrategy
785 ).workersVirtualTaskEndTimestamp
786 ).toBeInstanceOf(Array)
787 expect(
788 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
789 workerChoiceStrategy
790 ).workersVirtualTaskEndTimestamp.length
791 ).toBe(0)
792 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
793 workerChoiceStrategy
794 ).workersVirtualTaskEndTimestamp[0] = performance.now()
795 expect(
796 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
797 workerChoiceStrategy
798 ).workersVirtualTaskEndTimestamp.length
799 ).toBe(1)
800 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
801 expect(
802 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
803 workerChoiceStrategy
804 ).workersVirtualTaskEndTimestamp
805 ).toBeInstanceOf(Array)
806 expect(
807 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
808 workerChoiceStrategy
809 ).workersVirtualTaskEndTimestamp.length
810 ).toBe(0)
811 // We need to clean up the resources after our test
812 await pool.destroy()
813 })
814
815 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
816 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
817 let pool = new FixedThreadPool(
818 max,
819 './tests/worker-files/thread/testWorker.js',
820 { workerChoiceStrategy }
821 )
822 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
823 runTime: true,
824 avgRunTime: true,
825 medRunTime: false,
826 waitTime: false,
827 avgWaitTime: false,
828 medWaitTime: false,
829 elu: false
830 })
831 await pool.destroy()
832 pool = new DynamicThreadPool(
833 min,
834 max,
835 './tests/worker-files/thread/testWorker.js',
836 { workerChoiceStrategy }
837 )
838 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
839 runTime: true,
840 avgRunTime: true,
841 medRunTime: false,
842 waitTime: false,
843 avgWaitTime: false,
844 medWaitTime: false,
845 elu: false
846 })
847 // We need to clean up the resources after our test
848 await pool.destroy()
849 })
850
851 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
852 const pool = new FixedThreadPool(
853 max,
854 './tests/worker-files/thread/testWorker.js',
855 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
856 )
857 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
858 const promises = new Set()
859 const maxMultiplier = 2
860 for (let i = 0; i < max * maxMultiplier; i++) {
861 promises.add(pool.execute())
862 }
863 await Promise.all(promises)
864 for (const workerNode of pool.workerNodes) {
865 expect(workerNode.workerUsage).toStrictEqual({
866 tasks: {
867 executed: expect.any(Number),
868 executing: 0,
869 queued: 0,
870 failed: 0
871 },
872 runTime: {
873 aggregation: expect.any(Number),
874 average: expect.any(Number),
875 median: 0,
876 history: expect.any(CircularArray)
877 },
878 waitTime: {
879 aggregation: 0,
880 average: 0,
881 median: 0,
882 history: expect.any(CircularArray)
883 },
884 elu: undefined
885 })
886 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
887 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
888 max * maxMultiplier
889 )
890 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThanOrEqual(
891 0
892 )
893 expect(workerNode.workerUsage.runTime.average).toBeGreaterThanOrEqual(0)
894 }
895 expect(
896 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
897 pool.workerChoiceStrategyContext.workerChoiceStrategy
898 ).defaultWorkerWeight
899 ).toBeGreaterThan(0)
900 expect(
901 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
902 pool.workerChoiceStrategyContext.workerChoiceStrategy
903 ).workerVirtualTaskRunTime
904 ).toBeGreaterThanOrEqual(0)
905 // We need to clean up the resources after our test
906 await pool.destroy()
907 })
908
909 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
910 const pool = new DynamicThreadPool(
911 min,
912 max,
913 './tests/worker-files/thread/testWorker.js',
914 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
915 )
916 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
917 const promises = new Set()
918 const maxMultiplier = 2
919 for (let i = 0; i < max * maxMultiplier; i++) {
920 promises.add(pool.execute())
921 }
922 await Promise.all(promises)
923 for (const workerNode of pool.workerNodes) {
924 expect(workerNode.workerUsage).toStrictEqual({
925 tasks: {
926 executed: expect.any(Number),
927 executing: 0,
928 queued: 0,
929 failed: 0
930 },
931 runTime: {
932 aggregation: expect.any(Number),
933 average: expect.any(Number),
934 median: 0,
935 history: expect.any(CircularArray)
936 },
937 waitTime: {
938 aggregation: 0,
939 average: 0,
940 median: 0,
941 history: expect.any(CircularArray)
942 },
943 elu: undefined
944 })
945 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
946 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
947 max * maxMultiplier
948 )
949 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
950 expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
951 }
952 expect(
953 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
954 pool.workerChoiceStrategyContext.workerChoiceStrategy
955 ).defaultWorkerWeight
956 ).toBeGreaterThan(0)
957 expect(
958 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
959 pool.workerChoiceStrategyContext.workerChoiceStrategy
960 ).workerVirtualTaskRunTime
961 ).toBeGreaterThanOrEqual(0)
962 // We need to clean up the resources after our test
963 await pool.destroy()
964 })
965
966 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
967 const pool = new DynamicThreadPool(
968 min,
969 max,
970 './tests/worker-files/thread/testWorker.js',
971 {
972 workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
973 workerChoiceStrategyOptions: {
974 medRunTime: true
975 }
976 }
977 )
978 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
979 const promises = new Set()
980 const maxMultiplier = 2
981 for (let i = 0; i < max * maxMultiplier; i++) {
982 promises.add(pool.execute())
983 }
984 await Promise.all(promises)
985 for (const workerNode of pool.workerNodes) {
986 expect(workerNode.workerUsage).toStrictEqual({
987 tasks: {
988 executed: expect.any(Number),
989 executing: 0,
990 queued: 0,
991 failed: 0
992 },
993 runTime: {
994 aggregation: expect.any(Number),
995 average: 0,
996 median: expect.any(Number),
997 history: expect.any(CircularArray)
998 },
999 waitTime: {
1000 aggregation: 0,
1001 average: 0,
1002 median: 0,
1003 history: expect.any(CircularArray)
1004 },
1005 elu: undefined
1006 })
1007 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
1008 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
1009 max * maxMultiplier
1010 )
1011 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
1012 expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
1013 }
1014 expect(
1015 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1016 pool.workerChoiceStrategyContext.workerChoiceStrategy
1017 ).defaultWorkerWeight
1018 ).toBeGreaterThan(0)
1019 expect(
1020 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1021 pool.workerChoiceStrategyContext.workerChoiceStrategy
1022 ).workerVirtualTaskRunTime
1023 ).toBeGreaterThanOrEqual(0)
1024 // We need to clean up the resources after our test
1025 await pool.destroy()
1026 })
1027
1028 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1029 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
1030 let pool = new FixedThreadPool(
1031 max,
1032 './tests/worker-files/thread/testWorker.js'
1033 )
1034 expect(
1035 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1036 workerChoiceStrategy
1037 ).currentWorkerNodeId
1038 ).toBeDefined()
1039 expect(
1040 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1041 workerChoiceStrategy
1042 ).defaultWorkerWeight
1043 ).toBeDefined()
1044 expect(
1045 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1046 workerChoiceStrategy
1047 ).workerVirtualTaskRunTime
1048 ).toBeDefined()
1049 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1050 expect(
1051 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1052 pool.workerChoiceStrategyContext.workerChoiceStrategy
1053 ).currentWorkerNodeId
1054 ).toBe(0)
1055 expect(
1056 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1057 pool.workerChoiceStrategyContext.workerChoiceStrategy
1058 ).defaultWorkerWeight
1059 ).toBeGreaterThan(0)
1060 expect(
1061 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1062 workerChoiceStrategy
1063 ).workerVirtualTaskRunTime
1064 ).toBe(0)
1065 await pool.destroy()
1066 pool = new DynamicThreadPool(
1067 min,
1068 max,
1069 './tests/worker-files/thread/testWorker.js'
1070 )
1071 expect(
1072 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1073 workerChoiceStrategy
1074 ).currentWorkerNodeId
1075 ).toBeDefined()
1076 expect(
1077 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1078 workerChoiceStrategy
1079 ).defaultWorkerWeight
1080 ).toBeDefined()
1081 expect(
1082 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1083 workerChoiceStrategy
1084 ).workerVirtualTaskRunTime
1085 ).toBeDefined()
1086 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1087 expect(
1088 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1089 pool.workerChoiceStrategyContext.workerChoiceStrategy
1090 ).currentWorkerNodeId
1091 ).toBe(0)
1092 expect(
1093 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1094 pool.workerChoiceStrategyContext.workerChoiceStrategy
1095 ).defaultWorkerWeight
1096 ).toBeGreaterThan(0)
1097 expect(
1098 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1099 workerChoiceStrategy
1100 ).workerVirtualTaskRunTime
1101 ).toBe(0)
1102 // We need to clean up the resources after our test
1103 await pool.destroy()
1104 })
1105
1106 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1107 const workerChoiceStrategy =
1108 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1109 let pool = new FixedThreadPool(
1110 max,
1111 './tests/worker-files/thread/testWorker.js',
1112 { workerChoiceStrategy }
1113 )
1114 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
1115 runTime: false,
1116 avgRunTime: false,
1117 medRunTime: false,
1118 waitTime: false,
1119 avgWaitTime: false,
1120 medWaitTime: false,
1121 elu: false
1122 })
1123 await pool.destroy()
1124 pool = new DynamicThreadPool(
1125 min,
1126 max,
1127 './tests/worker-files/thread/testWorker.js',
1128 { workerChoiceStrategy }
1129 )
1130 expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
1131 runTime: false,
1132 avgRunTime: false,
1133 medRunTime: false,
1134 waitTime: false,
1135 avgWaitTime: false,
1136 medWaitTime: false,
1137 elu: false
1138 })
1139 // We need to clean up the resources after our test
1140 await pool.destroy()
1141 })
1142
1143 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1144 const pool = new FixedThreadPool(
1145 max,
1146 './tests/worker-files/thread/testWorker.js',
1147 {
1148 workerChoiceStrategy:
1149 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1150 }
1151 )
1152 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1153 const promises = new Set()
1154 const maxMultiplier = 2
1155 for (let i = 0; i < max * maxMultiplier; i++) {
1156 promises.add(pool.execute())
1157 }
1158 await Promise.all(promises)
1159 for (const workerNode of pool.workerNodes) {
1160 expect(workerNode.workerUsage).toStrictEqual({
1161 tasks: {
1162 executed: maxMultiplier,
1163 executing: 0,
1164 queued: 0,
1165 failed: 0
1166 },
1167 runTime: {
1168 aggregation: 0,
1169 average: 0,
1170 median: 0,
1171 history: expect.any(CircularArray)
1172 },
1173 waitTime: {
1174 aggregation: 0,
1175 average: 0,
1176 median: 0,
1177 history: expect.any(CircularArray)
1178 },
1179 elu: undefined
1180 })
1181 }
1182 expect(
1183 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1184 pool.workerChoiceStrategyContext.workerChoiceStrategy
1185 ).defaultWorkerWeight
1186 ).toBeGreaterThan(0)
1187 expect(
1188 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1189 pool.workerChoiceStrategyContext.workerChoiceStrategy
1190 ).currentRoundId
1191 ).toBe(0)
1192 expect(
1193 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1194 pool.workerChoiceStrategyContext.workerChoiceStrategy
1195 ).currentWorkerNodeId
1196 ).toBe(0)
1197 expect(
1198 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1199 pool.workerChoiceStrategyContext.workerChoiceStrategy
1200 ).roundWeights
1201 ).toStrictEqual([
1202 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1203 pool.workerChoiceStrategyContext.workerChoiceStrategy
1204 ).defaultWorkerWeight
1205 ])
1206 // We need to clean up the resources after our test
1207 await pool.destroy()
1208 })
1209
1210 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1211 const pool = new DynamicThreadPool(
1212 min,
1213 max,
1214 './tests/worker-files/thread/testWorker.js',
1215 {
1216 workerChoiceStrategy:
1217 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1218 }
1219 )
1220 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1221 const promises = new Set()
1222 const maxMultiplier = 2
1223 for (let i = 0; i < max * maxMultiplier; i++) {
1224 promises.add(pool.execute())
1225 }
1226 await Promise.all(promises)
1227 for (const workerNode of pool.workerNodes) {
1228 expect(workerNode.workerUsage).toStrictEqual({
1229 tasks: {
1230 executed: maxMultiplier,
1231 executing: 0,
1232 queued: 0,
1233 failed: 0
1234 },
1235 runTime: {
1236 aggregation: 0,
1237 average: 0,
1238 median: 0,
1239 history: expect.any(CircularArray)
1240 },
1241 waitTime: {
1242 aggregation: 0,
1243 average: 0,
1244 median: 0,
1245 history: expect.any(CircularArray)
1246 },
1247 elu: undefined
1248 })
1249 }
1250 expect(
1251 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1252 pool.workerChoiceStrategyContext.workerChoiceStrategy
1253 ).defaultWorkerWeight
1254 ).toBeGreaterThan(0)
1255 expect(
1256 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1257 pool.workerChoiceStrategyContext.workerChoiceStrategy
1258 ).currentRoundId
1259 ).toBe(0)
1260 expect(
1261 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1262 pool.workerChoiceStrategyContext.workerChoiceStrategy
1263 ).currentWorkerNodeId
1264 ).toBe(0)
1265 expect(
1266 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1267 pool.workerChoiceStrategyContext.workerChoiceStrategy
1268 ).roundWeights
1269 ).toStrictEqual([
1270 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1271 pool.workerChoiceStrategyContext.workerChoiceStrategy
1272 ).defaultWorkerWeight
1273 ])
1274 // We need to clean up the resources after our test
1275 await pool.destroy()
1276 })
1277
1278 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1279 const workerChoiceStrategy =
1280 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1281 let pool = new FixedThreadPool(
1282 max,
1283 './tests/worker-files/thread/testWorker.js'
1284 )
1285 expect(
1286 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1287 workerChoiceStrategy
1288 ).currentRoundId
1289 ).toBeDefined()
1290 expect(
1291 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1292 workerChoiceStrategy
1293 ).currentWorkerNodeId
1294 ).toBeDefined()
1295 expect(
1296 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1297 workerChoiceStrategy
1298 ).defaultWorkerWeight
1299 ).toBeDefined()
1300 expect(
1301 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1302 workerChoiceStrategy
1303 ).roundWeights
1304 ).toBeDefined()
1305 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1306 expect(
1307 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1308 workerChoiceStrategy
1309 ).currentRoundId
1310 ).toBe(0)
1311 expect(
1312 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1313 pool.workerChoiceStrategyContext.workerChoiceStrategy
1314 ).currentWorkerNodeId
1315 ).toBe(0)
1316 expect(
1317 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1318 pool.workerChoiceStrategyContext.workerChoiceStrategy
1319 ).defaultWorkerWeight
1320 ).toBeGreaterThan(0)
1321 expect(
1322 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1323 workerChoiceStrategy
1324 ).roundWeights
1325 ).toStrictEqual([
1326 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1327 pool.workerChoiceStrategyContext.workerChoiceStrategy
1328 ).defaultWorkerWeight
1329 ])
1330 await pool.destroy()
1331 pool = new DynamicThreadPool(
1332 min,
1333 max,
1334 './tests/worker-files/thread/testWorker.js'
1335 )
1336 expect(
1337 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1338 workerChoiceStrategy
1339 ).currentRoundId
1340 ).toBeDefined()
1341 expect(
1342 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1343 workerChoiceStrategy
1344 ).currentWorkerNodeId
1345 ).toBeDefined()
1346 expect(
1347 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1348 workerChoiceStrategy
1349 ).defaultWorkerWeight
1350 ).toBeDefined()
1351 expect(
1352 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1353 workerChoiceStrategy
1354 ).roundWeights
1355 ).toBeDefined()
1356 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1357 expect(
1358 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1359 pool.workerChoiceStrategyContext.workerChoiceStrategy
1360 ).currentWorkerNodeId
1361 ).toBe(0)
1362 expect(
1363 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1364 pool.workerChoiceStrategyContext.workerChoiceStrategy
1365 ).defaultWorkerWeight
1366 ).toBeGreaterThan(0)
1367 expect(
1368 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1369 workerChoiceStrategy
1370 ).roundWeights
1371 ).toStrictEqual([
1372 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1373 pool.workerChoiceStrategyContext.workerChoiceStrategy
1374 ).defaultWorkerWeight
1375 ])
1376 // We need to clean up the resources after our test
1377 await pool.destroy()
1378 })
1379
1380 it('Verify unknown strategy throw error', () => {
1381 expect(
1382 () =>
1383 new DynamicThreadPool(
1384 min,
1385 max,
1386 './tests/worker-files/thread/testWorker.js',
1387 { workerChoiceStrategy: 'UNKNOWN_STRATEGY' }
1388 )
1389 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")
1390 })
1391 })