From fa2af10149b6da760ab35b04755ef90f98105eac Mon Sep 17 00:00:00 2001 From: Lyudmil Danailov Date: Thu, 21 Mar 2024 17:13:26 +0200 Subject: [PATCH] Updating tests --- index.js | 4 +- lib/task_manager.js | 2 +- test/eth/next_interval_calculator.spec.js | 10 +- test/eth/worker.spec.js | 7 + test/index.test.js | 14 ++ test/lib/task_manager.spec.js | 157 +++++++--------------- 6 files changed, 78 insertions(+), 116 deletions(-) diff --git a/index.js b/index.js index 6eccead9..4c2f16e7 100644 --- a/index.js +++ b/index.js @@ -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); } diff --git a/lib/task_manager.js b/lib/task_manager.js index 7bbeb508..58c52a04 100644 --- a/lib/task_manager.js +++ b/lib/task_manager.js @@ -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); diff --git a/test/eth/next_interval_calculator.spec.js b/test/eth/next_interval_calculator.spec.js index 0b5b9813..e5ef8c3f 100644 --- a/test/eth/next_interval_calculator.spec.js +++ b/test/eth/next_interval_calculator.spec.js @@ -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); }); @@ -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); }); diff --git a/test/eth/worker.spec.js b/test/eth/worker.spec.js index 2efe9c0d..75d7b79c 100644 --- a/test/eth/worker.spec.js +++ b/test/eth/worker.spec.js @@ -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 () { diff --git a/test/index.test.js b/test/index.test.js index a49054e8..737c60e3 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -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); diff --git a/test/lib/task_manager.spec.js b/test/lib/task_manager.spec.js index ce7f7e07..a206d959 100644 --- a/test/lib/task_manager.spec.js +++ b/test/lib/task_manager.spec.js @@ -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); @@ -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]); }); });