test: improve IWRR coverage
[poolifier.git] / tests / pools / selection-strategies / worker-choice-strategy-context.test.mjs
index dc898e4ff04cd8ccb554a1215191896354757928..2b8d35d8f485f1ac45ffa6fd203ce33dd6f04073 100644 (file)
@@ -49,13 +49,14 @@ describe('Worker choice strategy context test suite', () => {
     )
   })
 
-  it('Verify that execute() return the worker chosen by the strategy with fixed pool', () => {
+  it('Verify that execute() return the worker node key chosen by the strategy with fixed pool', () => {
     const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
       fixedPool
     )
     const workerChoiceStrategyStub = createStubInstance(
       RoundRobinWorkerChoiceStrategy,
       {
+        hasPoolWorkerNodesReady: stub().returns(true),
         choose: stub().returns(0)
       }
     )
@@ -79,44 +80,123 @@ describe('Worker choice strategy context test suite', () => {
     const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
       fixedPool
     )
+    expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
+      WorkerChoiceStrategies.ROUND_ROBIN
+    )
     const workerChoiceStrategyUndefinedStub = createStubInstance(
       RoundRobinWorkerChoiceStrategy,
       {
+        hasPoolWorkerNodesReady: stub().returns(true),
         choose: stub().returns(undefined)
       }
     )
+    workerChoiceStrategyContext.workerChoiceStrategies.set(
+      workerChoiceStrategyContext.workerChoiceStrategy,
+      workerChoiceStrategyUndefinedStub
+    )
+    expect(() => workerChoiceStrategyContext.execute()).toThrow(
+      new Error(
+        `Worker node key chosen is null or undefined after ${
+          fixedPool.info.maxSize +
+          Object.keys(workerChoiceStrategyContext.opts.weights).length
+        } retries`
+      )
+    )
     const workerChoiceStrategyNullStub = createStubInstance(
       RoundRobinWorkerChoiceStrategy,
       {
+        hasPoolWorkerNodesReady: stub().returns(true),
         choose: stub().returns(null)
       }
     )
+    workerChoiceStrategyContext.workerChoiceStrategies.set(
+      workerChoiceStrategyContext.workerChoiceStrategy,
+      workerChoiceStrategyNullStub
+    )
+    expect(() => workerChoiceStrategyContext.execute()).toThrow(
+      new Error(
+        `Worker node key chosen is null or undefined after ${
+          fixedPool.info.maxSize +
+          Object.keys(workerChoiceStrategyContext.opts.weights).length
+        } retries`
+      )
+    )
+  })
+
+  it('Verify that execute() retry until a worker node is ready and chosen', () => {
+    const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
+      fixedPool
+    )
+    const workerChoiceStrategyStub = createStubInstance(
+      RoundRobinWorkerChoiceStrategy,
+      {
+        hasPoolWorkerNodesReady: stub()
+          .onCall(0)
+          .returns(false)
+          .onCall(1)
+          .returns(false)
+          .onCall(2)
+          .returns(false)
+          .onCall(3)
+          .returns(false)
+          .onCall(4)
+          .returns(false)
+          .returns(true),
+        choose: stub().returns(1)
+      }
+    )
     expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
       WorkerChoiceStrategies.ROUND_ROBIN
     )
     workerChoiceStrategyContext.workerChoiceStrategies.set(
       workerChoiceStrategyContext.workerChoiceStrategy,
-      workerChoiceStrategyUndefinedStub
+      workerChoiceStrategyStub
+    )
+    const chosenWorkerKey = workerChoiceStrategyContext.execute()
+    expect(
+      workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategyContext.workerChoiceStrategy
+      ).hasPoolWorkerNodesReady.callCount
+    ).toBe(6)
+    expect(
+      workerChoiceStrategyContext.workerChoiceStrategies.get(
+        workerChoiceStrategyContext.workerChoiceStrategy
+      ).choose.callCount
+    ).toBe(1)
+    expect(chosenWorkerKey).toBe(1)
+  })
+
+  it('Verify that execute() throws error if worker choice strategy recursion reach the maximum depth', () => {
+    const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
+      fixedPool
+    )
+    const workerChoiceStrategyStub = createStubInstance(
+      RoundRobinWorkerChoiceStrategy,
+      {
+        hasPoolWorkerNodesReady: stub().returns(false),
+        choose: stub().returns(0)
+      }
     )
-    expect(() => workerChoiceStrategyContext.execute()).toThrowError(
-      new Error('Worker node key chosen is null or undefined after 6 retries')
+    expect(workerChoiceStrategyContext.workerChoiceStrategy).toBe(
+      WorkerChoiceStrategies.ROUND_ROBIN
     )
     workerChoiceStrategyContext.workerChoiceStrategies.set(
       workerChoiceStrategyContext.workerChoiceStrategy,
-      workerChoiceStrategyNullStub
+      workerChoiceStrategyStub
     )
-    expect(() => workerChoiceStrategyContext.execute()).toThrowError(
-      new Error('Worker node key chosen is null or undefined after 6 retries')
+    expect(() => workerChoiceStrategyContext.execute()).toThrow(
+      new RangeError('Maximum call stack size exceeded')
     )
   })
 
-  it('Verify that execute() return the worker chosen by the strategy with dynamic pool', () => {
+  it('Verify that execute() return the worker node key chosen by the strategy with dynamic pool', () => {
     const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
       dynamicPool
     )
     const workerChoiceStrategyStub = createStubInstance(
       RoundRobinWorkerChoiceStrategy,
       {
+        hasPoolWorkerNodesReady: stub().returns(true),
         choose: stub().returns(0)
       }
     )