From 5eb5ef204e9d78a80d16dbd17835b8e05edbb969 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Fri, 1 Oct 2021 14:01:08 -0700 Subject: [PATCH] fix(json rpc): Increasing to 100% test coverage --- src/controllers/json-rpc/index.js | 16 ++- .../unit/controllers/json-rpc/a10-rpc.unit.js | 115 ++++++++++++++++++ test/unit/mocks/adapters/index.js | 8 +- 3 files changed, 132 insertions(+), 7 deletions(-) diff --git a/src/controllers/json-rpc/index.js b/src/controllers/json-rpc/index.js index ab54cea..ba90db0 100644 --- a/src/controllers/json-rpc/index.js +++ b/src/controllers/json-rpc/index.js @@ -56,7 +56,7 @@ class JSONRPC { wlogger.info( 'Warning: Can not send JSON RPC response. Can not determine which peer this message came from.' ) - return + return false } // Attempt to parse the incoming data as a JSON RPC string. @@ -66,22 +66,24 @@ class JSONRPC { // Exit quietly if the incoming string is an invalid JSON RPC string. if (parsedData.type === 'invalid') { wlogger.info('Rejecting invalid JSON RPC command.') - return + return false } // Check for duplicate entries with same 'id' value. const alreadyProcessed = _this._checkIfAlreadyProcessed(parsedData) if (alreadyProcessed) { - return + return false } else { + // console.log(`parsedData: ${JSON.stringify(parsedData, null, 2)}`) + // This node will regularly ping known circuit relays with an /about // JSON RPC call. These will be handled by ipfs-coord, but will percolate - // up to ipfs-coord. Ignore these messages. + // up to this library. Ignore these messages. if ( parsedData.type.includes('success') && parsedData.payload.method === undefined ) { - return + return false } // Log the incoming JSON RPC command. @@ -151,6 +153,8 @@ class JSONRPC { // If the ID is new, the function adds it to the cache and return false. _checkIfAlreadyProcessed (data) { try { + // console.log('data: ', data) + const id = data.payload.id // Check if the hash is in the array of already processed message. @@ -170,7 +174,7 @@ class JSONRPC { return alreadyProcessed } catch (err) { console.error('Error in _checkIfAlreadyProcessed: ', err) - return false + return true } } diff --git a/test/unit/controllers/json-rpc/a10-rpc.unit.js b/test/unit/controllers/json-rpc/a10-rpc.unit.js index ce63523..efe6bfb 100644 --- a/test/unit/controllers/json-rpc/a10-rpc.unit.js +++ b/test/unit/controllers/json-rpc/a10-rpc.unit.js @@ -179,5 +179,120 @@ describe('#JSON RPC', () => { assert.equal(obj.result.method, 'about') assert.equal(obj.id, id) }) + + it('should exit quietly for duplicate RPC message', async () => { + const id = uid() + const json = jsonrpc.request(id, 'unknownMethod', {}) + + const str = JSON.stringify(json) + + // Call router once. + await uut.router(str, 'peerA') + + // Call the router again with the same input. + const result = await uut.router(str, 'peerA') + + assert.equal(result, false) + }) + + it('should ignore metric queries from ipfs-coord', async () => { + const id = uid() + const json = jsonrpc.request(id, 'unknownMethod', {}) + + const str = JSON.stringify(json) + + // Force the RPC type to be 'success', to indicate an RPC that was + // processed internal to ipfs-coord. + sandbox.stub(uut.jsonrpc, 'parse').returns({ + payload: {}, + type: 'success' + }) + + // Call the router again with the same input. + const result = await uut.router(str, 'peerA') + + assert.equal(result, false) + }) + + it('should report errors when trying to send messages to peers', async () => { + const id = uid() + const json = jsonrpc.request(id, 'unknownMethod', {}) + + const str = JSON.stringify(json) + + // Force issue with sendPrivateMessage() + sandbox + .stub(uut.ipfsCoord.useCases.peer, 'sendPrivateMessage') + .rejects('test error') + + // Call the router again with the same input. + const result = await uut.router(str, 'peerA') + // console.log('result: ', result) + + assert.property(result, 'from') + assert.property(result, 'retStr') + }) + }) + + describe('#_checkIfAlreadyProcessed', () => { + it('should return false the first time an RPC command is seen', () => { + const data = { + payload: { + jsonrpc: '2.0', + id: '6c515f3c-cf8a-42ec-870e-e416edd4923f', + method: 'unknownMethod', + params: {} + }, + type: 'request' + } + + const result = uut._checkIfAlreadyProcessed(data) + + assert.equal(result, false) + }) + + it('should return true the second time an RPC command is seen', () => { + const data = { + payload: { + jsonrpc: '2.0', + id: '6c515f3c-cf8a-42ec-870e-e416edd4923f', + method: 'unknownMethod', + params: {} + }, + type: 'request' + } + + // First call. + uut._checkIfAlreadyProcessed(data) + + // Second call. + const result = uut._checkIfAlreadyProcessed(data) + + assert.equal(result, true) + }) + + it('should push out old data from the cache for new data', () => { + const data = { + payload: { + jsonrpc: '2.0', + id: '6c515f3c-cf8a-42ec-870e-e416edd4923f', + method: 'unknownMethod', + params: {} + }, + type: 'request' + } + + uut.MSG_CACHE_SIZE = 0 + + const result = uut._checkIfAlreadyProcessed(data) + + assert.equal(result, false) + }) + + it('should return true on error', () => { + const result = uut._checkIfAlreadyProcessed() + + assert.equal(result, true) + }) }) }) diff --git a/test/unit/mocks/adapters/index.js b/test/unit/mocks/adapters/index.js index aa84c05..a236014 100644 --- a/test/unit/mocks/adapters/index.js +++ b/test/unit/mocks/adapters/index.js @@ -7,7 +7,13 @@ const ipfs = { ipfs: {} }, ipfsCoordAdapter: { - ipfsCoord: {} + ipfsCoord: { + useCases: { + peer: { + sendPrivateMessage: () => {} + } + } + } } }