docs: refine changelog entries
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
index 9f1d3a09f42f74f8742e320eec6d6cca2f26dbd0..e9376281efbe66dec0a5f193b03a9fc02bf039fd 100644 (file)
@@ -6,7 +6,6 @@ const {
   FixedClusterPool
 } = require('../../../lib')
 const { CircularArray } = require('../../../lib/circular-array')
-const TestUtils = require('../../test-utils')
 
 describe('Selection strategies test suite', () => {
   const min = 0
@@ -126,13 +125,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -144,13 +151,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -178,18 +193,32 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
     }
     expect(
@@ -224,18 +253,32 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
     }
     expect(
@@ -323,13 +366,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -341,13 +392,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -375,18 +434,32 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
     }
     // We need to clean up the resources after our test
@@ -416,19 +489,32 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
     }
     // We need to clean up the resources after our test
@@ -445,13 +531,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: true,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: true,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: true,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: true,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -463,13 +557,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: true,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: true,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: true,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: true,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -497,29 +599,41 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
       expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
       expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThanOrEqual(
+      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.waitTime.aggregate).toBeGreaterThanOrEqual(
         0
       )
-      expect(
-        workerNode.workerUsage.waitTime.aggregation
-      ).toBeGreaterThanOrEqual(0)
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -548,25 +662,39 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 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.waitTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.waitTime.aggregate).toBeGreaterThan(0)
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -582,13 +710,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: true
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: true,
+        average: false,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -600,13 +736,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: true
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: true,
+        average: false,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -619,13 +763,14 @@ describe('Selection strategies test suite', () => {
       { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_ELU }
     )
     // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#choose`
+    const promises = new Set()
     const maxMultiplier = 2
     for (let i = 0; i < max * maxMultiplier; i++) {
-      await pool.execute()
-      if (i !== max * maxMultiplier - 1) await TestUtils.sleep(500)
+      promises.add(pool.execute())
     }
+    await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      const expectedWorkerUsage = {
+      expect(workerNode.workerUsage).toStrictEqual({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
@@ -633,37 +778,100 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
+        },
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: expect.any(Number),
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: expect.any(Number)
         }
-      }
-      if (workerNode.workerUsage.elu === undefined) {
-        expect(workerNode.workerUsage).toStrictEqual({
-          ...expectedWorkerUsage,
-          elu: undefined
-        })
-      } else {
-        expect(workerNode.workerUsage).toStrictEqual({
-          ...expectedWorkerUsage,
-          elu: {
-            active: expect.any(Number),
-            idle: 0,
-            utilization: 1
-          }
-        })
-      }
+      })
       expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
       expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
+      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
+    }
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify LEAST_ELU strategy can be run in a dynamic pool', async () => {
+    const pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy: WorkerChoiceStrategies.LEAST_ELU }
+    )
+    // TODO: Create a better test to cover `LeastEluWorkerChoiceStrategy#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: expect.any(Number),
+          executing: 0,
+          queued: 0,
+          failed: 0
+        },
+        runTime: {
+          aggregate: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        waitTime: {
+          aggregate: 0,
+          average: 0,
+          median: 0,
+          history: expect.any(CircularArray)
+        },
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: expect.any(Number),
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: expect.any(Number)
+        }
+      })
+      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -679,13 +887,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: true,
-      avgRunTime: true,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: true,
+        average: true,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: true,
+        average: true,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -697,13 +913,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: true,
-      avgRunTime: true,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: true,
+        average: true,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: true,
+        average: true,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -731,21 +955,37 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: expect.any(Number),
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: expect.any(Number),
+            average: expect.any(Number),
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: expect.any(Number)
+        }
       })
-      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
       expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -779,21 +1019,37 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: expect.any(Number),
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: expect.any(Number),
+            average: expect.any(Number),
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: expect.any(Number)
+        }
       })
-      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
       expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -812,7 +1068,7 @@ describe('Selection strategies test suite', () => {
       {
         workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE,
         workerChoiceStrategyOptions: {
-          medRunTime: true
+          runTime: { median: true }
         }
       }
     )
@@ -832,21 +1088,37 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: 0,
           median: expect.any(Number),
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: expect.any(Number),
+            average: expect.any(Number),
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: expect.any(Number)
+        }
       })
-      expect(workerNode.workerUsage.runTime.aggregation).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
       expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
+      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -941,13 +1213,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: true,
-      avgRunTime: true,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: true,
+        average: true,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -959,13 +1239,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: true,
-      avgRunTime: true,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: true,
+        average: true,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -993,26 +1281,38 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: expect.any(Number),
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 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.aggregate).toBeGreaterThanOrEqual(0)
       expect(workerNode.workerUsage.runTime.average).toBeGreaterThanOrEqual(0)
     }
     expect(
@@ -1052,24 +1352,38 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: expect.any(Number),
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 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.aggregate).toBeGreaterThan(0)
       expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
     }
     expect(
@@ -1094,7 +1408,7 @@ describe('Selection strategies test suite', () => {
       {
         workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN,
         workerChoiceStrategyOptions: {
-          medRunTime: true
+          runTime: { median: true }
         }
       }
     )
@@ -1114,24 +1428,38 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: expect.any(Number),
+          aggregate: expect.any(Number),
           average: 0,
           median: expect.any(Number),
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 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.aggregate).toBeGreaterThan(0)
       expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
     }
     expect(
@@ -1237,13 +1565,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     await pool.destroy()
     pool = new DynamicThreadPool(
@@ -1255,13 +1591,21 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.getTaskStatisticsRequirements()
     ).toStrictEqual({
-      runTime: false,
-      avgRunTime: false,
-      medRunTime: false,
-      waitTime: false,
-      avgWaitTime: false,
-      medWaitTime: false,
-      elu: false
+      runTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      waitTime: {
+        aggregate: false,
+        average: false,
+        median: false
+      },
+      elu: {
+        aggregate: false,
+        average: false,
+        median: false
+      }
     })
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -1292,18 +1636,32 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
     }
     expect(
@@ -1360,18 +1718,32 @@ describe('Selection strategies test suite', () => {
           failed: 0
         },
         runTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
         waitTime: {
-          aggregation: 0,
+          aggregate: 0,
           average: 0,
           median: 0,
           history: expect.any(CircularArray)
         },
-        elu: undefined
+        elu: {
+          idle: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          active: {
+            aggregate: 0,
+            average: 0,
+            median: 0,
+            history: expect.any(CircularArray)
+          },
+          utilization: 0
+        }
       })
     }
     expect(