jstests/replsets/awaitable_hello_errors_on_horizon_change.js
// runTest takes in the hello command or its aliases, isMaster and ismaster.
runTest takes in the hello command or its aliases, isMaster and ismaster.
runTest takes in the hello command or its aliases isMaster and ismaster .
function runTest(cmd) {
    const primaryFirstResponse = assert.commandWorked(primaryDB.runCommand({[cmd]: 1}));
    const primaryTopologyVersion = primaryFirstResponse.topologyVersion;
    const secondaryFirstResponse = assert.commandWorked(secondaryDB.runCommand({[cmd]: 1}));
    const secondaryTopologyVersion = secondaryFirstResponse.topologyVersion;
    let primaryFailPoint = configureFailPoint(primary, "waitForHelloResponse");
    let secondaryFailPoint = configureFailPoint(secondary, "waitForHelloResponse");
    const awaitCmdHorizonChangeOnPrimary = startParallelShell(
        funWithArgs(runAwaitableCmdBeforeHorizonChange, cmd, primaryTopologyVersion), primary.port);
    const awaitCmdHorizonChangeOnSecondary = startParallelShell(
        funWithArgs(runAwaitableCmdBeforeHorizonChange, cmd, secondaryTopologyVersion),
        secondary.port);
    primaryFailPoint.wait();
    secondaryFailPoint.wait();
    let numAwaitingTopologyChangeOnPrimary =
        primaryDB.serverStatus().connections.awaitingTopologyChanges;
    let numAwaitingTopologyChangeOnSecondary =
        secondaryDB.serverStatus().connections.awaitingTopologyChanges;
    assert.eq(1, numAwaitingTopologyChangeOnPrimary);
    assert.eq(1, numAwaitingTopologyChangeOnSecondary);
    let rsConfig = primary.getDB("local").system.replset.findOne();
    rsConfig.members.forEach(function(member) {
        member.horizons = {specialHorizon: 'horizon.com:100' + idx};
        idx++;
    });
    rsConfig.version++;
    jsTest.log('Calling replSetReconfig with config: ' + tojson(rsConfig));
    assert.commandWorked(primary.adminCommand({replSetReconfig: rsConfig}));
    awaitCmdHorizonChangeOnPrimary();
    awaitCmdHorizonChangeOnSecondary();
    numAwaitingTopologyChangeOnPrimary =
        primaryDB.serverStatus().connections.awaitingTopologyChanges;
    numAwaitingTopologyChangeOnSecondary =
        secondaryDB.serverStatus().connections.awaitingTopologyChanges;
    assert.eq(0, numAwaitingTopologyChangeOnPrimary);
    assert.eq(0, numAwaitingTopologyChangeOnSecondary);
    const primaryRespAfterHorizonChange = assert.commandWorked(primaryDB.runCommand({[cmd]: 1}));
    const secondaryRespAfterHorizonChange =
        assert.commandWorked(secondaryDB.runCommand({[cmd]: 1}));
    const primaryTopVersionAfterHorizonChange = primaryRespAfterHorizonChange.topologyVersion;
    const secondaryTopVersionAfterHorizonChange = secondaryRespAfterHorizonChange.topologyVersion;
    rsConfig = primary.getDB("local").system.replset.findOne();
    rsConfig.members.forEach(function(member) {
        if (member.host == primary.host) {
            member.tags = {dc: 'ny'};
        } else {
            member.tags = {dc: 'sf'};
        }
    });
    rsConfig.version++;
    primaryFailPoint = configureFailPoint(primary, "waitForHelloResponse");
    secondaryFailPoint = configureFailPoint(primary, "waitForHelloResponse");
    let primaryAwaitCmdBeforeAddingTags = startParallelShell(
        funWithArgs(runAwaitableCmd, cmd, primaryTopVersionAfterHorizonChange), primary.port);
    let secondaryAwaitCmdBeforeAddingTags = startParallelShell(
        funWithArgs(runAwaitableCmd, cmd, secondaryTopVersionAfterHorizonChange), secondary.port);
    primaryFailPoint.wait();
    secondaryFailPoint.wait();
    jsTest.log('Calling replSetReconfig with config: ' + tojson(rsConfig));
    assert.commandWorked(primary.adminCommand({replSetReconfig: rsConfig}));
    primaryAwaitCmdBeforeAddingTags();
    secondaryAwaitCmdBeforeAddingTags();
}
function runTest ( cmd ) { const primaryFirstResponse = assert . commandWorked ( primaryDB . runCommand ( { [ cmd ] : 1 } ) ) ; const primaryTopologyVersion = primaryFirstResponse . topologyVersion ; const secondaryFirstResponse = assert . commandWorked ( secondaryDB . runCommand ( { [ cmd ] : 1 } ) ) ; const secondaryTopologyVersion = secondaryFirstResponse . topologyVersion ; let primaryFailPoint = configureFailPoint ( primary , "waitForHelloResponse" ) ; let secondaryFailPoint = configureFailPoint ( secondary , "waitForHelloResponse" ) ; const awaitCmdHorizonChangeOnPrimary = startParallelShell ( funWithArgs ( runAwaitableCmdBeforeHorizonChange , cmd , primaryTopologyVersion ) , primary . port ) ; const awaitCmdHorizonChangeOnSecondary = startParallelShell ( funWithArgs ( runAwaitableCmdBeforeHorizonChange , cmd , secondaryTopologyVersion ) , secondary . port ) ; primaryFailPoint . wait ( ) ; secondaryFailPoint . wait ( ) ; let numAwaitingTopologyChangeOnPrimary = primaryDB . serverStatus ( ) . connections . awaitingTopologyChanges ; let numAwaitingTopologyChangeOnSecondary = secondaryDB . serverStatus ( ) . connections . awaitingTopologyChanges ; assert . eq ( 1 , numAwaitingTopologyChangeOnPrimary ) ; assert . eq ( 1 , numAwaitingTopologyChangeOnSecondary ) ; let rsConfig = primary . getDB ( "local" ) . system . replset . findOne ( ) ; rsConfig . members . forEach ( function ( member ) { member . horizons = { specialHorizon : 'horizon.com:100' + idx } ; idx ++ ; } ) ; rsConfig . version ++ ; jsTest . log ( 'Calling replSetReconfig with config: ' + tojson ( rsConfig ) ) ; assert . commandWorked ( primary . adminCommand ( { replSetReconfig : rsConfig } ) ) ; awaitCmdHorizonChangeOnPrimary ( ) ; awaitCmdHorizonChangeOnSecondary ( ) ; numAwaitingTopologyChangeOnPrimary = primaryDB . serverStatus ( ) . connections . awaitingTopologyChanges ; numAwaitingTopologyChangeOnSecondary = secondaryDB . serverStatus ( ) . connections . awaitingTopologyChanges ; assert . eq ( 0 , numAwaitingTopologyChangeOnPrimary ) ; assert . eq ( 0 , numAwaitingTopologyChangeOnSecondary ) ; const primaryRespAfterHorizonChange = assert . commandWorked ( primaryDB . runCommand ( { [ cmd ] : 1 } ) ) ; const secondaryRespAfterHorizonChange = assert . commandWorked ( secondaryDB . runCommand ( { [ cmd ] : 1 } ) ) ; const primaryTopVersionAfterHorizonChange = primaryRespAfterHorizonChange . topologyVersion ; const secondaryTopVersionAfterHorizonChange = secondaryRespAfterHorizonChange . topologyVersion ; rsConfig = primary . getDB ( "local" ) . system . replset . findOne ( ) ; rsConfig . members . forEach ( function ( member ) { if ( member . host == primary . host ) { member . tags = { dc : 'ny' } ; } else { member . tags = { dc : 'sf' } ; } } ) ; rsConfig . version ++ ; primaryFailPoint = configureFailPoint ( primary , "waitForHelloResponse" ) ; secondaryFailPoint = configureFailPoint ( primary , "waitForHelloResponse" ) ; let primaryAwaitCmdBeforeAddingTags = startParallelShell ( funWithArgs ( runAwaitableCmd , cmd , primaryTopVersionAfterHorizonChange ) , primary . port ) ; let secondaryAwaitCmdBeforeAddingTags = startParallelShell ( funWithArgs ( runAwaitableCmd , cmd , secondaryTopVersionAfterHorizonChange ) , secondary . port ) ; primaryFailPoint . wait ( ) ; secondaryFailPoint . wait ( ) ; jsTest . log ( 'Calling replSetReconfig with config: ' + tojson ( rsConfig ) ) ; assert . commandWorked ( primary . adminCommand ( { replSetReconfig : rsConfig } ) ) ; primaryAwaitCmdBeforeAddingTags ( ) ; secondaryAwaitCmdBeforeAddingTags ( ) ; }
runTest takes in the hello command or its aliases, isMaster and ismaster.
runTest takes in the hello command or its aliases isMaster and ismaster .
// A failpoint signalling that the server has received the hello/isMaster request and is waiting // for a topology change. // Send an awaitable hello/isMaster request. This will block until there is a topology change. // Each node has one hello/isMaster request waiting on a topology change. // Doing a reconfig that changes the horizon should respond to all waiting hello/isMaster // requests with an error. // All hello/isMaster requests should have been responded to after the reconfig. // Doing a reconfig that doesn't change the horizon should increment the topologyVersion and // reply to waiting hello/isMaster requests with a successful response. // Reconfigure the failpoint to refresh the number of times the failpoint has been entered. // Send an awaitable hello/isMaster request. This will block until maxAwaitTimeMS has elapsed or // a topology change happens.