Skip to content

Commit

Permalink
add test to uncovered lines in some modules in the worker folder:
Browse files Browse the repository at this point in the history
caliper-worker
worker-message-handler
fixedFeedbackRate
recordRate

Signed-off-by: Babatunde Sanusi <[email protected]>
  • Loading branch information
tunedev committed Aug 21, 2024
1 parent a8a32d4 commit 1e3cdf4
Show file tree
Hide file tree
Showing 6 changed files with 544 additions and 49 deletions.
5 changes: 3 additions & 2 deletions packages/caliper-core/lib/worker/caliper-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,14 @@ class CaliperWorker {
/**
* Perform test with specified test duration
* @param {object} workloadModule The user test module.
* @param {Object} duration duration to run for
* @param {Object} duration duration to run forASc
* @param {Object} rateController rate controller object
* @async
*/
async runDuration(workloadModule, duration, rateController) {
const stats = this.internalTxObserver.getCurrentStatistics();
let startTime = stats.getRoundStartTime();

let error = undefined;
while ((Date.now() - startTime) < (duration * 1000) && !error) {
await rateController.applyRateControl();
Expand Down Expand Up @@ -161,7 +162,7 @@ class CaliperWorker {
await this.workloadModule.initializeWorkloadModule(this.workerIndex, prepareTestMessage.getWorkersNumber(), roundIndex, prepareTestMessage.getWorkloadSpec().arguments, this.connector, context);
await CaliperUtils.sleep(this.txUpdateTime);
} catch (err) {
Logger.info(`Worker [${this.workerIndex}] encountered an error during prepare test phase for round ${roundIndex}: ${(err.stack ? err.stack : err)}`);
Logger.warn(`Worker [${this.workerIndex}] encountered an error during prepare test phase for round ${roundIndex}: ${(err.stack ? err.stack : err)}`);
throw err;
} finally {
await this.connector.releaseContext(context);
Expand Down
83 changes: 81 additions & 2 deletions packages/caliper-core/test/worker/caliper-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ mockery.registerMock('./tx-observers/tx-observer-dispatch', MockTxObserverDispat

const loggerSandbox = sinon.createSandbox();
const CaliperUtils = require('../../lib/common/utils/caliper-utils');
loggerSandbox.replace(CaliperUtils, "getLogger", MockCaliperUtils.getLogger);
loggerSandbox.replace(CaliperUtils, 'getLogger', MockCaliperUtils.getLogger);

const CaliperWorker = require('../../lib/worker/caliper-worker');

Expand Down Expand Up @@ -119,7 +119,7 @@ describe('Caliper worker', () => {

afterEach(() => {
sandbox.restore();
})
});

const validateCallsAndWarnings = (warnings) => {
sinon.assert.calledOnce(mockWorkload.submitTransaction);
Expand Down Expand Up @@ -161,5 +161,84 @@ describe('Caliper worker', () => {
await worker.executeRound(mockTestMessage);
validateCallsAndWarnings(4);
});

it('should wait for all transactions to finish', async () => {
const mockRoundStats = {
getTotalFinishedTx: sinon.stub(),
getTotalSubmittedTx: sinon.stub()
};

mockRoundStats.getTotalFinishedTx.onCall(0).returns(0);
mockRoundStats.getTotalFinishedTx.onCall(1).returns(1);
mockRoundStats.getTotalSubmittedTx.returns(1);

await CaliperWorker._waitForTxsToFinish(mockRoundStats);

sinon.assert.calledTwice(mockRoundStats.getTotalFinishedTx);
});

it('should execute the round for a specified duration', async function() {
this.timeout(5000); // Increase the timeout for this test
const worker = new CaliperWorker(mockConnector, 1, mockMessenger, 'uuid');
await worker.prepareTest(mockTestMessage);
mockWorkload.submitTransaction.resolves();
mockTestMessage.getRoundDuration.returns(1); // duration in seconds

await worker.executeRound(mockTestMessage);

sinon.assert.calledOnce(deactivateMethod);
sinon.assert.calledOnce(mockRate.end);
sinon.assert.calledOnce(mockWorkload.cleanupWorkloadModule);
sinon.assert.called(mockConnector.releaseContext);
});

it('should handle error during transaction submission in runDuration', async () => {
const worker = new CaliperWorker(mockConnector, 1, mockMessenger, 'uuid');
await worker.prepareTest(mockTestMessage);
mockWorkload.submitTransaction.rejects(new Error('transaction error'));
mockTestMessage.getRoundDuration.returns(Date.now() * 100); // duration in seconds
const getCurrentStatisticsStub = sinon.stub(worker.internalTxObserver, 'getCurrentStatistics');
getCurrentStatisticsStub.returns({
getRoundStartTime: sandbox.stub().returns(2)
});

await worker.executeRound(mockTestMessage).should.be.rejectedWith(/transaction error/);

sinon.assert.calledOnce(deactivateMethod);
sinon.assert.calledOnce(mockRate.end);
sinon.assert.calledOnce(mockWorkload.cleanupWorkloadModule);
sinon.assert.called(mockConnector.releaseContext);

getCurrentStatisticsStub.restore();
});

it('should handle errors during the prepareTest phase', async () => {
const worker = new CaliperWorker(mockConnector, 1, mockMessenger, 'uuid');
const errorMessage = 'Initialization error';
mockConnector.getContext.rejects(new Error(errorMessage));
mockTestMessage.getRoundIndex.returns(1);
mockTestMessage.getWorkloadSpec.returns({ module: 'test/workload' });
mockTestMessage.getWorkerArguments.returns([]);

await worker.prepareTest(mockTestMessage).should.be.rejectedWith(errorMessage);

sinon.assert.calledOnce(mockConnector.getContext);
sinon.assert.calledOnce(logwarningMethod);
});

it('should execute multiple iterations of the while loop in runDuration', async function() {
this.timeout(5000); // Increase the timeout for this test
const worker = new CaliperWorker(mockConnector, 1, mockMessenger, 'uuid');
await worker.prepareTest(mockTestMessage);
mockWorkload.submitTransaction.resolves();
mockTestMessage.getRoundDuration.returns(2); // duration in seconds

await worker.executeRound(mockTestMessage);

sinon.assert.calledOnce(deactivateMethod);
sinon.assert.calledOnce(mockRate.end);
sinon.assert.calledOnce(mockWorkload.cleanupWorkloadModule);
sinon.assert.called(mockConnector.releaseContext);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,29 @@ describe('fixedFeedbackRate controller implementation', () => {
sinon.assert.calledOnce(sleepStub);
sinon.assert.calledWith(sleepStub, 20000);
});

it('should sleep when no successful transactions have occurred', async () => {
txnStats.stats.txCounters.totalSubmitted = 5;
txnStats.stats.txCounters.totalFinished = 2;
txnStats.stats.txCounters.totalSuccessful = 0;
controller.generalSleepTime = 1;

await controller.applyRateControl();

sinon.assert.calledOnce(sleepStub);
sinon.assert.calledWith(sleepStub, 1 * controller.backOffTime);
});

it('should sleep when unfinished transactions are above the threshold', async () => {
txnStats.stats.txCounters.totalSubmitted = 44;
txnStats.stats.txCounters.totalFinished = 40;
controller.unfinishedPerWorker = 1;
controller.backOffTime = 100;

await controller.applyRateControl();

sinon.assert.calledOnce(sleepStub);
sinon.assert.calledWith(sleepStub, 88 * controller.backOffTime);
});
});
});
4 changes: 2 additions & 2 deletions packages/caliper-core/test/worker/rate-control/noRate.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('noRate controller implementation', () => {
});


it ('should throw an error if a value for the number of transactions is set', async () => {
it('should throw an error if a value for the number of transactions is set', async () => {
try {
testMessage.content.numb = 6;
controller = new NoRate.createRateController(testMessage, {}, 0);
Expand All @@ -60,7 +60,7 @@ describe('noRate controller implementation', () => {
}
});

it ('should set the sleep time based on the length of the round in seconds', () => {
it('should set the sleep time based on the length of the round in seconds', () => {
testMessage.content.txDuration = 6;
controller = new NoRate.createRateController(testMessage, {}, 0);

Expand Down
Loading

0 comments on commit 1e3cdf4

Please sign in to comment.