From fd4b3b6ce9c49aeb9f48b918600a6c44dc92df2d Mon Sep 17 00:00:00 2001 From: Theo Ilie Date: Thu, 26 May 2022 18:01:46 -0700 Subject: [PATCH] Test stateMachineUtils and CNodeToSpIdMapManager (#3162) --- ...HealthManager.js => CNodeHealthManager.js} | 12 +- ...MapManager.js => CNodeToSpIdMapManager.js} | 2 +- .../src/services/stateMachineManager/index.js | 2 +- .../stateMachineManager/stateMachineUtils.js | 2 +- .../processStateMonitoringJob.js | 4 +- .../stateMonitoring/stateMonitoringUtils.js | 2 +- .../test/CNodeToSpIdMapManager.test.js | 115 +++++++++++ .../test/StateMonitoringQueue.test.js | 4 + creator-node/test/peerSetManager.test.js | 11 ++ .../test/processStateMonitoringJob.test.js | 8 +- creator-node/test/snapbackSM.test.js | 2 + creator-node/test/stateMachineUtils.test.js | 185 ++++++++++++++++++ .../test/stateMonitoringUtils.test.js | 34 ++-- 13 files changed, 357 insertions(+), 26 deletions(-) rename creator-node/src/services/stateMachineManager/{nodeHealthManager.js => CNodeHealthManager.js} (97%) rename creator-node/src/services/stateMachineManager/{cNodeToSpIdMapManager.js => CNodeToSpIdMapManager.js} (95%) create mode 100644 creator-node/test/CNodeToSpIdMapManager.test.js create mode 100644 creator-node/test/stateMachineUtils.test.js diff --git a/creator-node/src/services/stateMachineManager/nodeHealthManager.js b/creator-node/src/services/stateMachineManager/CNodeHealthManager.js similarity index 97% rename from creator-node/src/services/stateMachineManager/nodeHealthManager.js rename to creator-node/src/services/stateMachineManager/CNodeHealthManager.js index bdf189cd6d0..2872b5a320f 100644 --- a/creator-node/src/services/stateMachineManager/nodeHealthManager.js +++ b/creator-node/src/services/stateMachineManager/CNodeHealthManager.js @@ -24,7 +24,7 @@ const MAX_NUMBER_SECONDS_PRIMARY_REMAINS_UNHEALTHY = config.get( * Tracks and caches health of Content Nodes. * TODO: Add caching for secondaries similar to how primaries have a threshold of time to remain unhealthy for. */ -class NodeHealthManager { +class CNodeHealthManager { constructor() { /* We do not want to eagerly cycle off the primary when issuing reconfigs if necessary, as the primary may have data that the secondaries lack. This map is used to track the primary and the number of times it has @@ -39,11 +39,11 @@ class NodeHealthManager { } log(msg) { - logger.info(`NodeHealthManager: ${msg}`) + logger.info(`CNodeHealthManager: ${msg}`) } logError(msg) { - logger.error(`NodeHealthManager ERROR: ${msg}`) + logger.error(`CNodeHealthManager ERROR: ${msg}`) } /** @@ -91,7 +91,9 @@ class NodeHealthManager { this.determinePeerHealth(verboseHealthCheckResp) } } catch (e) { - this.logError(`isNodeHealthy peer=${peer} is unhealthy: ${e.toString()}`) + this.logError( + `isNodeHealthy() peer=${peer} is unhealthy: ${e.toString()}` + ) return false } @@ -282,4 +284,4 @@ class NodeHealthManager { } } -module.exports = new NodeHealthManager() +module.exports = new CNodeHealthManager() diff --git a/creator-node/src/services/stateMachineManager/cNodeToSpIdMapManager.js b/creator-node/src/services/stateMachineManager/CNodeToSpIdMapManager.js similarity index 95% rename from creator-node/src/services/stateMachineManager/cNodeToSpIdMapManager.js rename to creator-node/src/services/stateMachineManager/CNodeToSpIdMapManager.js index 90176dadfb1..91a29862c92 100644 --- a/creator-node/src/services/stateMachineManager/cNodeToSpIdMapManager.js +++ b/creator-node/src/services/stateMachineManager/CNodeToSpIdMapManager.js @@ -39,7 +39,7 @@ class CNodeToSpIdMapManager { const mapLength = Object.keys(this.cNodeEndpointToSpIdMap).length if (mapLength === 0) { const errorMessage = - 'updateCnodeEndpointToSpIdMap Unable to initialize cNodeEndpointToSpIdMap' + 'updateCnodeEndpointToSpIdMap() Unable to initialize cNodeEndpointToSpIdMap' logger.error(errorMessage) throw new Error(errorMessage) } diff --git a/creator-node/src/services/stateMachineManager/index.js b/creator-node/src/services/stateMachineManager/index.js index 330daf1f0e8..7a6a8b48aff 100644 --- a/creator-node/src/services/stateMachineManager/index.js +++ b/creator-node/src/services/stateMachineManager/index.js @@ -1,7 +1,7 @@ const config = require('../../config') const { logger } = require('../../logging') const StateMonitoringQueue = require('./stateMonitoring/StateMonitoringQueue') -const NodeToSpIdManager = require('./cNodeToSpIdMapManager') +const NodeToSpIdManager = require('./CNodeToSpIdMapManager') const { RECONFIG_MODES } = require('./stateMachineConstants') /** diff --git a/creator-node/src/services/stateMachineManager/stateMachineUtils.js b/creator-node/src/services/stateMachineManager/stateMachineUtils.js index 8e10be51f7b..a8f327dee6c 100644 --- a/creator-node/src/services/stateMachineManager/stateMachineUtils.js +++ b/creator-node/src/services/stateMachineManager/stateMachineUtils.js @@ -79,7 +79,7 @@ const retrieveClockStatusesForUsersAcrossReplicaSet = async ( // If failed to get response after all attempts, add replica to `unhealthyPeers` set for reconfig if (errorMsg) { logger.error( - `retrieveClockStatusesForUsersAcrossReplicaSet Could not fetch clock values for wallets=${walletsOnReplica} on replica=${replica} ${errorMsg.toString()}` + `retrieveClockStatusesForUsersAcrossReplicaSet() Could not fetch clock values for wallets=${walletsOnReplica} on replica=${replica} ${errorMsg.toString()}` ) unhealthyPeers.add(replica) } diff --git a/creator-node/src/services/stateMachineManager/stateMonitoring/processStateMonitoringJob.js b/creator-node/src/services/stateMachineManager/stateMonitoring/processStateMonitoringJob.js index 1ccfaf14566..30c3ca4bbdf 100644 --- a/creator-node/src/services/stateMachineManager/stateMonitoring/processStateMonitoringJob.js +++ b/creator-node/src/services/stateMachineManager/stateMonitoring/processStateMonitoringJob.js @@ -1,7 +1,7 @@ const config = require('../../../config') const { logger } = require('../../../logging') -const NodeHealthManager = require('../nodeHealthManager') -const NodeToSpIdManager = require('../cNodeToSpIdMapManager') +const NodeHealthManager = require('../CNodeHealthManager') +const NodeToSpIdManager = require('../CNodeToSpIdMapManager') const { getNodeUsers, buildReplicaSetNodesToUserWalletsMap, diff --git a/creator-node/src/services/stateMachineManager/stateMonitoring/stateMonitoringUtils.js b/creator-node/src/services/stateMachineManager/stateMonitoring/stateMonitoringUtils.js index e10d9361aa7..a6dabb7c760 100644 --- a/creator-node/src/services/stateMachineManager/stateMonitoring/stateMonitoringUtils.js +++ b/creator-node/src/services/stateMachineManager/stateMonitoring/stateMonitoringUtils.js @@ -4,7 +4,7 @@ const { CancelToken } = axios const config = require('../../../config') const Utils = require('../../../utils') -const { isPrimaryHealthy } = require('../nodeHealthManager') +const { isPrimaryHealthy } = require('../CNodeHealthManager') const { logger } = require('../../../logging') const SecondarySyncHealthTracker = require('../../../snapbackSM/secondarySyncHealthTracker') const { diff --git a/creator-node/test/CNodeToSpIdMapManager.test.js b/creator-node/test/CNodeToSpIdMapManager.test.js new file mode 100644 index 00000000000..54061d7e25f --- /dev/null +++ b/creator-node/test/CNodeToSpIdMapManager.test.js @@ -0,0 +1,115 @@ +const chai = require('chai') +const sinon = require('sinon') +const { expect } = chai +chai.use(require('sinon-chai')) +chai.use(require('chai-as-promised')) + +const CNodeToSpIdMapManager = require('../src/services/stateMachineManager/CNodeToSpIdMapManager') + +describe('test CNodeToSpIdMapManager', function () { + let sandbox + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + + afterEach(function () { + sandbox.restore() + }) + + it('replaces existing mapping when ethContracts is successful', async function () { + // Set the existing/old mapping that should later be replaced + CNodeToSpIdMapManager.cNodeEndpointToSpIdMap = { + 'http://old_cn1.co': 'oldSpId' + } + + // Create content nodes that will be used to make new mapping + const contentNodes = [ + { + endpoint: 'http://cn1.co', + spID: 1 + }, + { + endpoint: 'http://cn5.co', + spID: 100 + } + ] + const expectedNewMapping = { + 'http://cn1.co': 1, + 'http://cn5.co': 100 + } + + // Mock ethContracts to return the content nodes that will be used to build the new mapping + const getServiceProviderListStub = sandbox.stub().resolves(contentNodes) + const ethContracts = { + getServiceProviderList: getServiceProviderListStub + } + + // Verify that CNodeToSpIdMapManager's mapping is set to the new mapping + await CNodeToSpIdMapManager.updateCnodeEndpointToSpIdMap(ethContracts) + expect(CNodeToSpIdMapManager.getCNodeEndpointToSpIdMap()).to.deep.equal( + expectedNewMapping + ) + }) + + it("doesn't replace existing mapping when new mapping is empty", async function () { + // Set the existing mapping that should NOT be replaced later + const originalCNodeEndpointToSpIdMap = { + 'http://old_cn1.co': 'oldSpId' + } + CNodeToSpIdMapManager.cNodeEndpointToSpIdMap = + originalCNodeEndpointToSpIdMap + + // Mock ethContracts to return an empty array of content nodes + const getServiceProviderListStub = sandbox.stub().resolves([]) + const ethContracts = { + getServiceProviderList: getServiceProviderListStub + } + + // Verify that CNodeToSpIdMapManager's mapping was NOT replaced with the empty mapping + await CNodeToSpIdMapManager.updateCnodeEndpointToSpIdMap(ethContracts) + expect(CNodeToSpIdMapManager.getCNodeEndpointToSpIdMap()).to.deep.equal( + originalCNodeEndpointToSpIdMap + ) + }) + + it("doesn't replace existing mapping when ethContracts throws", async function () { + // Set the existing mapping that should NOT be replaced later + const originalCNodeEndpointToSpIdMap = { + 'http://old_cn1.co': 'oldSpId' + } + CNodeToSpIdMapManager.cNodeEndpointToSpIdMap = + originalCNodeEndpointToSpIdMap + + // Mock ethContracts to return an empty array of content nodes + const getServiceProviderListStub = sandbox.stub().rejects() + const ethContracts = { + getServiceProviderList: getServiceProviderListStub + } + + // Verify that CNodeToSpIdMapManager's mapping is set to the new mapping + await CNodeToSpIdMapManager.updateCnodeEndpointToSpIdMap(ethContracts) + expect(CNodeToSpIdMapManager.getCNodeEndpointToSpIdMap()).to.deep.equal( + originalCNodeEndpointToSpIdMap + ) + }) + + it('throws when the existing and new mapping are both empty', async function () { + // Set the existing mapping that should NOT be replaced later + CNodeToSpIdMapManager.cNodeEndpointToSpIdMap = {} + + // Mock ethContracts to return an empty array of content nodes + const getServiceProviderListStub = sandbox.stub().resolves([]) + const ethContracts = { + getServiceProviderList: getServiceProviderListStub + } + + // Verify that CNodeToSpIdMapManager throws because its mapping is empty + return expect( + CNodeToSpIdMapManager.updateCnodeEndpointToSpIdMap(ethContracts) + ) + .to.eventually.be.rejectedWith( + 'updateCnodeEndpointToSpIdMap() Unable to initialize cNodeEndpointToSpIdMap' + ) + .and.be.an.instanceOf(Error) + }) +}) diff --git a/creator-node/test/StateMonitoringQueue.test.js b/creator-node/test/StateMonitoringQueue.test.js index 3a5376749b8..bd33368597e 100644 --- a/creator-node/test/StateMonitoringQueue.test.js +++ b/creator-node/test/StateMonitoringQueue.test.js @@ -25,11 +25,13 @@ describe('test StateMonitoringQueue initialization and logging', function () { sandbox = sinon.createSandbox() config.set('spID', 1) + nock.disableNetConnect() }) afterEach(async function () { await server.close() nock.cleanAll() + nock.enableNetConnect() sandbox.restore() }) @@ -143,11 +145,13 @@ describe('test StateMonitoringQueue re-enqueuing', function () { sandbox = sinon.createSandbox() config.set('spID', 1) + nock.disableNetConnect() }) afterEach(async function () { await server.close() nock.cleanAll() + nock.enableNetConnect() sandbox.restore() }) diff --git a/creator-node/test/peerSetManager.test.js b/creator-node/test/peerSetManager.test.js index 1263f1c2e85..e36bc80a3d8 100644 --- a/creator-node/test/peerSetManager.test.js +++ b/creator-node/test/peerSetManager.test.js @@ -53,6 +53,7 @@ describe('test peerSetManager -- determinePeerHealth', () => { } beforeEach(() => { + nock.disableNetConnect() peerSetManager = new PeerSetManager({ discoveryProviderEndpoint: 'https://discovery_endpoint.audius.co', creatorNodeEndpoint: 'https://content_node_endpoint.audius.co' @@ -61,6 +62,7 @@ describe('test peerSetManager -- determinePeerHealth', () => { afterEach(() => { nock.cleanAll() + nock.enableNetConnect() }) it('should throw error if storage path vars are improper', () => { @@ -299,6 +301,15 @@ describe('test peerSetManager -- getNodeUsers', () => { }) }) + beforeEach(() => { + nock.disableNetConnect() + }) + + afterEach(() => { + nock.cleanAll() + nock.enableNetConnect() + }) + it('uses correct params for axios request when not given pagination params', async () => { const GET_NODE_USERS_TIMEOUT_MS = 100 const GET_NODE_USERS_CANCEL_TOKEN_MS = 5_000 diff --git a/creator-node/test/processStateMonitoringJob.test.js b/creator-node/test/processStateMonitoringJob.test.js index d363554be67..42ae19cb05c 100644 --- a/creator-node/test/processStateMonitoringJob.test.js +++ b/creator-node/test/processStateMonitoringJob.test.js @@ -10,8 +10,8 @@ const _ = require('lodash') const config = require('../src/config') const { getApp } = require('./lib/app') const { getLibsMock } = require('./lib/libsMock') -const NodeHealthManager = require('../src/services/stateMachineManager/nodeHealthManager') -const CNodeToSpIdMapManager = require('../src/services/stateMachineManager/cNodeToSpIdMapManager') +const NodeHealthManager = require('../src/services/stateMachineManager/CNodeHealthManager') +const CNodeToSpIdMapManager = require('../src/services/stateMachineManager/CNodeToSpIdMapManager') describe('test processStateMonitoringJob', function () { let server, @@ -133,8 +133,8 @@ describe('test processStateMonitoringJob', function () { aggregateReconfigAndPotentialSyncOps: aggregateReconfigAndPotentialSyncOpsStub }, - '../nodeHealthManager': NodeHealthManager, - '../cNodeToSpIdMapManager': CNodeToSpIdMapManager, + '../CNodeHealthManager': NodeHealthManager, + '../CNodeToSpIdMapManager': CNodeToSpIdMapManager, '../stateMachineUtils': { retrieveClockStatusesForUsersAcrossReplicaSet: retrieveClockStatusesForUsersAcrossReplicaSetStub diff --git a/creator-node/test/snapbackSM.test.js b/creator-node/test/snapbackSM.test.js index ba21c1010d2..07bf485a482 100644 --- a/creator-node/test/snapbackSM.test.js +++ b/creator-node/test/snapbackSM.test.js @@ -83,11 +83,13 @@ describe('test SnapbackSM -- determineNewReplicaSet, sync queue, and reconfig mo await app.get('redisClient').flushdb() nodeConfig.set('spID', 1) + nock.disableNetConnect() }) afterEach(async function () { await server.close() nock.cleanAll() + nock.enableNetConnect() }) it('Manual and recurring syncs are processed correctly', async function () { diff --git a/creator-node/test/stateMachineUtils.test.js b/creator-node/test/stateMachineUtils.test.js new file mode 100644 index 00000000000..93a87a3e4f5 --- /dev/null +++ b/creator-node/test/stateMachineUtils.test.js @@ -0,0 +1,185 @@ +/* eslint-disable no-unused-expressions */ +const nock = require('nock') +const chai = require('chai') +const sinon = require('sinon') +const { expect } = chai +chai.use(require('sinon-chai')) +chai.use(require('chai-as-promised')) +const proxyquire = require('proxyquire') + +const config = require('../src/config') + +describe('test retrieveClockStatusesForUsersAcrossReplicaSet()', function () { + beforeEach(function () { + nock.disableNetConnect() + }) + + afterEach(function () { + nock.cleanAll() + nock.enableNetConnect() + }) + + it('returns expected clock values and updates unhealthyPeers', async function () { + const healthyCn1 = 'http://healthyCn1.co' + const healthyCn2 = 'http://healthyCn2.co' + const unhealthyCn = 'http://unhealthyCn.co' + const replicasToWalletsMap = { + [healthyCn1]: ['wallet1', 'wallet2', 'wallet3', 'wallet4', 'wallet5'], + [healthyCn2]: ['wallet1', 'wallet2'], + [unhealthyCn]: ['wallet1', 'wallet2'] + } + const expectedReplicaToClockValueMap = { + [healthyCn1]: { + wallet1: 1, + wallet2: 2, + wallet3: 3, + wallet4: 4, + wallet5: 5 + }, + [healthyCn2]: { + wallet1: 10, + wallet2: 20 + }, + [unhealthyCn]: {} + } + + // Mock the axios requests for healthy Content Nodes to return clock values + nock(healthyCn1) + .post('/users/batch_clock_status') + .query(true) // Match any query because we don't care about signature, timestamp, and spID + .times(3) // 3 times because there are 5 wallets and the batch size is 2 wallets per request + .reply(200, function (uri, requestBody) { + const { walletPublicKeys } = requestBody + console.log(`cn1 walletPublicKeys: ${walletPublicKeys}`) + console.log( + `returning ${JSON.stringify( + walletPublicKeys.map((wallet) => { + return { + wallet, + clock: expectedReplicaToClockValueMap[healthyCn1][wallet] + } + }) + )}` + ) + return { + data: { + users: walletPublicKeys.map((wallet) => { + return { + walletPublicKey: wallet, + clock: expectedReplicaToClockValueMap[healthyCn1][wallet] + } + }) + } + } + }) + nock(healthyCn2) + .post('/users/batch_clock_status') + .query(true) // Match any query because we don't care about signature, timestamp, and spID + .reply(200, function (uri, requestBody) { + const { walletPublicKeys } = requestBody + return { + data: { + users: walletPublicKeys.map((wallet) => { + return { + walletPublicKey: wallet, + clock: expectedReplicaToClockValueMap[healthyCn2][wallet] + } + }) + } + } + }) + + // Mock the axios request to the unhealthy Content Node to return an error + nock(unhealthyCn) + .post('/users/batch_clock_status') + .query(true) // Match any because we don't care about signature, timestamp, and spID + .times(2) // It retries the failure once + .reply(500) + + // Mock retrieveClockStatusesForUsersAcrossReplicaSet to have our desired config and constants + config.set('maxBatchClockStatusBatchSize', 2) + const { retrieveClockStatusesForUsersAcrossReplicaSet } = proxyquire( + '../src/services/stateMachineManager/stateMachineUtils.js', + { + '../../config': config, + './stateMachineConstants': { + MAX_USER_BATCH_CLOCK_FETCH_RETRIES: 1, + BATCH_CLOCK_STATUS_REQUEST_TIMEOUT: 1000 + } + } + ) + + const { replicasToUserClockStatusMap, unhealthyPeers } = + await retrieveClockStatusesForUsersAcrossReplicaSet(replicasToWalletsMap) + + // Verify that all mocked endpoints were been hit the expected number of times + expect(nock.isDone()).to.be.true + + // Verify that each wallet had the expected clock value and the unhealthy node was marked as unhealthy + expect(Object.keys(replicasToUserClockStatusMap)).to.have.lengthOf(3) + expect(replicasToUserClockStatusMap).to.deep.equal( + expectedReplicaToClockValueMap + ) + expect(unhealthyPeers).to.have.property('size', 1) + expect(unhealthyPeers).to.include('http://unhealthyCn.co') + }) +}) + +describe('test retrieveClockValueForUserFromReplica()', function () { + let sandbox + beforeEach(function () { + sandbox = sinon.createSandbox() + }) + + afterEach(function () { + sandbox.restore() + }) + + it('returns expected clock value when successful', async function () { + const replica = 'http://healthyCn.co' + const wallet = '0x123456789' + + // Get stubbed function with a CreatorNode dependency that returns a dummy clock value + const expectedClockValue = 12345 + const getClockValueStub = sandbox.stub().resolves(expectedClockValue) + const { retrieveClockValueForUserFromReplica } = proxyquire( + '../src/services/stateMachineManager/stateMachineUtils.js', + { + '@audius/libs': { + CreatorNode: { + getClockValue: getClockValueStub + } + } + } + ) + + // Verify that the function returns the dummy clock value + return expect( + retrieveClockValueForUserFromReplica(replica, wallet) + ).to.eventually.be.fulfilled.and.to.equal(expectedClockValue) + }) + + it('throws when CreatorNode throws', async function () { + const replica = 'http://healthyCn.co' + const wallet = '0x123456789' + + // Get stubbed function with a CreatorNode dependency that returns a dummy clock value + const expectedError = new Error('test error') + const getClockValueStub = sandbox.stub().rejects(expectedError) + const { retrieveClockValueForUserFromReplica } = proxyquire( + '../src/services/stateMachineManager/stateMachineUtils.js', + { + '@audius/libs': { + CreatorNode: { + getClockValue: getClockValueStub + } + } + } + ) + + // Verify that the function returns the dummy clock value + return expect( + retrieveClockValueForUserFromReplica(replica, wallet) + ).to.eventually.be.rejectedWith(expectedError) + }) +}) diff --git a/creator-node/test/stateMonitoringUtils.test.js b/creator-node/test/stateMonitoringUtils.test.js index d2cd32723f8..fe688a112b8 100644 --- a/creator-node/test/stateMonitoringUtils.test.js +++ b/creator-node/test/stateMonitoringUtils.test.js @@ -23,11 +23,15 @@ const { } = require('../src/services/stateMachineManager/stateMachineConstants') const SecondarySyncHealthTracker = require('../src/snapbackSM/secondarySyncHealthTracker') -describe('test getLatestUserIdFromDiscovery', function () { +describe('test getLatestUserIdFromDiscovery()', function () { const DISCOVERY_NODE_ENDPOINT = 'https://discovery_endpoint.audius.co' + beforeEach(() => { + nock.disableNetConnect() + }) afterEach(() => { nock.cleanAll() + nock.enableNetConnect() }) it('returns correct value from discovery endpoint param', async function () { @@ -55,7 +59,7 @@ describe('test getLatestUserIdFromDiscovery', function () { }) }) -describe('test getNodeUsers', function () { +describe('test getNodeUsers()', function () { const DISCOVERY_NODE_ENDPOINT = 'https://discovery_endpoint.audius.co' const CONTENT_NODE_ENDPOINT = 'https://content_node_endpoint.audius.co' const DEFAULT_GET_NODE_USERS_TIMEOUT_MS = 100 @@ -96,8 +100,16 @@ describe('test getNodeUsers', function () { return getNodeUsers } + let sandbox + beforeEach(() => { + sandbox = sinon.createSandbox() + nock.disableNetConnect() + }) + afterEach(() => { + sandbox.restore() nock.cleanAll() + nock.enableNetConnect() }) it('uses correct params for axios request when not given pagination params', async function () { @@ -108,8 +120,8 @@ describe('test getNodeUsers', function () { return { data: { data: users } } } - const cancelTokenSourceMock = sinon.mock(CancelToken.source()) - const cancelTokenCancelFunc = sinon.stub() + const cancelTokenSourceMock = sandbox.mock(CancelToken.source()) + const cancelTokenCancelFunc = sandbox.stub() cancelTokenSourceMock.cancel = cancelTokenCancelFunc const cancelTokenStub = { source: () => cancelTokenSourceMock } axiosStub.CancelToken = cancelTokenStub @@ -142,8 +154,8 @@ describe('test getNodeUsers', function () { return { data: { data: users } } } - const cancelTokenSourceMock = sinon.mock(CancelToken.source()) - const cancelTokenCancelFunc = sinon.stub() + const cancelTokenSourceMock = sandbox.mock(CancelToken.source()) + const cancelTokenCancelFunc = sandbox.stub() cancelTokenSourceMock.cancel = cancelTokenCancelFunc const cancelTokenStub = { source: () => cancelTokenSourceMock } axiosStub.CancelToken = cancelTokenStub @@ -210,8 +222,8 @@ describe('test getNodeUsers', function () { return { data: { data: users } } } - const cancelTokenSourceMock = sinon.mock(CancelToken.source()) - const cancelTokenCancelFunc = sinon.stub() + const cancelTokenSourceMock = sandbox.mock(CancelToken.source()) + const cancelTokenCancelFunc = sandbox.stub() cancelTokenSourceMock.cancel = cancelTokenCancelFunc const cancelTokenStub = { source: () => cancelTokenSourceMock } axiosStub.CancelToken = cancelTokenStub @@ -284,7 +296,7 @@ describe('test getNodeUsers', function () { }) }) -describe('test buildReplicaSetNodesToUserWalletsMap', function () { +describe('test buildReplicaSetNodesToUserWalletsMap()', function () { it('', function () { const nodeUsersInput = [ { @@ -329,7 +341,7 @@ describe('test buildReplicaSetNodesToUserWalletsMap', function () { }) }) -describe('test computeUserSecondarySyncSuccessRatesMap', function () { +describe('test computeUserSecondarySyncSuccessRatesMap()', function () { let server beforeEach(async function () { const appInfo = await getApp(getLibsMock()) @@ -428,7 +440,7 @@ describe('test computeUserSecondarySyncSuccessRatesMap', function () { }) }) -describe('test aggregateReconfigAndPotentialSyncOps', function () { +describe('test aggregateReconfigAndPotentialSyncOps()', function () { let server beforeEach(async function () {