feat: add initial infrastructure to track per task statistics
[poolifier.git] / tests / pools / selection-strategies / selection-strategies.test.js
index 9b581ff57a9f052d93bca4edfe67e46c266ce8b6..167736edb9f11c24da068a0b43da56c48db14344 100644 (file)
@@ -98,7 +98,7 @@ describe('Selection strategies test suite', () => {
         expect(
           pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
             workerChoiceStrategy
-          ).currentWorkerNodeId
+          ).nextWorkerNodeId
         ).toBe(0)
         expect(
           pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -115,7 +115,31 @@ describe('Selection strategies test suite', () => {
     await pool.destroy()
   })
 
-  it('Verify ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
+  it('Verify ROUND_ROBIN strategy default policy', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: true
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: true
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify ROUND_ROBIN strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN
     let pool = new FixedThreadPool(
       max,
@@ -185,39 +209,27 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: maxMultiplier,
           executing: 0,
           queued: 0,
+          maxQueued: 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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
     }
@@ -245,39 +257,27 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: maxMultiplier,
           executing: 0,
           queued: 0,
+          maxQueued: 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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
     }
@@ -356,7 +356,31 @@ describe('Selection strategies test suite', () => {
     await pool.destroy()
   })
 
-  it('Verify LEAST_USED strategy default tasks usage statistics requirements', async () => {
+  it('Verify LEAST_USED strategy default policy', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify LEAST_USED strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_USED
     let pool = new FixedThreadPool(
       max,
@@ -426,41 +450,33 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
-          executed: maxMultiplier,
+          executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -481,47 +497,63 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
-          executed: maxMultiplier,
+          executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
     }
     // We need to clean up the resources after our test
     await pool.destroy()
   })
 
-  it('Verify LEAST_BUSY strategy default tasks usage statistics requirements', async () => {
+  it('Verify LEAST_BUSY strategy default policy', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify LEAST_BUSY strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_BUSY
     let pool = new FixedThreadPool(
       max,
@@ -591,49 +623,41 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
         runTime: {
           aggregate: expect.any(Number),
-          average: 0,
-          median: 0,
+          maximum: expect.any(Number),
+          minimum: expect.any(Number),
           history: expect.any(CircularArray)
         },
         waitTime: {
           aggregate: expect.any(Number),
-          average: 0,
-          median: 0,
+          maximum: expect.any(Number),
+          minimum: expect.any(Number),
           history: expect.any(CircularArray)
         },
         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(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.waitTime.aggregate).toBeGreaterThanOrEqual(
-        0
-      )
+      expect(workerNode.usage.runTime.aggregate).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.waitTime.aggregate).toBeGreaterThanOrEqual(0)
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -654,53 +678,71 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
         runTime: {
           aggregate: expect.any(Number),
-          average: 0,
-          median: 0,
+          maximum: expect.any(Number),
+          minimum: expect.any(Number),
           history: expect.any(CircularArray)
         },
         waitTime: {
           aggregate: expect.any(Number),
-          average: 0,
-          median: 0,
+          maximum: expect.any(Number),
+          minimum: expect.any(Number),
           history: expect.any(CircularArray)
         },
         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(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.waitTime.aggregate).toBeGreaterThan(0)
+      expect(workerNode.usage.runTime.aggregate).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.waitTime.aggregate).toBeGreaterThanOrEqual(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 () => {
+  it('Verify LEAST_ELU strategy default policy', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify LEAST_ELU strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.LEAST_ELU
     let pool = new FixedThreadPool(
       max,
@@ -770,47 +812,39 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toMatchObject({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 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,
+          idle: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          active: {
-            aggregate: expect.any(Number),
-            average: 0,
-            median: 0,
+          }),
+          active: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          utilization: expect.any(Number)
+          })
         }
       })
-      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
+      if (workerNode.usage.elu.utilization == null) {
+        expect(workerNode.usage.elu.utilization).toBeUndefined()
+      } else {
+        expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0)
+        expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1)
+      }
     }
     // We need to clean up the resources after our test
     await pool.destroy()
@@ -831,53 +865,69 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toMatchObject({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 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,
+          idle: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          active: {
-            aggregate: expect.any(Number),
-            average: 0,
-            median: 0,
+          }),
+          active: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          utilization: expect.any(Number)
+          })
         }
       })
