Skip to content

Commit

Permalink
Test stateMachineUtils and CNodeToSpIdMapManager (#3162)
Browse files Browse the repository at this point in the history
  • Loading branch information
theoilie authored May 27, 2022
1 parent 424a7c6 commit fd4b3b6
Show file tree
Hide file tree
Showing 13 changed files with 357 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}`)
}

/**
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -282,4 +284,4 @@ class NodeHealthManager {
}
}

module.exports = new NodeHealthManager()
module.exports = new CNodeHealthManager()
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion creator-node/src/services/stateMachineManager/index.js
Original file line number Diff line number Diff line change
@@ -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')

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
115 changes: 115 additions & 0 deletions creator-node/test/CNodeToSpIdMapManager.test.js
Original file line number Diff line number Diff line change
@@ -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)
})
})
4 changes: 4 additions & 0 deletions creator-node/test/StateMonitoringQueue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})

Expand Down Expand Up @@ -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()
})

Expand Down
11 changes: 11 additions & 0 deletions creator-node/test/peerSetManager.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -61,6 +62,7 @@ describe('test peerSetManager -- determinePeerHealth', () => {

afterEach(() => {
nock.cleanAll()
nock.enableNetConnect()
})

it('should throw error if storage path vars are improper', () => {
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions creator-node/test/processStateMonitoringJob.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -133,8 +133,8 @@ describe('test processStateMonitoringJob', function () {
aggregateReconfigAndPotentialSyncOps:
aggregateReconfigAndPotentialSyncOpsStub
},
'../nodeHealthManager': NodeHealthManager,
'../cNodeToSpIdMapManager': CNodeToSpIdMapManager,
'../CNodeHealthManager': NodeHealthManager,
'../CNodeToSpIdMapManager': CNodeToSpIdMapManager,
'../stateMachineUtils': {
retrieveClockStatusesForUsersAcrossReplicaSet:
retrieveClockStatusesForUsersAcrossReplicaSetStub
Expand Down
2 changes: 2 additions & 0 deletions creator-node/test/snapbackSM.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down
Loading

0 comments on commit fd4b3b6

Please sign in to comment.