From: Jérôme Benoit Date: Wed, 5 Jul 2023 21:41:47 +0000 (+0200) Subject: fix: fix internal measurements handling X-Git-Tag: v2.6.9~11 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=715143510b6627ffeb2735f42bb682935f16b9e9;p=poolifier.git fix: fix internal measurements handling Signed-off-by: Jérôme Benoit --- diff --git a/src/pools/abstract-pool.ts b/src/pools/abstract-pool.ts index fc703d14..e97ce4f8 100644 --- a/src/pools/abstract-pool.ts +++ b/src/pools/abstract-pool.ts @@ -303,12 +303,12 @@ export abstract class AbstractPool< runTime: { minimum: Math.min( ...this.workerNodes.map( - workerNode => workerNode.usage.runTime.minimum + workerNode => workerNode.usage.runTime?.minimum ?? Infinity ) ), maximum: Math.max( ...this.workerNodes.map( - workerNode => workerNode.usage.runTime.maximum + workerNode => workerNode.usage.runTime?.maximum ?? -Infinity ) ) } @@ -318,12 +318,12 @@ export abstract class AbstractPool< waitTime: { minimum: Math.min( ...this.workerNodes.map( - workerNode => workerNode.usage.waitTime.minimum + workerNode => workerNode.usage.waitTime?.minimum ?? Infinity ) ), maximum: Math.max( ...this.workerNodes.map( - workerNode => workerNode.usage.waitTime.maximum + workerNode => workerNode.usage.waitTime?.maximum ?? -Infinity ) ) } @@ -341,12 +341,12 @@ export abstract class AbstractPool< (performance.now() - this.startTimestamp) * this.maxSize const totalTasksRunTime = this.workerNodes.reduce( (accumulator, workerNode) => - accumulator + workerNode.usage.runTime.aggregate, + accumulator + (workerNode.usage.runTime?.aggregate ?? 0), 0 ) const totalTasksWaitTime = this.workerNodes.reduce( (accumulator, workerNode) => - accumulator + workerNode.usage.waitTime.aggregate, + accumulator + (workerNode.usage.waitTime?.aggregate ?? 0), 0 ) return (totalTasksRunTime + totalTasksWaitTime) / poolRunTimeCapacity @@ -617,14 +617,15 @@ export abstract class AbstractPool< .aggregate ) { const taskRunTime = message.taskPerformance?.runTime ?? 0 - workerUsage.runTime.aggregate += taskRunTime + workerUsage.runTime.aggregate = + (workerUsage.runTime.aggregate ?? 0) + taskRunTime workerUsage.runTime.minimum = Math.min( taskRunTime, - workerUsage.runTime.minimum ?? Infinity + workerUsage.runTime?.minimum ?? Infinity ) workerUsage.runTime.maximum = Math.max( taskRunTime, - workerUsage.runTime.maximum ?? -Infinity + workerUsage.runTime?.maximum ?? -Infinity ) if ( this.workerChoiceStrategyContext.getTaskStatisticsRequirements().runTime @@ -656,14 +657,15 @@ export abstract class AbstractPool< this.workerChoiceStrategyContext.getTaskStatisticsRequirements().waitTime .aggregate ) { - workerUsage.waitTime.aggregate += taskWaitTime + workerUsage.waitTime.aggregate = + (workerUsage.waitTime?.aggregate ?? 0) + taskWaitTime workerUsage.waitTime.minimum = Math.min( taskWaitTime, - workerUsage.waitTime.minimum ?? Infinity + workerUsage.waitTime?.minimum ?? Infinity ) workerUsage.waitTime.maximum = Math.max( taskWaitTime, - workerUsage.waitTime.maximum ?? -Infinity + workerUsage.waitTime?.maximum ?? -Infinity ) if ( this.workerChoiceStrategyContext.getTaskStatisticsRequirements() @@ -676,8 +678,7 @@ export abstract class AbstractPool< } if ( this.workerChoiceStrategyContext.getTaskStatisticsRequirements() - .waitTime.median && - taskWaitTime != null + .waitTime.median ) { workerUsage.waitTime.history.push(taskWaitTime) workerUsage.waitTime.median = median(workerUsage.waitTime.history) @@ -694,8 +695,12 @@ export abstract class AbstractPool< .aggregate ) { if (message.taskPerformance?.elu != null) { - workerUsage.elu.idle.aggregate += message.taskPerformance.elu.idle - workerUsage.elu.active.aggregate += message.taskPerformance.elu.active + workerUsage.elu.idle.aggregate = + (workerUsage.elu.idle?.aggregate ?? 0) + + message.taskPerformance.elu.idle + workerUsage.elu.active.aggregate = + (workerUsage.elu.active?.aggregate ?? 0) + + message.taskPerformance.elu.active if (workerUsage.elu.utilization != null) { workerUsage.elu.utilization = (workerUsage.elu.utilization + @@ -706,42 +711,44 @@ export abstract class AbstractPool< } workerUsage.elu.idle.minimum = Math.min( message.taskPerformance.elu.idle, - workerUsage.elu.idle.minimum ?? Infinity + workerUsage.elu.idle?.minimum ?? Infinity ) workerUsage.elu.idle.maximum = Math.max( message.taskPerformance.elu.idle, - workerUsage.elu.idle.maximum ?? -Infinity + workerUsage.elu.idle?.maximum ?? -Infinity ) workerUsage.elu.active.minimum = Math.min( message.taskPerformance.elu.active, - workerUsage.elu.active.minimum ?? Infinity + workerUsage.elu.active?.minimum ?? Infinity ) workerUsage.elu.active.maximum = Math.max( message.taskPerformance.elu.active, - workerUsage.elu.active.maximum ?? -Infinity + workerUsage.elu.active?.maximum ?? -Infinity ) - } - if ( - this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu - .average && - workerUsage.tasks.executed !== 0 - ) { - const executedTasks = - workerUsage.tasks.executed - workerUsage.tasks.failed - workerUsage.elu.idle.average = - workerUsage.elu.idle.aggregate / executedTasks - workerUsage.elu.active.average = - workerUsage.elu.active.aggregate / executedTasks - } - if ( - this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu - .median && - message.taskPerformance?.elu != null - ) { - workerUsage.elu.idle.history.push(message.taskPerformance.elu.idle) - workerUsage.elu.active.history.push(message.taskPerformance.elu.active) - workerUsage.elu.idle.median = median(workerUsage.elu.idle.history) - workerUsage.elu.active.median = median(workerUsage.elu.active.history) + if ( + this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu + .average && + workerUsage.tasks.executed !== 0 + ) { + const executedTasks = + workerUsage.tasks.executed - workerUsage.tasks.failed + workerUsage.elu.idle.average = + workerUsage.elu.idle.aggregate / executedTasks + workerUsage.elu.active.average = + workerUsage.elu.active.aggregate / executedTasks + } + if ( + this.workerChoiceStrategyContext.getTaskStatisticsRequirements().elu + .median && + message.taskPerformance?.elu != null + ) { + workerUsage.elu.idle.history.push(message.taskPerformance.elu.idle) + workerUsage.elu.active.history.push( + message.taskPerformance.elu.active + ) + workerUsage.elu.idle.median = median(workerUsage.elu.idle.history) + workerUsage.elu.active.median = median(workerUsage.elu.active.history) + } } } } @@ -1120,14 +1127,26 @@ export abstract class AbstractPool< private getInitialWorkerUsage (worker?: Worker): WorkerUsage { const getTasksQueueSize = (worker?: Worker): number => { - return worker != null - ? this.tasksQueueSize(this.getWorkerNodeKey(worker)) - : 0 + if (worker == null) { + return 0 + } + // FIXME: Workaround tasks queue initialization issue. + try { + return this.tasksQueueSize(this.getWorkerNodeKey(worker)) + } catch { + return 0 + } } const getTasksMaxQueueSize = (worker?: Worker): number => { - return worker != null - ? this.tasksMaxQueueSize(this.getWorkerNodeKey(worker)) - : 0 + if (worker == null) { + return 0 + } + // FIXME: Workaround tasks queue initialization issue. + try { + return this.tasksMaxQueueSize(this.getWorkerNodeKey(worker)) + } catch { + return 0 + } } return { tasks: { @@ -1142,36 +1161,16 @@ export abstract class AbstractPool< failed: 0 }, runTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: new CircularArray() }, waitTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: new CircularArray() }, elu: { idle: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: new CircularArray() }, active: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: new CircularArray() } } diff --git a/src/pools/selection-strategies/abstract-worker-choice-strategy.ts b/src/pools/selection-strategies/abstract-worker-choice-strategy.ts index cd969ccd..7f26706d 100644 --- a/src/pools/selection-strategies/abstract-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/abstract-worker-choice-strategy.ts @@ -152,8 +152,8 @@ export abstract class AbstractWorkerChoiceStrategy< */ protected getWorkerTaskRunTime (workerNodeKey: number): number { return this.taskStatisticsRequirements.runTime.median - ? this.pool.workerNodes[workerNodeKey].usage.runTime.median - : this.pool.workerNodes[workerNodeKey].usage.runTime.average + ? this.pool.workerNodes[workerNodeKey].usage.runTime?.median ?? 0 + : this.pool.workerNodes[workerNodeKey].usage.runTime?.average ?? 0 } /** @@ -166,8 +166,8 @@ export abstract class AbstractWorkerChoiceStrategy< */ protected getWorkerTaskWaitTime (workerNodeKey: number): number { return this.taskStatisticsRequirements.waitTime.median - ? this.pool.workerNodes[workerNodeKey].usage.waitTime.median - : this.pool.workerNodes[workerNodeKey].usage.waitTime.average + ? this.pool.workerNodes[workerNodeKey].usage.waitTime?.median ?? 0 + : this.pool.workerNodes[workerNodeKey].usage.waitTime?.average ?? 0 } /** @@ -180,8 +180,8 @@ export abstract class AbstractWorkerChoiceStrategy< */ protected getWorkerTaskElu (workerNodeKey: number): number { return this.taskStatisticsRequirements.elu.median - ? this.pool.workerNodes[workerNodeKey].usage.elu.active.median - : this.pool.workerNodes[workerNodeKey].usage.elu.active.average + ? this.pool.workerNodes[workerNodeKey].usage.elu.active?.median ?? 0 + : this.pool.workerNodes[workerNodeKey].usage.elu.active?.average ?? 0 } protected computeDefaultWorkerWeight (): number { diff --git a/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts b/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts index 14aee44f..928b1b2a 100644 --- a/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts +++ b/src/pools/selection-strategies/least-busy-worker-choice-strategy.ts @@ -64,7 +64,8 @@ export class LeastBusyWorkerChoiceStrategy< let minTime = Infinity for (const [workerNodeKey, workerNode] of this.pool.workerNodes.entries()) { const workerTime = - workerNode.usage.runTime.aggregate + workerNode.usage.waitTime.aggregate + (workerNode.usage.runTime?.aggregate ?? 0) + + (workerNode.usage.waitTime?.aggregate ?? 0) if (workerTime === 0) { this.nextWorkerNodeId = workerNodeKey break diff --git a/src/pools/worker.ts b/src/pools/worker.ts index 35853b7d..d071413b 100644 --- a/src/pools/worker.ts +++ b/src/pools/worker.ts @@ -64,23 +64,23 @@ export interface MeasurementStatistics { /** * Measurement aggregate. */ - aggregate: number + aggregate?: number /** * Measurement minimum. */ - minimum: number + minimum?: number /** * Measurement maximum. */ - maximum: number + maximum?: number /** * Measurement average. */ - average: number + average?: number /** * Measurement median. */ - median: number + median?: number /** * Measurement history. */ diff --git a/tests/pools/abstract/abstract-pool.test.js b/tests/pools/abstract/abstract-pool.test.js index d4b147f7..da870774 100644 --- a/tests/pools/abstract/abstract-pool.test.js +++ b/tests/pools/abstract/abstract-pool.test.js @@ -462,36 +462,16 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, waitTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, elu: { idle: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, active: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) } } @@ -534,36 +514,16 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, waitTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, elu: { idle: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, active: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) } } @@ -580,36 +540,16 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, waitTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, elu: { idle: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, active: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) } } @@ -640,36 +580,16 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, waitTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, elu: { idle: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, active: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) } } @@ -688,36 +608,16 @@ describe('Abstract pool test suite', () => { failed: 0 }, runTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, waitTime: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, elu: { idle: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) }, active: { - aggregate: 0, - maximum: 0, - minimum: 0, - average: 0, - median: 0, history: expect.any(CircularArray) } } diff --git a/tests/pools/selection-strategies/selection-strategies.test.js b/tests/pools/selection-strategies/selection-strategies.test.js index b2aa4a0b..167736ed 100644 --- a/tests/pools/selection-strategies/selection-strategies.test.js +++ b/tests/pools/selection-strategies/selection-strategies.test.js @@ -218,31 +218,18 @@ describe('Selection strategies test suite', () => { 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 + } } }) } @@ -279,31 +266,18 @@ describe('Selection strategies test suite', () => { 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 + } } }) } @@ -485,31 +459,18 @@ describe('Selection strategies test suite', () => { 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) @@ -545,31 +506,18 @@ describe('Selection strategies test suite', () => { 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) @@ -685,30 +633,23 @@ describe('Selection strategies test suite', () => { }, 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) @@ -747,30 +688,23 @@ describe('Selection strategies test suite', () => { }, 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) @@ -878,7 +812,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.usage).toStrictEqual({ + expect(workerNode.usage).toMatchObject({ tasks: { executed: expect.any(Number), executing: 0, @@ -887,39 +821,30 @@ describe('Selection strategies test suite', () => { 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) - expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.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() @@ -940,7 +865,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.usage).toStrictEqual({ + expect(workerNode.usage).toMatchObject({ tasks: { executed: expect.any(Number), executing: 0, @@ -949,39 +874,30 @@ describe('Selection strategies test suite', () => { 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) - expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.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() @@ -1081,7 +997,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.usage).toStrictEqual({ + expect(workerNode.usage).toMatchObject({ tasks: { executed: expect.any(Number), executing: 0, @@ -1089,42 +1005,41 @@ describe('Selection strategies test suite', () => { 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: expect.any(Number), - average: expect.any(Number), - median: 0, + }), + active: expect.objectContaining({ history: expect.any(CircularArray) - }, - utilization: expect.any(Number) + }) } }) expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) - expect(workerNode.usage.runTime.aggregate).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.runTime.average).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.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.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( @@ -1150,7 +1065,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.usage).toStrictEqual({ + expect(workerNode.usage).toMatchObject({ tasks: { executed: expect.any(Number), executing: 0, @@ -1158,42 +1073,41 @@ describe('Selection strategies test suite', () => { 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: expect.any(Number), - average: expect.any(Number), - median: 0, + }), + active: expect.objectContaining({ history: expect.any(CircularArray) - }, - utilization: expect.any(Number) + }) } }) expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) - expect(workerNode.usage.runTime.aggregate).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.runTime.average).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.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.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( @@ -1224,7 +1138,7 @@ describe('Selection strategies test suite', () => { } await Promise.all(promises) for (const workerNode of pool.workerNodes) { - expect(workerNode.usage).toStrictEqual({ + expect(workerNode.usage).toMatchObject({ tasks: { executed: expect.any(Number), executing: 0, @@ -1232,42 +1146,41 @@ describe('Selection strategies test suite', () => { 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: expect.any(Number), - average: expect.any(Number), - median: 0, + }), + active: expect.objectContaining({ history: expect.any(CircularArray) - }, - utilization: expect.any(Number) + }) } }) expect(workerNode.usage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) - expect(workerNode.usage.runTime.aggregate).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.runTime.median).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.elu.utilization).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.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.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( @@ -1454,40 +1367,35 @@ describe('Selection strategies test suite', () => { 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) expect(workerNode.usage.tasks.executed).toBeLessThanOrEqual( max * maxMultiplier ) - expect(workerNode.usage.runTime.aggregate).toBeGreaterThanOrEqual(0) - expect(workerNode.usage.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( @@ -1528,30 +1436,21 @@ describe('Selection strategies test suite', () => { }, 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) @@ -1605,30 +1504,21 @@ describe('Selection strategies test suite', () => { }, 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.usage.tasks.executed).toBeGreaterThanOrEqual(0) @@ -1838,31 +1728,18 @@ describe('Selection strategies test suite', () => { 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 + } } }) } @@ -1921,31 +1798,18 @@ describe('Selection strategies test suite', () => { 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 + } } }) }