-      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1)
+      if (workerNode.usage.elu.utilization == null) {
+        expect(workerNode.usage.elu.utilization).toBeUndefined()
+      } else {
+        expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0)
+        expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1)
+      }
     }
     // We need to clean up the resources after our test
     await pool.destroy()
   })
 
-  it('Verify FAIR_SHARE strategy default tasks usage statistics requirements', async () => {
+  it('Verify FAIR_SHARE strategy default policy', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: false
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify FAIR_SHARE strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.FAIR_SHARE
     let pool = new FixedThreadPool(
       max,
@@ -898,8 +948,8 @@ describe('Selection strategies test suite', () => {
         median: false
       },
       elu: {
-        aggregate: false,
-        average: false,
+        aggregate: true,
+        average: true,
         median: false
       }
     })
@@ -924,8 +974,8 @@ describe('Selection strategies test suite', () => {
         median: false
       },
       elu: {
-        aggregate: false,
-        average: false,
+        aggregate: true,
+        average: true,
         median: false
       }
     })
@@ -947,43 +997,49 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toMatchObject({
         tasks: {
-          executed: maxMultiplier,
+          executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
-        runTime: {
-          aggregate: expect.any(Number),
-          average: expect.any(Number),
-          median: 0,
+        runTime: expect.objectContaining({
           history: expect.any(CircularArray)
-        },
+        }),
         waitTime: {
-          aggregate: 0,
-          average: 0,
-          median: 0,
           history: expect.any(CircularArray)
         },
         elu: {
-          idle: {
-            aggregate: 0,
-            average: 0,
-            median: 0,
+          idle: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          active: {
-            aggregate: 0,
-            average: 0,
-            median: 0,
+          }),
+          active: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          })
         }
       })
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      if (workerNode.usage.runTime.aggregate == null) {
+        expect(workerNode.usage.runTime.aggregate).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.runTime.average == null) {
+        expect(workerNode.usage.runTime.average).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.average).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.elu.utilization == null) {
+        expect(workerNode.usage.elu.utilization).toBeUndefined()
+      } else {
+        expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0)
+        expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1)
+      }
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1009,43 +1065,49 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toMatchObject({
         tasks: {
-          executed: maxMultiplier,
+          executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
-        runTime: {
-          aggregate: expect.any(Number),
-          average: expect.any(Number),
-          median: 0,
+        runTime: expect.objectContaining({
           history: expect.any(CircularArray)
-        },
+        }),
         waitTime: {
-          aggregate: 0,
-          average: 0,
-          median: 0,
           history: expect.any(CircularArray)
         },
         elu: {
-          idle: {
-            aggregate: 0,
-            average: 0,
-            median: 0,
+          idle: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          active: {
-            aggregate: 0,
-            average: 0,
-            median: 0,
+          }),
+          active: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          })
         }
       })
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      if (workerNode.usage.runTime.aggregate == null) {
+        expect(workerNode.usage.runTime.aggregate).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.runTime.average == null) {
+        expect(workerNode.usage.runTime.average).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.average).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.elu.utilization == null) {
+        expect(workerNode.usage.elu.utilization).toBeUndefined()
+      } else {
+        expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0)
+        expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1)
+      }
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1076,43 +1138,49 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toMatchObject({
         tasks: {
-          executed: maxMultiplier,
+          executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
-        runTime: {
-          aggregate: expect.any(Number),
-          average: 0,
-          median: expect.any(Number),
+        runTime: expect.objectContaining({
           history: expect.any(CircularArray)
-        },
+        }),
         waitTime: {
-          aggregate: 0,
-          average: 0,
-          median: 0,
           history: expect.any(CircularArray)
         },
         elu: {
-          idle: {
-            aggregate: 0,
-            average: 0,
-            median: 0,
+          idle: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          active: {
-            aggregate: 0,
-            average: 0,
-            median: 0,
+          }),
+          active: expect.objectContaining({
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          })
         }
       })
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
+        max * maxMultiplier
+      )
+      if (workerNode.usage.runTime.aggregate == null) {
+        expect(workerNode.usage.runTime.aggregate).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.runTime.median == null) {
+        expect(workerNode.usage.runTime.median).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.median).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.elu.utilization == null) {
+        expect(workerNode.usage.elu.utilization).toBeUndefined()
+      } else {
+        expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0)
+        expect(workerNode.usage.elu.utilization).toBeLessThanOrEqual(1)
+      }
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1197,7 +1265,31 @@ describe('Selection strategies test suite', () => {
     await pool.destroy()
   })
 
