X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=tests%2Fpools%2Fselection-strategies%2Fselection-strategies.test.js;h=3329e1dc718f3565202e1344479248013a6171c8;hb=c84b1e6ee62ca0e38ec6a63c0d4ec0b76b9857f8;hp=d7567114ed67d35f9288bd1399c327ac6d9911f4;hpb=d33be4309c69e39da5e81479e40b1a5ec7078bd5;p=poolifier.git diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index d7567114..3329e1dc 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -1,9 +1,10 @@ const { expect } = require('expect') const { - WorkerChoiceStrategies, + DynamicClusterPool, DynamicThreadPool, + FixedClusterPool, FixedThreadPool, - FixedClusterPool + WorkerChoiceStrategies } = require('../../../lib') const { CircularArray } = require('../../../lib/circular-array') @@ -65,6 +66,43 @@ describe('Selection strategies test suite', () => { expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe( workerChoiceStrategy ) + expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ + retries: 6, + runTime: { median: false }, + waitTime: { median: false }, + elu: { median: false } + }) + expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({ + retries: 6, + runTime: { median: false }, + waitTime: { median: false }, + elu: { median: false } + }) + await pool.destroy() + } + for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { + const pool = new DynamicClusterPool( + min, + max, + './tests/worker-files/cluster/testWorker.js' + ) + pool.setWorkerChoiceStrategy(workerChoiceStrategy, { retries: 3 }) + expect(pool.opts.workerChoiceStrategy).toBe(workerChoiceStrategy) + expect(pool.workerChoiceStrategyContext.workerChoiceStrategy).toBe( + workerChoiceStrategy + ) + expect(pool.opts.workerChoiceStrategyOptions).toStrictEqual({ + retries: 3, + runTime: { median: false }, + waitTime: { median: false }, + elu: { median: false } + }) + expect(pool.workerChoiceStrategyContext.opts).toStrictEqual({ + retries: 3, + runTime: { median: false }, + waitTime: { median: false }, + elu: { median: false } + }) await pool.destroy() } }) @@ -75,41 +113,62 @@ describe('Selection strategies test suite', () => { './tests/worker-files/thread/testWorker.js' ) for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { - if (workerChoiceStrategy === WorkerChoiceStrategies.ROUND_ROBIN) { + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).previousWorkerNodeKey + ).toBe(0) + if ( + workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN + ) { + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).defaultWorkerWeight + ).toBeGreaterThan(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).nextWorkerNodeId + ).workerNodeVirtualTaskRunTime ).toBe(0) - } else if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) { + } else if ( + workerChoiceStrategy === + WorkerChoiceStrategies.INTERLEAVED_WEIGHTED_ROUND_ROBIN + ) { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskEndTimestamp - ).toBeInstanceOf(Array) + ).defaultWorkerWeight + ).toBeGreaterThan(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length + ).workerNodeVirtualTaskRunTime ).toBe(0) - } else if ( - workerChoiceStrategy === WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN - ) { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).nextWorkerNodeId + ).roundId ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).defaultWorkerWeight - ).toBeGreaterThan(0) + ).workerNodeId + ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workerVirtualTaskRunTime - ).toBe(0) + ).roundWeights + ).toStrictEqual([ + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).defaultWorkerWeight + ]) } } await pool.destroy() @@ -123,7 +182,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: true + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -133,7 +193,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: true + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -196,10 +257,11 @@ describe('Selection strategies test suite', () => { }) it('Verify ROUND_ROBIN strategy can be run in a fixed pool', async () => { + const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN const pool = new FixedThreadPool( max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } + { workerChoiceStrategy } ) // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` const promises = new Set() @@ -209,57 +271,52 @@ 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, + stolen: 0, failed: 0 }, runTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - WorkerChoiceStrategies.ROUND_ROBIN - ).nextWorkerNodeId + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toBe(pool.workerNodes.length - 1) // We need to clean up the resources after our test await pool.destroy() }) it('Verify ROUND_ROBIN strategy can be run in a dynamic pool', async () => { + const workerChoiceStrategy = WorkerChoiceStrategies.ROUND_ROBIN const pool = new DynamicThreadPool( min, max, './tests/worker-files/thread/testWorker.js', - { workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN } + { workerChoiceStrategy } ) // TODO: Create a better test to cover `RoundRobinWorkerChoiceStrategy#choose` const promises = new Set() @@ -269,47 +326,45 @@ 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, + stolen: 0, failed: 0 }, runTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) + expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) + expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( + max * maxMultiplier + ) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - WorkerChoiceStrategies.ROUND_ROBIN - ).nextWorkerNodeId + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toBe(pool.workerNodes.length - 1) // We need to clean up the resources after our test await pool.destroy() }) @@ -349,14 +404,24 @@ describe('Selection strategies test suite', () => { ) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).nextWorkerNodeId + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBeDefined() pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBe(0) await pool.destroy() pool = new DynamicThreadPool( @@ -367,14 +432,24 @@ describe('Selection strategies test suite', () => { ) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).nextWorkerNodeId + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBeDefined() pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBe(0) // We need to clean up the resources after our test await pool.destroy() @@ -388,7 +463,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -398,7 +474,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -474,42 +551,45 @@ 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, + stolen: 0, failed: 0 }, runTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) + expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) + expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( + max * maxMultiplier + ) } + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -529,42 +609,45 @@ 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, + stolen: 0, failed: 0 }, runTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) + expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) + expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( + max * maxMultiplier + ) } + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -577,7 +660,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -587,7 +671,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -663,50 +748,55 @@ 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, + stolen: 0, failed: 0 }, - runTime: { - aggregate: expect.any(Number), - average: 0, - median: 0, + runTime: expect.objectContaining({ history: expect.any(CircularArray) - }, - waitTime: { - aggregate: expect.any(Number), - average: 0, - median: 0, + }), + waitTime: expect.objectContaining({ history: expect.any(CircularArray) - }, + }), elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) - 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).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.waitTime.aggregate).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.waitTime.aggregate == null) { + expect(workerNode.usage.waitTime.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.waitTime.aggregate).toBeGreaterThan(0) + } } + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -726,48 +816,55 @@ 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, + stolen: 0, failed: 0 }, - runTime: { - aggregate: expect.any(Number), - average: 0, - median: 0, + runTime: expect.objectContaining({ history: expect.any(CircularArray) - }, - waitTime: { - aggregate: expect.any(Number), - average: 0, - median: 0, + }), + waitTime: expect.objectContaining({ history: expect.any(CircularArray) - }, + }), elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) - 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) + if (workerNode.usage.runTime.aggregate == null) { + expect(workerNode.usage.runTime.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.runTime.aggregate).toBeGreaterThan(0) + } + if (workerNode.usage.waitTime.aggregate == null) { + expect(workerNode.usage.waitTime.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.waitTime.aggregate).toBeGreaterThan(0) + } } + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -780,7 +877,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -790,7 +888,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -866,48 +965,61 @@ 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, + stolen: 0, failed: 0 }, runTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, - elu: { - idle: { - aggregate: 0, - average: 0, - median: 0, + elu: expect.objectContaining({ + 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.active.aggregate == null) { + expect(workerNode.usage.elu.active.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.active.aggregate).toBeGreaterThan(0) + } + if (workerNode.usage.elu.idle.aggregate == null) { + expect(workerNode.usage.elu.idle.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.idle.aggregate).toBeGreaterThanOrEqual(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( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -927,48 +1039,61 @@ 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, + stolen: 0, failed: 0 }, runTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, - elu: { - idle: { - aggregate: 0, - average: 0, - median: 0, + elu: expect.objectContaining({ + 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.active.aggregate == null) { + expect(workerNode.usage.elu.active.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.active.aggregate).toBeGreaterThan(0) + } + if (workerNode.usage.elu.idle.aggregate == null) { + expect(workerNode.usage.elu.idle.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.idle.aggregate).toBeGreaterThanOrEqual(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( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -981,7 +1106,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -991,7 +1117,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: false + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -1067,55 +1194,72 @@ 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, + stolen: 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) + history: new CircularArray() }, - elu: { - idle: { - aggregate: 0, - average: 0, - median: 0, + elu: expect.objectContaining({ + idle: expect.objectContaining({ history: expect.any(CircularArray) - }, - active: { - aggregate: expect.any(Number), - average: expect.any(Number), - 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.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) + 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.active.aggregate == null) { + expect(workerNode.usage.elu.active.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.active.aggregate).toBeGreaterThan(0) + } + if (workerNode.usage.elu.idle.aggregate == null) { + expect(workerNode.usage.elu.idle.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.idle.aggregate).toBeGreaterThanOrEqual(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(workerNode.strategyData.virtualTaskEndTimestamp).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(pool.workerNodes.length) + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -1135,55 +1279,72 @@ 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, + stolen: 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) + history: new CircularArray() }, - elu: { - idle: { - aggregate: 0, - average: 0, - median: 0, + elu: expect.objectContaining({ + idle: expect.objectContaining({ history: expect.any(CircularArray) - }, - active: { - aggregate: expect.any(Number), - average: expect.any(Number), - 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.runTime.aggregate).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.runTime.average).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1) + 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.active.aggregate == null) { + expect(workerNode.usage.elu.active.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.active.aggregate).toBeGreaterThan(0) + } + if (workerNode.usage.elu.idle.aggregate == null) { + expect(workerNode.usage.elu.idle.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.idle.aggregate).toBeGreaterThanOrEqual(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(workerNode.strategyData.virtualTaskEndTimestamp).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(pool.workerNodes.length) + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -1208,55 +1369,72 @@ 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, + stolen: 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) + history: new CircularArray() }, - elu: { - idle: { - aggregate: 0, - average: 0, - median: 0, + elu: expect.objectContaining({ + idle: expect.objectContaining({ history: expect.any(CircularArray) - }, - active: { - aggregate: expect.any(Number), - average: expect.any(Number), - 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.runTime.aggregate).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.runTime.median).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.workerUsage.elu.utilization).toBeLessThanOrEqual(1) + 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.active.aggregate == null) { + expect(workerNode.usage.elu.active.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.active.aggregate).toBeGreaterThan(0) + } + if (workerNode.usage.elu.idle.aggregate == null) { + expect(workerNode.usage.elu.idle.aggregate).toBeUndefined() + } else { + expect(workerNode.usage.elu.idle.aggregate).toBeGreaterThanOrEqual(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(workerNode.strategyData.virtualTaskEndTimestamp).toBeGreaterThan(0) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(pool.workerNodes.length) + ).nextWorkerNodeKey + ).toEqual(expect.any(Number)) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) // We need to clean up the resources after our test await pool.destroy() }) @@ -1267,70 +1445,30 @@ describe('Selection strategies test suite', () => { max, './tests/worker-files/thread/testWorker.js' ) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp - ).toBeInstanceOf(Array) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(0) - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp[0] = performance.now() - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(1) + for (const workerNode of pool.workerNodes) { + workerNode.strategyData = { + virtualTaskEndTimestamp: performance.now() + } + } pool.setWorkerChoiceStrategy(workerChoiceStrategy) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp - ).toBeInstanceOf(Array) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(0) + for (const workerNode of pool.workerNodes) { + expect(workerNode.strategyData.virtualTaskEndTimestamp).toBeUndefined() + } await pool.destroy() pool = new DynamicThreadPool( min, max, './tests/worker-files/thread/testWorker.js' ) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp - ).toBeInstanceOf(Array) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(0) - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp[0] = performance.now() - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(1) + for (const workerNode of pool.workerNodes) { + workerNode.strategyData = { + virtualTaskEndTimestamp: performance.now() + } + } pool.setWorkerChoiceStrategy(workerChoiceStrategy) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp - ).toBeInstanceOf(Array) - expect( - pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workersVirtualTaskEndTimestamp.length - ).toBe(0) + for (const workerNode of pool.workerNodes) { + expect(workerNode.strategyData.virtualTaskEndTimestamp).toBeUndefined() + } // We need to clean up the resources after our test await pool.destroy() }) @@ -1343,7 +1481,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: true + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -1353,7 +1492,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: true + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -1429,48 +1569,55 @@ 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, + stolen: 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) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) - 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( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy @@ -1479,7 +1626,7 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workerVirtualTaskRunTime + ).workerNodeVirtualTaskRunTime ).toBeGreaterThanOrEqual(0) // We need to clean up the resources after our test await pool.destroy() @@ -1500,48 +1647,55 @@ 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, + stolen: 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) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) - 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).toBeGreaterThan(0) - expect(workerNode.workerUsage.runTime.average).toBeGreaterThan(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( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy @@ -1550,7 +1704,7 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workerVirtualTaskRunTime + ).workerNodeVirtualTaskRunTime ).toBeGreaterThanOrEqual(0) // We need to clean up the resources after our test await pool.destroy() @@ -1576,48 +1730,55 @@ 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, + stolen: 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) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) - 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).toBeGreaterThan(0) - expect(workerNode.workerUsage.runTime.median).toBeGreaterThan(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.median == null) { + expect(workerNode.usage.runTime.median).toBeUndefined() + } else { + expect(workerNode.usage.runTime.median).toBeGreaterThan(0) + } } + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy @@ -1626,7 +1787,7 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).workerVirtualTaskRunTime + ).workerNodeVirtualTaskRunTime ).toBeGreaterThanOrEqual(0) // We need to clean up the resources after our test await pool.destroy() @@ -1641,7 +1802,12 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).nextWorkerNodeId + ).nextWorkerNodeKey + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).previousWorkerNodeKey ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1651,13 +1817,18 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workerVirtualTaskRunTime + ).workerNodeVirtualTaskRunTime ).toBeDefined() pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1666,8 +1837,8 @@ describe('Selection strategies test suite', () => { ).toBeGreaterThan(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workerVirtualTaskRunTime + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).workerNodeVirtualTaskRunTime ).toBe(0) await pool.destroy() pool = new DynamicThreadPool( @@ -1678,7 +1849,12 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).nextWorkerNodeId + ).nextWorkerNodeKey + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).previousWorkerNodeKey ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1688,13 +1864,18 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).workerVirtualTaskRunTime + ).workerNodeVirtualTaskRunTime ).toBeDefined() pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1703,8 +1884,8 @@ describe('Selection strategies test suite', () => { ).toBeGreaterThan(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy - ).workerVirtualTaskRunTime + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).workerNodeVirtualTaskRunTime ).toBe(0) // We need to clean up the resources after our test await pool.destroy() @@ -1719,7 +1900,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: true + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) await pool.destroy() pool = new DynamicThreadPool( @@ -1729,7 +1911,8 @@ describe('Selection strategies test suite', () => { { workerChoiceStrategy } ) expect(pool.workerChoiceStrategyContext.getStrategyPolicy()).toStrictEqual({ - useDynamicWorker: true + dynamicWorkerUsage: false, + dynamicWorkerReady: true }) // We need to clean up the resources after our test await pool.destroy() @@ -1747,8 +1930,8 @@ describe('Selection strategies test suite', () => { pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() ).toStrictEqual({ runTime: { - aggregate: false, - average: false, + aggregate: true, + average: true, median: false }, waitTime: { @@ -1773,8 +1956,8 @@ describe('Selection strategies test suite', () => { pool.workerChoiceStrategyContext.getTaskStatisticsRequirements() ).toStrictEqual({ runTime: { - aggregate: false, - average: false, + aggregate: true, + average: true, median: false }, waitTime: { @@ -1809,41 +1992,34 @@ 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, + stolen: 0, failed: 0 }, - runTime: { - aggregate: 0, - average: 0, - median: 0, + runTime: expect.objectContaining({ history: expect.any(CircularArray) - }, + }), waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) + expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) + expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( + max * maxMultiplier + ) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1858,8 +2034,18 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).workerNodeId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy @@ -1891,41 +2077,34 @@ 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, + stolen: 0, failed: 0 }, - runTime: { - aggregate: 0, - average: 0, - median: 0, + runTime: expect.objectContaining({ history: expect.any(CircularArray) - }, + }), waitTime: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, elu: { idle: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) + history: new CircularArray() }, active: { - aggregate: 0, - average: 0, - median: 0, - history: expect.any(CircularArray) - }, - utilization: 0 + history: new CircularArray() + } } }) + expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) + expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( + max * maxMultiplier + ) } expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1940,8 +2119,18 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).workerNodeId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey + ).toEqual(expect.any(Number)) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy @@ -1970,7 +2159,17 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).nextWorkerNodeId + ).workerNodeId + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).nextWorkerNodeKey + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).previousWorkerNodeKey ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -1985,13 +2184,23 @@ describe('Selection strategies test suite', () => { pool.setWorkerChoiceStrategy(workerChoiceStrategy) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy + pool.workerChoiceStrategyContext.workerChoiceStrategy ).roundId ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).workerNodeId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -2000,7 +2209,7 @@ describe('Selection strategies test suite', () => { ).toBeGreaterThan(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy + pool.workerChoiceStrategyContext.workerChoiceStrategy ).roundWeights ).toStrictEqual([ pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -2021,7 +2230,17 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( workerChoiceStrategy - ).nextWorkerNodeId + ).workerNodeId + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).nextWorkerNodeKey + ).toBeDefined() + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + workerChoiceStrategy + ).previousWorkerNodeKey ).toBeDefined() expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -2037,7 +2256,22 @@ describe('Selection strategies test suite', () => { expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( pool.workerChoiceStrategyContext.workerChoiceStrategy - ).nextWorkerNodeId + ).roundId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).workerNodeId + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).nextWorkerNodeKey + ).toBe(0) + expect( + pool.workerChoiceStrategyContext.workerChoiceStrategies.get( + pool.workerChoiceStrategyContext.workerChoiceStrategy + ).previousWorkerNodeKey ).toBe(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( @@ -2046,7 +2280,7 @@ describe('Selection strategies test suite', () => { ).toBeGreaterThan(0) expect( pool.workerChoiceStrategyContext.workerChoiceStrategies.get( - workerChoiceStrategy + pool.workerChoiceStrategyContext.workerChoiceStrategy ).roundWeights ).toStrictEqual([ pool.workerChoiceStrategyContext.workerChoiceStrategies.get(