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: false,
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: false,
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: 0,
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 }
520 // We need to clean up the resources after our test
521 await pool.destroy()
522 })
523
524 it('Verify LEAST_BUSY strategy can be run in a dynamic pool', async () => {
525 const pool = new DynamicThreadPool(
526 min,
527 max,
528 './tests/worker-files/thread/testWorker.js',
529 { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY }
530 )
531 // TODO: Create a better test to cover `LeastBusyWorkerChoiceStrategy#choose`
532 const promises = new Set()
533 const maxMultiplier = 2
534 for (let i = 0; i < max * maxMultiplier; i++) {
535 promises.add(pool.execute())
536 }
537 await Promise.all(promises)
538 for (const workerNode of pool.workerNodes) {
539 expect(workerNode.workerUsage).toStrictEqual({
540 tasks: {
541 executed: expect.any(Number),
542 executing: 0,
543 queued: 0,
544 failed: 0
545 },
546 runTime: {
547 aggregation: expect.any(Number),
548 average: 0,
549 median: 0,
550 history: expect.any(CircularArray)
551 },
552 waitTime: {
553 aggregation: 0,
554 average: 0,
555 median: 0,
556 history: expect.any(CircularArray)
557 },
558 elu: undefined
559 })
560 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
561 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
562 max * maxMultiplier
563 )
564 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
565 }
566 // We need to clean up the resources after our test
567 await pool.destroy()
568 })
569
570 it('Verify LEAST_ELU strategy default tasks usage statistics requirements', async () => {
571 const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
572 let pool = new FixedThreadPool(
573 max,
574 './tests/worker-files/thread/testWorker.js',
575 { workerChoiceStrategy }
576 )
577 expect(
578 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
579 ).toStrictEqual({
580 runTime: false,
581 avgRunTime: false,
582 medRunTime: false,
583 waitTime: false,
584 avgWaitTime: false,
585 medWaitTime: false,
586 elu: true
587 })
588 await pool.destroy()
589 pool = new DynamicThreadPool(
590 min,
591 max,
592 './tests/worker-files/thread/testWorker.js',
593 { workerChoiceStrategy }
594 )
595 expect(
596 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
597 ).toStrictEqual({
598 runTime: false,
599 avgRunTime: false,
600 medRunTime: false,
601 waitTime: false,
602 avgWaitTime: false,
603 medWaitTime: false,
604 elu: true
605 })
606 // We need to clean up the resources after our test
607 await pool.destroy()
608 })
609
610 it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
611 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
612 let pool = new FixedThreadPool(
613 max,
614 './tests/worker-files/thread/testWorker.js',
615 { workerChoiceStrategy }
616 )
617 expect(
618 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
619 ).toStrictEqual({
620 runTime: true,
621 avgRunTime: true,
622 medRunTime: false,
623 waitTime: false,
624 avgWaitTime: false,
625 medWaitTime: false,
626 elu: false
627 })
628 await pool.destroy()
629 pool = new DynamicThreadPool(
630 min,
631 max,
632 './tests/worker-files/thread/testWorker.js',
633 { workerChoiceStrategy }
634 )
635 expect(
636 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
637 ).toStrictEqual({
638 runTime: true,
639 avgRunTime: true,
640 medRunTime: false,
641 waitTime: false,
642 avgWaitTime: false,
643 medWaitTime: false,
644 elu: false
645 })
646 // We need to clean up the resources after our test
647 await pool.destroy()
648 })
649
650 it('Verify FAIR_SHARE strategy can be run in a fixed pool', async () => {
651 const pool = new FixedThreadPool(
652 max,
653 './tests/worker-files/thread/testWorker.js',
654 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
655 )
656 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
657 const promises = new Set()
658 const maxMultiplier = 2
659 for (let i = 0; i < max * maxMultiplier; i++) {
660 promises.add(pool.execute())
661 }
662 await Promise.all(promises)
663 for (const workerNode of pool.workerNodes) {
664 expect(workerNode.workerUsage).toStrictEqual({
665 tasks: {
666 executed: maxMultiplier,
667 executing: 0,
668 queued: 0,
669 failed: 0
670 },
671 runTime: {
672 aggregation: expect.any(Number),
673 average: expect.any(Number),
674 median: 0,
675 history: expect.any(CircularArray)
676 },
677 waitTime: {
678 aggregation: 0,
679 average: 0,
680 median: 0,
681 history: expect.any(CircularArray)
682 },
683 elu: undefined
684 })
685 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
686 expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
687 }
688 expect(
689 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
690 pool.workerChoiceStrategyContext.workerChoiceStrategy
691 ).workersVirtualTaskEndTimestamp.length
692 ).toBe(pool.workerNodes.length)
693 // We need to clean up the resources after our test
694 await pool.destroy()
695 })
696
697 it('Verify FAIR_SHARE strategy can be run in a dynamic pool', async () => {
698 const pool = new DynamicThreadPool(
699 min,
700 max,
701 './tests/worker-files/thread/testWorker.js',
702 { workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE }
703 )
704 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
705 const promises = new Set()
706 const maxMultiplier = 2
707 for (let i = 0; i < max * maxMultiplier; i++) {
708 promises.add(pool.execute())
709 }
710 await Promise.all(promises)
711 for (const workerNode of pool.workerNodes) {
712 expect(workerNode.workerUsage).toStrictEqual({
713 tasks: {
714 executed: maxMultiplier,
715 executing: 0,
716 queued: 0,
717 failed: 0
718 },
719 runTime: {
720 aggregation: expect.any(Number),
721 average: expect.any(Number),
722 median: 0,
723 history: expect.any(CircularArray)
724 },
725 waitTime: {
726 aggregation: 0,
727 average: 0,
728 median: 0,
729 history: expect.any(CircularArray)
730 },
731 elu: undefined
732 })
733 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
734 expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
735 }
736 expect(
737 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
738 pool.workerChoiceStrategyContext.workerChoiceStrategy
739 ).workersVirtualTaskEndTimestamp.length
740 ).toBe(pool.workerNodes.length)
741 // We need to clean up the resources after our test
742 await pool.destroy()
743 })
744
745 it('Verify FAIR_SHARE strategy can be run in a dynamic pool with median runtime statistic', async () => {
746 const pool = new DynamicThreadPool(
747 min,
748 max,
749 './tests/worker-files/thread/testWorker.js',
750 {
751 workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE,
752 workerChoiceStrategyOptions: {
753 medRunTime: true
754 }
755 }
756 )
757 // TODO: Create a better test to cover `FairShareChoiceStrategy#choose`
758 const promises = new Set()
759 const maxMultiplier = 2
760 for (let i = 0; i < max * maxMultiplier; i++) {
761 promises.add(pool.execute())
762 }
763 await Promise.all(promises)
764 for (const workerNode of pool.workerNodes) {
765 expect(workerNode.workerUsage).toStrictEqual({
766 tasks: {
767 executed: maxMultiplier,
768 executing: 0,
769 queued: 0,
770 failed: 0
771 },
772 runTime: {
773 aggregation: expect.any(Number),
774 average: 0,
775 median: expect.any(Number),
776 history: expect.any(CircularArray)
777 },
778 waitTime: {
779 aggregation: 0,
780 average: 0,
781 median: 0,
782 history: expect.any(CircularArray)
783 },
784 elu: undefined
785 })
786 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
787 expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
788 }
789 expect(
790 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
791 pool.workerChoiceStrategyContext.workerChoiceStrategy
792 ).workersVirtualTaskEndTimestamp.length
793 ).toBe(pool.workerNodes.length)
794 // We need to clean up the resources after our test
795 await pool.destroy()
796 })
797
798 it('Verify FAIR_SHARE strategy internals are resets after setting it', async () => {
799 const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
800 let pool = new FixedThreadPool(
801 max,
802 './tests/worker-files/thread/testWorker.js'
803 )
804 expect(
805 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
806 workerChoiceStrategy
807 ).workersVirtualTaskEndTimestamp
808 ).toBeInstanceOf(Array)
809 expect(
810 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
811 workerChoiceStrategy
812 ).workersVirtualTaskEndTimestamp.length
813 ).toBe(0)
814 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
815 workerChoiceStrategy
816 ).workersVirtualTaskEndTimestamp[0] = performance.now()
817 expect(
818 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
819 workerChoiceStrategy
820 ).workersVirtualTaskEndTimestamp.length
821 ).toBe(1)
822 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
823 expect(
824 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
825 workerChoiceStrategy
826 ).workersVirtualTaskEndTimestamp
827 ).toBeInstanceOf(Array)
828 expect(
829 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
830 workerChoiceStrategy
831 ).workersVirtualTaskEndTimestamp.length
832 ).toBe(0)
833 await pool.destroy()
834 pool = new DynamicThreadPool(
835 min,
836 max,
837 './tests/worker-files/thread/testWorker.js'
838 )
839 expect(
840 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
841 workerChoiceStrategy
842 ).workersVirtualTaskEndTimestamp
843 ).toBeInstanceOf(Array)
844 expect(
845 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
846 workerChoiceStrategy
847 ).workersVirtualTaskEndTimestamp.length
848 ).toBe(0)
849 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
850 workerChoiceStrategy
851 ).workersVirtualTaskEndTimestamp[0] = performance.now()
852 expect(
853 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
854 workerChoiceStrategy
855 ).workersVirtualTaskEndTimestamp.length
856 ).toBe(1)
857 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
858 expect(
859 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
860 workerChoiceStrategy
861 ).workersVirtualTaskEndTimestamp
862 ).toBeInstanceOf(Array)
863 expect(
864 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
865 workerChoiceStrategy
866 ).workersVirtualTaskEndTimestamp.length
867 ).toBe(0)
868 // We need to clean up the resources after our test
869 await pool.destroy()
870 })
871
872 it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
873 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
874 let pool = new FixedThreadPool(
875 max,
876 './tests/worker-files/thread/testWorker.js',
877 { workerChoiceStrategy }
878 )
879 expect(
880 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
881 ).toStrictEqual({
882 runTime: true,
883 avgRunTime: true,
884 medRunTime: false,
885 waitTime: false,
886 avgWaitTime: false,
887 medWaitTime: false,
888 elu: false
889 })
890 await pool.destroy()
891 pool = new DynamicThreadPool(
892 min,
893 max,
894 './tests/worker-files/thread/testWorker.js',
895 { workerChoiceStrategy }
896 )
897 expect(
898 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
899 ).toStrictEqual({
900 runTime: true,
901 avgRunTime: true,
902 medRunTime: false,
903 waitTime: false,
904 avgWaitTime: false,
905 medWaitTime: false,
906 elu: false
907 })
908 // We need to clean up the resources after our test
909 await pool.destroy()
910 })
911
912 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
913 const pool = new FixedThreadPool(
914 max,
915 './tests/worker-files/thread/testWorker.js',
916 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
917 )
918 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
919 const promises = new Set()
920 const maxMultiplier = 2
921 for (let i = 0; i < max * maxMultiplier; i++) {
922 promises.add(pool.execute())
923 }
924 await Promise.all(promises)
925 for (const workerNode of pool.workerNodes) {
926 expect(workerNode.workerUsage).toStrictEqual({
927 tasks: {
928 executed: expect.any(Number),
929 executing: 0,
930 queued: 0,
931 failed: 0
932 },
933 runTime: {
934 aggregation: expect.any(Number),
935 average: expect.any(Number),
936 median: 0,
937 history: expect.any(CircularArray)
938 },
939 waitTime: {
940 aggregation: 0,
941 average: 0,
942 median: 0,
943 history: expect.any(CircularArray)
944 },
945 elu: undefined
946 })
947 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
948 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
949 max * maxMultiplier
950 )
951 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThanOrEqual(
952 0
953 )
954 expect(workerNode.workerUsage.runTime.average).toBeGreaterThanOrEqual(0)
955 }
956 expect(
957 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
958 pool.workerChoiceStrategyContext.workerChoiceStrategy
959 ).defaultWorkerWeight
960 ).toBeGreaterThan(0)
961 expect(
962 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
963 pool.workerChoiceStrategyContext.workerChoiceStrategy
964 ).workerVirtualTaskRunTime
965 ).toBeGreaterThanOrEqual(0)
966 // We need to clean up the resources after our test
967 await pool.destroy()
968 })
969
970 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
971 const pool = new DynamicThreadPool(
972 min,
973 max,
974 './tests/worker-files/thread/testWorker.js',
975 { workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN }
976 )
977 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
978 const promises = new Set()
979 const maxMultiplier = 2
980 for (let i = 0; i < max * maxMultiplier; i++) {
981 promises.add(pool.execute())
982 }
983 await Promise.all(promises)
984 for (const workerNode of pool.workerNodes) {
985 expect(workerNode.workerUsage).toStrictEqual({
986 tasks: {
987 executed: expect.any(Number),
988 executing: 0,
989 queued: 0,
990 failed: 0
991 },
992 runTime: {
993 aggregation: expect.any(Number),
994 average: expect.any(Number),
995 median: 0,
996 history: expect.any(CircularArray)
997 },
998 waitTime: {
999 aggregation: 0,
1000 average: 0,
1001 median: 0,
1002 history: expect.any(CircularArray)
1003 },
1004 elu: undefined
1005 })
1006 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
1007 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
1008 max * maxMultiplier
1009 )
1010 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
1011 expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
1012 }
1013 expect(
1014 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1015 pool.workerChoiceStrategyContext.workerChoiceStrategy
1016 ).defaultWorkerWeight
1017 ).toBeGreaterThan(0)
1018 expect(
1019 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1020 pool.workerChoiceStrategyContext.workerChoiceStrategy
1021 ).workerVirtualTaskRunTime
1022 ).toBeGreaterThanOrEqual(0)
1023 // We need to clean up the resources after our test
1024 await pool.destroy()
1025 })
1026
1027 it('Verify WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool with median runtime statistic', async () => {
1028 const pool = new DynamicThreadPool(
1029 min,
1030 max,
1031 './tests/worker-files/thread/testWorker.js',
1032 {
1033 workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
1034 workerChoiceStrategyOptions: {
1035 medRunTime: true
1036 }
1037 }
1038 )
1039 // TODO: Create a better test to cover `WeightedRoundRobinWorkerChoiceStrategy#choose`
1040 const promises = new Set()
1041 const maxMultiplier = 2
1042 for (let i = 0; i < max * maxMultiplier; i++) {
1043 promises.add(pool.execute())
1044 }
1045 await Promise.all(promises)
1046 for (const workerNode of pool.workerNodes) {
1047 expect(workerNode.workerUsage).toStrictEqual({
1048 tasks: {
1049 executed: expect.any(Number),
1050 executing: 0,
1051 queued: 0,
1052 failed: 0
1053 },
1054 runTime: {
1055 aggregation: expect.any(Number),
1056 average: 0,
1057 median: expect.any(Number),
1058 history: expect.any(CircularArray)
1059 },
1060 waitTime: {
1061 aggregation: 0,
1062 average: 0,
1063 median: 0,
1064 history: expect.any(CircularArray)
1065 },
1066 elu: undefined
1067 })
1068 expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
1069 expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
1070 max * maxMultiplier
1071 )
1072 expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
1073 expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
1074 }
1075 expect(
1076 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1077 pool.workerChoiceStrategyContext.workerChoiceStrategy
1078 ).defaultWorkerWeight
1079 ).toBeGreaterThan(0)
1080 expect(
1081 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1082 pool.workerChoiceStrategyContext.workerChoiceStrategy
1083 ).workerVirtualTaskRunTime
1084 ).toBeGreaterThanOrEqual(0)
1085 // We need to clean up the resources after our test
1086 await pool.destroy()
1087 })
1088
1089 it('Verify WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1090 const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
1091 let pool = new FixedThreadPool(
1092 max,
1093 './tests/worker-files/thread/testWorker.js'
1094 )
1095 expect(
1096 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1097 workerChoiceStrategy
1098 ).currentWorkerNodeId
1099 ).toBeDefined()
1100 expect(
1101 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1102 workerChoiceStrategy
1103 ).defaultWorkerWeight
1104 ).toBeDefined()
1105 expect(
1106 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1107 workerChoiceStrategy
1108 ).workerVirtualTaskRunTime
1109 ).toBeDefined()
1110 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1111 expect(
1112 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1113 pool.workerChoiceStrategyContext.workerChoiceStrategy
1114 ).currentWorkerNodeId
1115 ).toBe(0)
1116 expect(
1117 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1118 pool.workerChoiceStrategyContext.workerChoiceStrategy
1119 ).defaultWorkerWeight
1120 ).toBeGreaterThan(0)
1121 expect(
1122 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1123 workerChoiceStrategy
1124 ).workerVirtualTaskRunTime
1125 ).toBe(0)
1126 await pool.destroy()
1127 pool = new DynamicThreadPool(
1128 min,
1129 max,
1130 './tests/worker-files/thread/testWorker.js'
1131 )
1132 expect(
1133 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1134 workerChoiceStrategy
1135 ).currentWorkerNodeId
1136 ).toBeDefined()
1137 expect(
1138 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1139 workerChoiceStrategy
1140 ).defaultWorkerWeight
1141 ).toBeDefined()
1142 expect(
1143 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1144 workerChoiceStrategy
1145 ).workerVirtualTaskRunTime
1146 ).toBeDefined()
1147 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1148 expect(
1149 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1150 pool.workerChoiceStrategyContext.workerChoiceStrategy
1151 ).currentWorkerNodeId
1152 ).toBe(0)
1153 expect(
1154 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1155 pool.workerChoiceStrategyContext.workerChoiceStrategy
1156 ).defaultWorkerWeight
1157 ).toBeGreaterThan(0)
1158 expect(
1159 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1160 workerChoiceStrategy
1161 ).workerVirtualTaskRunTime
1162 ).toBe(0)
1163 // We need to clean up the resources after our test
1164 await pool.destroy()
1165 })
1166
1167 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
1168 const workerChoiceStrategy =
1169 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1170 let pool = new FixedThreadPool(
1171 max,
1172 './tests/worker-files/thread/testWorker.js',
1173 { workerChoiceStrategy }
1174 )
1175 expect(
1176 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
1177 ).toStrictEqual({
1178 runTime: false,
1179 avgRunTime: false,
1180 medRunTime: false,
1181 waitTime: false,
1182 avgWaitTime: false,
1183 medWaitTime: false,
1184 elu: false
1185 })
1186 await pool.destroy()
1187 pool = new DynamicThreadPool(
1188 min,
1189 max,
1190 './tests/worker-files/thread/testWorker.js',
1191 { workerChoiceStrategy }
1192 )
1193 expect(
1194 pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
1195 ).toStrictEqual({
1196 runTime: false,
1197 avgRunTime: false,
1198 medRunTime: false,
1199 waitTime: false,
1200 avgWaitTime: false,
1201 medWaitTime: false,
1202 elu: false
1203 })
1204 // We need to clean up the resources after our test
1205 await pool.destroy()
1206 })
1207
1208 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
1209 const pool = new FixedThreadPool(
1210 max,
1211 './tests/worker-files/thread/testWorker.js',
1212 {
1213 workerChoiceStrategy:
1214 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1215 }
1216 )
1217 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1218 const promises = new Set()
1219 const maxMultiplier = 2
1220 for (let i = 0; i < max * maxMultiplier; i++) {
1221 promises.add(pool.execute())
1222 }
1223 await Promise.all(promises)
1224 for (const workerNode of pool.workerNodes) {
1225 expect(workerNode.workerUsage).toStrictEqual({
1226 tasks: {
1227 executed: maxMultiplier,
1228 executing: 0,
1229 queued: 0,
1230 failed: 0
1231 },
1232 runTime: {
1233 aggregation: 0,
1234 average: 0,
1235 median: 0,
1236 history: expect.any(CircularArray)
1237 },
1238 waitTime: {
1239 aggregation: 0,
1240 average: 0,
1241 median: 0,
1242 history: expect.any(CircularArray)
1243 },
1244 elu: undefined
1245 })
1246 }
1247 expect(
1248 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1249 pool.workerChoiceStrategyContext.workerChoiceStrategy
1250 ).defaultWorkerWeight
1251 ).toBeGreaterThan(0)
1252 expect(
1253 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1254 pool.workerChoiceStrategyContext.workerChoiceStrategy
1255 ).currentRoundId
1256 ).toBe(0)
1257 expect(
1258 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1259 pool.workerChoiceStrategyContext.workerChoiceStrategy
1260 ).currentWorkerNodeId
1261 ).toBe(0)
1262 expect(
1263 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1264 pool.workerChoiceStrategyContext.workerChoiceStrategy
1265 ).roundWeights
1266 ).toStrictEqual([
1267 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1268 pool.workerChoiceStrategyContext.workerChoiceStrategy
1269 ).defaultWorkerWeight
1270 ])
1271 // We need to clean up the resources after our test
1272 await pool.destroy()
1273 })
1274
1275 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
1276 const pool = new DynamicThreadPool(
1277 min,
1278 max,
1279 './tests/worker-files/thread/testWorker.js',
1280 {
1281 workerChoiceStrategy:
1282 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1283 }
1284 )
1285 // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
1286 const promises = new Set()
1287 const maxMultiplier = 2
1288 for (let i = 0; i < max * maxMultiplier; i++) {
1289 promises.add(pool.execute())
1290 }
1291 await Promise.all(promises)
1292 for (const workerNode of pool.workerNodes) {
1293 expect(workerNode.workerUsage).toStrictEqual({
1294 tasks: {
1295 executed: maxMultiplier,
1296 executing: 0,
1297 queued: 0,
1298 failed: 0
1299 },
1300 runTime: {
1301 aggregation: 0,
1302 average: 0,
1303 median: 0,
1304 history: expect.any(CircularArray)
1305 },
1306 waitTime: {
1307 aggregation: 0,
1308 average: 0,
1309 median: 0,
1310 history: expect.any(CircularArray)
1311 },
1312 elu: undefined
1313 })
1314 }
1315 expect(
1316 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1317 pool.workerChoiceStrategyContext.workerChoiceStrategy
1318 ).defaultWorkerWeight
1319 ).toBeGreaterThan(0)
1320 expect(
1321 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1322 pool.workerChoiceStrategyContext.workerChoiceStrategy
1323 ).currentRoundId
1324 ).toBe(0)
1325 expect(
1326 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1327 pool.workerChoiceStrategyContext.workerChoiceStrategy
1328 ).currentWorkerNodeId
1329 ).toBe(0)
1330 expect(
1331 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1332 pool.workerChoiceStrategyContext.workerChoiceStrategy
1333 ).roundWeights
1334 ).toStrictEqual([
1335 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1336 pool.workerChoiceStrategyContext.workerChoiceStrategy
1337 ).defaultWorkerWeight
1338 ])
1339 // We need to clean up the resources after our test
1340 await pool.destroy()
1341 })
1342
1343 it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
1344 const workerChoiceStrategy =
1345 WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
1346 let pool = new FixedThreadPool(
1347 max,
1348 './tests/worker-files/thread/testWorker.js'
1349 )
1350 expect(
1351 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1352 workerChoiceStrategy
1353 ).currentRoundId
1354 ).toBeDefined()
1355 expect(
1356 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1357 workerChoiceStrategy
1358 ).currentWorkerNodeId
1359 ).toBeDefined()
1360 expect(
1361 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1362 workerChoiceStrategy
1363 ).defaultWorkerWeight
1364 ).toBeDefined()
1365 expect(
1366 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1367 workerChoiceStrategy
1368 ).roundWeights
1369 ).toBeDefined()
1370 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1371 expect(
1372 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1373 workerChoiceStrategy
1374 ).currentRoundId
1375 ).toBe(0)
1376 expect(
1377 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1378 pool.workerChoiceStrategyContext.workerChoiceStrategy
1379 ).currentWorkerNodeId
1380 ).toBe(0)
1381 expect(
1382 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1383 pool.workerChoiceStrategyContext.workerChoiceStrategy
1384 ).defaultWorkerWeight
1385 ).toBeGreaterThan(0)
1386 expect(
1387 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1388 workerChoiceStrategy
1389 ).roundWeights
1390 ).toStrictEqual([
1391 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1392 pool.workerChoiceStrategyContext.workerChoiceStrategy
1393 ).defaultWorkerWeight
1394 ])
1395 await pool.destroy()
1396 pool = new DynamicThreadPool(
1397 min,
1398 max,
1399 './tests/worker-files/thread/testWorker.js'
1400 )
1401 expect(
1402 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1403 workerChoiceStrategy
1404 ).currentRoundId
1405 ).toBeDefined()
1406 expect(
1407 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1408 workerChoiceStrategy
1409 ).currentWorkerNodeId
1410 ).toBeDefined()
1411 expect(
1412 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1413 workerChoiceStrategy
1414 ).defaultWorkerWeight
1415 ).toBeDefined()
1416 expect(
1417 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1418 workerChoiceStrategy
1419 ).roundWeights
1420 ).toBeDefined()
1421 pool.setWorkerChoiceStrategy(workerChoiceStrategy)
1422 expect(
1423 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1424 pool.workerChoiceStrategyContext.workerChoiceStrategy
1425 ).currentWorkerNodeId
1426 ).toBe(0)
1427 expect(
1428 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1429 pool.workerChoiceStrategyContext.workerChoiceStrategy
1430 ).defaultWorkerWeight
1431 ).toBeGreaterThan(0)
1432 expect(
1433 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1434 workerChoiceStrategy
1435 ).roundWeights
1436 ).toStrictEqual([
1437 pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
1438 pool.workerChoiceStrategyContext.workerChoiceStrategy
1439 ).defaultWorkerWeight
1440 ])
1441 // We need to clean up the resources after our test
1442 await pool.destroy()
1443 })
1444
1445 it('Verify unknown strategy throw error', () => {
1446 expect(
1447 () =>
1448 new DynamicThreadPool(
1449 min,
1450 max,
1451 './tests/worker-files/thread/testWorker.js',
1452 { workerChoiceStrategy: 'UNKNOWN_STRATEGY' }
1453 )
1454 ).toThrowError("Invalid worker choice strategy 'UNKNOWN_STRATEGY'")
1455 })
1456 })