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