Merge branch 'elu-strategy' of github.com:poolifier/poolifier into elu-strategy
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
index 352eb7f636e30788ce90c80d4e6d98c1255ded77..a0a86efe3e6567f3594a3ac5020fae566455760d 100644 (file)
@@ -15,6 +15,7 @@ describe('Selection strategies test suite', () => {
     expect(WorkerChoiceStrategies.ROUND_ROBIN).toBe('ROUND_ROBIN')
     expect(WorkerChoiceStrategies.LEAST_USED).toBe('LEAST_USED')
     expect(WorkerChoiceStrategies.LEAST_BUSY).toBe('LEAST_BUSY')
+    expect(WorkerChoiceStrategies.LEAST_ELU).toBe('LEAST_ELU')
     expect(WorkerChoiceStrategies.FAIR_SHARE).toBe('FAIR_SHARE')
     expect(WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN).toBe(
       'WEIGHTED_ROUND_ROBIN'
@@ -122,14 +123,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: false,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -139,14 +141,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: false,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -166,20 +169,33 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: 0,
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
     }
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        WorkerChoiceStrategies.ROUND_ROBIN
+      ).nextWorkerNodeId
+    ).toBe(0)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -199,20 +215,33 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: 0,
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
     }
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        WorkerChoiceStrategies.ROUND_ROBIN
+      ).nextWorkerNodeId
+    ).toBe(0)
     // We need to clean up the resources after our test
     await pool.destroy()
   })
@@ -291,14 +320,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: false,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -308,14 +338,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: false,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -335,18 +366,26 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: 0,
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
     }
     // We need to clean up the resources after our test
@@ -368,18 +407,27 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: 0,
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+
+        elu: undefined
       })
     }
     // We need to clean up the resources after our test
@@ -394,14 +442,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: true,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -411,14 +460,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: true,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -438,22 +488,34 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: expect.any(Number),
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: expect.any(Number),
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.run).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier)
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThanOrEqual(
+        0
+      )
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -474,27 +536,73 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: expect.any(Number),
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: expect.any(Number),
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.run).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier)
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
     }
     // We need to clean up the resources after our test
     await pool.destroy()
   })
 
+  it('Verify LEAST_ELU strategy default tasks usage statistics requirements', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
+      runTime: false,
+      avgRunTime: false,
+      medRunTime: false,
+      waitTime: false,
+      avgWaitTime: false,
+      medWaitTime: false,
+      elu: true
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getTaskStatistics()).toStrictEqual({
+      runTime: false,
+      avgRunTime: false,
+      medRunTime: false,
+      waitTime: false,
+      avgWaitTime: false,
+      medWaitTime: false,
+      elu: true
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
   it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
     let pool = new FixedThreadPool(
@@ -503,14 +611,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: true,
       avgRunTime: true,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -520,14 +629,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: true,
       avgRunTime: true,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -547,21 +657,29 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: expect.any(Number),
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: expect.any(Number),
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -587,21 +705,29 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: expect.any(Number),
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: expect.any(Number),
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -632,21 +758,29 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: maxMultiplier,
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: expect.any(Number),
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: 0,
+          median: expect.any(Number),
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.medRunTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -739,14 +873,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: true,
       avgRunTime: true,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -756,14 +891,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: true,
       avgRunTime: true,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -783,23 +919,35 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: expect.any(Number),
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: expect.any(Number),
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: expect.any(Number),
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: expect.any(Number),
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.run).toBeGreaterThanOrEqual(0)
-      expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier)
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThanOrEqual(0)
-      expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThanOrEqual(
+        0
+      )
+      expect(workerNode.workerUsage.runTime.average).toBeGreaterThanOrEqual(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -830,23 +978,33 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: expect.any(Number),
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: expect.any(Number),
-        medRunTime: 0,
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: expect.any(Number),
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: expect.any(Number),
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.run).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier)
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.avgRunTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -882,23 +1040,33 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.tasksUsage).toStrictEqual({
-        run: expect.any(Number),
-        running: 0,
-        runTime: expect.any(Number),
-        runTimeHistory: expect.any(CircularArray),
-        avgRunTime: 0,
-        medRunTime: expect.any(Number),
-        waitTime: 0,
-        waitTimeHistory: expect.any(CircularArray),
-        avgWaitTime: 0,
-        medWaitTime: 0,
-        error: 0
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: expect.any(Number),
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: expect.any(Number),
+          average: 0,
+          median: expect.any(Number),
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
       })
