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