-  it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
+  it('Verify WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
+    const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: true
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: true
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy = WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
     let pool = new FixedThreadPool(
       max,
@@ -1267,47 +1359,43 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
-        runTime: {
-          aggregate: expect.any(Number),
-          average: expect.any(Number),
-          median: 0,
+        runTime: expect.objectContaining({
           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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
-      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThanOrEqual(0)
-      expect(workerNode.workerUsage.runTime.average).toBeGreaterThanOrEqual(0)
+      if (workerNode.usage.runTime.aggregate == null) {
+        expect(workerNode.usage.runTime.aggregate).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0)
+      }
+      if (workerNode.usage.runTime.average == null) {
+        expect(workerNode.usage.runTime.average).toBeUndefined()
+      } else {
+        expect(workerNode.usage.runTime.average).toBeGreaterThan(0)
+      }
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1338,47 +1426,39 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
         runTime: {
           aggregate: expect.any(Number),
+          maximum: expect.any(Number),
+          minimum: expect.any(Number),
           average: expect.any(Number),
-          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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
-      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(0)
+      expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0)
+      expect(workerNode.usage.runTime.average).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1414,47 +1494,39 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: expect.any(Number),
           executing: 0,
           queued: 0,
+          maxQueued: 0,
           failed: 0
         },
         runTime: {
           aggregate: expect.any(Number),
-          average: 0,
+          maximum: expect.any(Number),
+          minimum: expect.any(Number),
           median: expect.any(Number),
           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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
-      expect(workerNode.workerUsage.tasks.executed).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.tasks.executed).toBeLessThanOrEqual(
+      expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0)
+      expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual(
         max * maxMultiplier
       )
-      expect(workerNode.workerUsage.runTime.aggregate).toBeGreaterThan(0)
-      expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(0)
+      expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0)
+      expect(workerNode.usage.runTime.median).toBeGreaterThan(0)
     }
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1479,7 +1551,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBeDefined()
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1495,7 +1567,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1516,7 +1588,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBeDefined()
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1532,7 +1604,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1548,7 +1620,32 @@ describe('Selection strategies test suite', () => {
     await pool.destroy()
   })
 
-  it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks usage statistics requirements', async () => {
+  it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default policy', async () => {
+    const workerChoiceStrategy =
+      WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
+    let pool = new FixedThreadPool(
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: true
+    })
+    await pool.destroy()
+    pool = new DynamicThreadPool(
+      min,
+      max,
+      './tests/worker-files/thread/testWorker.js',
+      { workerChoiceStrategy }
+    )
+    expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({
+      useDynamicWorker: true
+    })
+    // We need to clean up the resources after our test
+    await pool.destroy()
+  })
+
+  it('Verify INTERLEAVED_WEIGHTED_ROUND_ROBIN strategy default tasks statistics requirements', async () => {
     const workerChoiceStrategy =
       WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN
     let pool = new FixedThreadPool(
@@ -1622,39 +1719,27 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: maxMultiplier,
           executing: 0,
           queued: 0,
+          maxQueued: 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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
     }
@@ -1666,12 +1751,12 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentRoundId
+      ).roundId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1704,39 +1789,27 @@ describe('Selection strategies test suite', () => {
     }
     await Promise.all(promises)
     for (const workerNode of pool.workerNodes) {
-      expect(workerNode.workerUsage).toStrictEqual({
+      expect(workerNode.usage).toStrictEqual({
         tasks: {
           executed: maxMultiplier,
           executing: 0,
           queued: 0,
+          maxQueued: 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: 0,
-            average: 0,
-            median: 0,
             history: expect.any(CircularArray)
-          },
-          utilization: 0
+          }
         }
       })
     }
@@ -1748,12 +1821,12 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentRoundId
+      ).roundId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1778,12 +1851,12 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentRoundId
+      ).roundId
     ).toBeDefined()
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBeDefined()
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1799,12 +1872,12 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentRoundId
+      ).roundId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1829,12 +1902,12 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentRoundId
+      ).roundId
     ).toBeDefined()
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBeDefined()
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
@@ -1850,7 +1923,7 @@ describe('Selection strategies test suite', () => {
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(
         pool.workerChoiceStrategyContext.workerChoiceStrategy
-      ).currentWorkerNodeId
+      ).nextWorkerNodeId
     ).toBe(0)
     expect(
       pool.workerChoiceStrategyContext.workerChoiceStrategies.get(