-      expect(workerNode.tasksUsage.run).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.run).toBeLessThanOrEqual(max * maxMultiplier)
-      expect(workerNode.tasksUsage.runTime).toBeGreaterThan(0)
-      expect(workerNode.tasksUsage.medRunTime).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1001,14 +1169,15 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: false,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -1018,19 +1187,257 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy }
     )
     expect(
-      pool.workerChoiceStrategyContext.getRequiredStatistics()
+      pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
       runTime: false,
       avgRunTime: false,
       medRunTime: false,
       waitTime: false,
       avgWaitTime: false,
-      medWaitTime: false
+      medWaitTime: false,
+      elu: false
     })
     // We need to clean up the resources after our test
     await pool.destroy()
   })
 
+  it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a fixed pool', async () => {
+    const pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      {
+        workerChoiceStrategy:
+          WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
+      }
+    )
+    // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
+    const promises = new Set()
+    const maxMultiplier = 2
+    for (let i = 0; i < max * maxMultiplier; i++) {
+      promises.add(pool.execute())
+    }
+    await Promise.all(promises)
+    for (const workerNode of pool.workerNodes) {
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
+      })
+    }
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ).toBeGreaterThan(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).currentRoundId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).currentWorkerNodeId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).roundWeights
+    ).toStrictEqual([
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ])
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy can be run in a dynamic pool', async () => {
+    const pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      {
+        workerChoiceStrategy:
+          WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
+      }
+    )
+    // TODO: Create a better test to cover `InterleavedWeightedRoundRobinWorkerChoiceStrategy#choose`
+    const promises = new Set()
+    const maxMultiplier = 2
+    for (let i = 0; i < max * maxMultiplier; i++) {
+      promises.add(pool.execute())
+    }
+    await Promise.all(promises)
+    for (const workerNode of pool.workerNodes) {
+      expect(workerNode.workerUsage).toStrictEqual({
+        tasks: {
+          executed: maxMultiplier,
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregation: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: undefined
+      })
+    }
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ).toBeGreaterThan(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).currentRoundId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).currentWorkerNodeId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).roundWeights
+    ).toStrictEqual([
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ])
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy internals are resets after setting it', async () => {
+    const workerChoiceStrategy =
+      WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js'
+    )
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).currentRoundId
+    ).toBeDefined()
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).currentWorkerNodeId
+    ).toBeDefined()
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).defaultWorkerWeight
+    ).toBeDefined()
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).roundWeights
+    ).toBeDefined()
+    pool.setWorkerChoiceStrategy(workerChoiceStrategy)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).currentRoundId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).currentWorkerNodeId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ).toBeGreaterThan(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).roundWeights
+    ).toStrictEqual([
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ])
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js'
+    )
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).currentRoundId
+    ).toBeDefined()
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).currentWorkerNodeId
+    ).toBeDefined()
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).defaultWorkerWeight
+    ).toBeDefined()
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).roundWeights
+    ).toBeDefined()
+    pool.setWorkerChoiceStrategy(workerChoiceStrategy)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).currentWorkerNodeId
+    ).toBe(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ).toBeGreaterThan(0)
+    expect(
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategy
+      ).roundWeights
+    ).toStrictEqual([
+      pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
+        pool.workerChoiceStrategyContext.workerChoiceStrategy
+      ).defaultWorkerWeight
+    ])
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
   it('Verify unknown strategy throw error', () => {
     expect(
       () =>