Skip to content

Commit

Permalink
Updating tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Lyudmil Danailov authored and Lyudmil Danailov committed Mar 21, 2024
1 parent 178afa5 commit fa2af10
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 116 deletions.
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class Main {
}

async handleInitPosition() {
this.lastProcessedPosition = await this.exporter.getLastPosition();
this.worker.initPosition(this.lastProcessedPosition);
const lastRecoveredPosition = await this.exporter.getLastPosition();
this.lastProcessedPosition = this.worker.initPosition(lastRecoveredPosition);
await this.exporter.savePosition(this.lastProcessedPosition);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/task_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class TaskManager {
retrieveCompleted() {
let lastExportedBlock;
const buffer = [];
while (this.taskData[this.lastExportedIndex + 1].data) {
while (this.taskData[this.lastExportedIndex + 1] && this.taskData[this.lastExportedIndex + 1].data) {
const events = this.taskData[this.lastExportedIndex + 1].data;
for (const event of events) buffer.push(event);

Expand Down
10 changes: 8 additions & 2 deletions test/eth/next_interval_calculator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ describe('nextIntervalCalculator', () => {
worker.lastExportedBlock = 0;
worker.lastConfirmedBlock = 150;

const { fromBlock, toBlock } = nextIntervalCalculator(worker);
const { fromBlock, toBlock } = nextIntervalCalculator(
worker.lastExportedBlock,
worker.lastConfirmedBlock,
worker.settings.BLOCK_INTERVAL);
assert.deepStrictEqual(fromBlock, 1);
assert.deepStrictEqual(toBlock, 100);
});
Expand All @@ -93,7 +96,10 @@ describe('nextIntervalCalculator', () => {
worker.lastExportedBlock = 0;
worker.lastConfirmedBlock = 37;

const { fromBlock, toBlock } = nextIntervalCalculator(worker);
const { fromBlock, toBlock } = nextIntervalCalculator(
worker.lastExportedBlock,
worker.lastConfirmedBlock,
worker.settings.BLOCK_INTERVAL);
assert.deepStrictEqual(fromBlock, 1);
assert.deepStrictEqual(toBlock, 37);
});
Expand Down
7 changes: 7 additions & 0 deletions test/eth/worker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ describe('Test worker', function () {
callResultWithPrimaryKey = v8.deserialize(v8.serialize(callResult));
callResultWithPrimaryKey.primaryKey = 2;
});

it('test primary key assignment', function () {
const data = [feeResult, callResult];
worker.decorateWithPrimaryKeys(data);

assert.deepStrictEqual(data, [feeResultWithPrimaryKey, callResultWithPrimaryKey]);
});
});

describe('Test that when action is null parsing would not break', function () {
Expand Down
14 changes: 14 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ describe('Main', () => {
}
});

it('init throws an error when handleInitPosition() fails', async () => {
const mainInstance = new Main();
sinon.stub(mainInstance, 'initExporter').resolves();
sinon.stub(mainInstance, 'initWorker').resolves();
sinon.stub(mainInstance, 'handleInitPosition').throws(new Error('Error when initializing position'));

try {
await mainInstance.init();
expect.fail('init should have thrown an error');
} catch (err) {
assert.strictEqual(err.message, 'Error when initializing position');
}
});

it('initWorker success', async () => {
const mainInstance = new Main();
mainInstance.taskManager = await TaskManager.create(1);
Expand Down
157 changes: 46 additions & 111 deletions test/lib/task_manager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@ const TaskManager = require('../../lib/task_manager');
const { MAX_TASK_DATA_KEYS, START_BLOCK, START_PRIMARY_KEY } = require('../../lib/constants');

describe('TaskManager', () => {
it('constructor initializes corresponding variables', () => {
const taskManager = new TaskManager();

assert.deepStrictEqual(taskManager.taskData, {});
assert.strictEqual(taskManager.consequentTaskIndex, 0);

assert.strictEqual(taskManager.queue, undefined);
assert.strictEqual(taskManager.lastPushedToBuffer, undefined);
assert.strictEqual(taskManager.lastPrimaryKey, undefined);
assert.strictEqual(taskManager.lastExportedBlock, undefined);
});

it('queue is initialized accordingly', async () => {
const taskManager = new TaskManager();
await taskManager.initQueue(5);
Expand All @@ -28,152 +16,99 @@ describe('TaskManager', () => {
const taskManager = await TaskManager.create(CONCURRENCY);
const PQueue = (await import('p-queue')).default;

assert.deepStrictEqual(taskManager.taskData, {});

assert.strictEqual(taskManager.lastExportedIndex, 0);
assert.strictEqual(taskManager.lastTaskIndex, 0);

expect(taskManager.queue).to.be.an.instanceof(PQueue);
expect(taskManager.queue.concurrency).to.eq(CONCURRENCY);

expect(taskManager).to.be.an.instanceof(TaskManager);
});

it('queue handles tasks accordingly when they finish', async () => {
it('pushQueue handles the given task metadata', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
let isMetadataLambdaCalled = false;
const exampleTaskMetadata = {
interval: { fromBlock: 1, toBlock: 50 },
lambda: () => { isMetadataLambdaCalled = true; }
};

const exampleEventsData = [ 1, 2, 3, 4, 5 ];
const emmitedTaskData = [{ fromBlock: 1, toBlock: 10 }, exampleEventsData];
taskManager.queue.emit('completed', emmitedTaskData);

expect(taskManager.taskData).to.deep.eq({ 1: { toBlock: 10, data: exampleEventsData } });
expect(taskManager.consequentTaskIndex).to.eq(1);
expect(taskManager.queue.isPaused).to.eq(false);
});

it('queue is paused when `consequentTaskIndex` crosses the borderline', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.consequentTaskIndex = MAX_TASK_DATA_KEYS;

const exampleEventsData = [ 1, 2, 3, 4, 5 ];
const emmitedTaskData = [{ fromBlock: 1, toBlock: 10 }, exampleEventsData];
taskManager.queue.emit('completed', emmitedTaskData);

expect(taskManager.queue.isPaused).to.eq(true);
taskManager.pushToQueue(exampleTaskMetadata);
expect(taskManager.lastTaskIndex).to.eq(1);
expect(taskManager.taskData).to.deep.eq({
1: exampleTaskMetadata
});
expect(isMetadataLambdaCalled).to.eq(true);
});

it('queue gets started if it\'s been paused', async () => {
it('queue handles tasks accordingly when they finish', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.consequentTaskIndex = MAX_TASK_DATA_KEYS;
taskManager.queue.pause();

taskManager.restartQueueIfNeeded();

expect(taskManager.queue.isPaused).to.eq(false);
expect(taskManager.consequentTaskIndex).to.eq(0);
});

it('retrieveCompleted returns empty array if `taskData` is an empty object', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
const interval = { fromBlock: 1, toBlock: 50 };
taskManager.pushToQueue({
interval: interval,
lambda: () => {}
});
const taskIndex = 1;
const taskData = [ 1, 2, 3, 4, 5 ];
const exampleEventsData = [taskIndex, taskData];
taskManager.queue.emit('completed', exampleEventsData);

const testResult = taskManager.retrieveCompleted();
expect(testResult).to.be.empty;
expect(taskManager.taskData).to.deep.eq({ 1: { data: taskData, interval: interval } });
});

it('retrieveCompleted returns an array for the corresponding sequence in `taskData`', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.initPosition({ blockNumber: 0, primaryKey: 0 });

const exampleEventsData = [ { prop: 1 }, { prop: 2 }, { prop: 3 } ];
const exampleEventsData2 = [ { prop: 4 }, { prop: 5 }, { prop: 6 } ];
const exampleEventsData3 = [ { prop: 7 }, { prop: 8 }, { prop: 9 } ];
const interval1 = { fromBlock: 1, toBlock: 10 };
const interval2 = { fromBlock: 11, toBlock: 20 };
const interval3 = { fromBlock: 21, toBlock: 30 };
const exampleTaskData = {
1: { toBlock: 10, data: exampleEventsData },
11: { toBlock: 20, data: exampleEventsData2 },
21: { toBlock: 30, data: exampleEventsData3 },
1: { interval: interval1, data: exampleEventsData },
2: { interval: interval2, data: exampleEventsData2 },
3: { interval: interval3, data: exampleEventsData3 },
};
taskManager.taskData = exampleTaskData;

const exampleResult = [
{ prop: 1, primaryKey: 1 }, { prop: 2, primaryKey: 2}, { prop: 3, primaryKey: 3 },
{ prop: 4, primaryKey: 4 }, { prop: 5, primaryKey: 5 }, { prop: 6, primaryKey: 6 },
{ prop: 7, primaryKey: 7 }, { prop: 8, primaryKey: 8 }, { prop: 9, primaryKey: 9 }
{ prop: 1 }, { prop: 2 }, { prop: 3 },
{ prop: 4 }, { prop: 5 }, { prop: 6 },
{ prop: 7 }, { prop: 8 }, { prop: 9 }
];

const testResult = taskManager.retrieveCompleted();
expect(testResult).to.deep.eq(exampleResult);
expect(testResult).to.deep.eq([30, exampleResult]);
});

it('retrieveCompleted returns only the first part of the keys data when holes are present in `taskData`', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.initPosition({ blockNumber: 0, primaryKey: 0 });

const exampleEventsData = [ { prop: 1 }, { prop: 2 }, { prop: 3 } ];
const exampleEventsData3 = [ { prop: 7 }, { prop: 8 }, { prop: 9 } ];
const interval1 = { fromBlock: 1, toBlock: 10 };
const interval2 = { fromBlock: 11, toBlock: 20 };
const interval3 = { fromBlock: 21, toBlock: 30 };
const exampleTaskData = {
1: { toBlock: 10, data: exampleEventsData },
21: { toBlock: 30, data: exampleEventsData3 },
1: { interval: interval1, data: exampleEventsData },
2: { interval: interval2, lambda: () => {} },
3: { interval: interval3, data: exampleEventsData3 },
};
taskManager.taskData = exampleTaskData;

const exampleResult = [
{ prop: 1, primaryKey: 1 }, { prop: 2, primaryKey: 2}, { prop: 3, primaryKey: 3 },
{ prop: 1 }, { prop: 2 }, { prop: 3 },
];

const testResult = taskManager.retrieveCompleted();
expect(testResult).to.deep.eq(exampleResult);
});

it('initPosition sets the instance properties accordingly, returns corresponding object (no ZK value present)', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);

const testResult = taskManager.initPosition();
expect(taskManager.lastExportedBlock).to.eq(START_BLOCK);
expect(taskManager.lastPrimaryKey).to.eq(START_PRIMARY_KEY);
expect(testResult).to.deep.eq({ blockNumber: START_BLOCK, primaryKey: START_PRIMARY_KEY });
});

it('initPosition sets the instance properties accordingly, returns corresponding object (ZK value present)', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);

const exampleZookeeperValue = { blockNumber: 10, primaryKey: 300 };
const testResult = taskManager.initPosition(exampleZookeeperValue);
expect(taskManager.lastExportedBlock).to.eq(exampleZookeeperValue.blockNumber);
expect(taskManager.lastPrimaryKey).to.eq(exampleZookeeperValue.primaryKey);
expect(testResult).to.deep.eq(exampleZookeeperValue);
});

it('getLastProcessedPosition returns correct object', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.lastExportedBlock = 10;
taskManager.lastPrimaryKey = 300;

const testResult = taskManager.getLastProcessedPosition();
expect(testResult).to.deep.eq({
blockNumber: taskManager.lastExportedBlock,
primaryKey: taskManager.lastPrimaryKey
});
});

it('isChangedLastExportedBlock returns false when lastProcessedPosition.blockNumber = lastExportedBlock', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.lastExportedBlock = 10;

const testResult = taskManager.isChangedLastExportedBlock(10);
expect(testResult).to.eq(false);
});

it('isChangedLastExportedBlock returns true when lastProcessedPosition.blockNumber != lastExportedBlock', async () => {
const CONCURRENCY = 1;
const taskManager = await TaskManager.create(CONCURRENCY);
taskManager.lastExportedBlock = 10;

const testResult = taskManager.isChangedLastExportedBlock(9);
expect(testResult).to.eq(true);
expect(testResult).to.deep.eq([10, exampleResult]);
});
});

0 comments on commit fa2af10

Please sign in to comment.