mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 01:21:03 +01:00
71 lines
2.9 KiB
JavaScript
71 lines
2.9 KiB
JavaScript
/**
|
|
* Tests that DBClientRS doesn't do any re-targeting on replica set member state changes until it
|
|
* sees a "not master" error response from a command.
|
|
* @tags: [requires_replication]
|
|
*/
|
|
(function() {
|
|
"use strict";
|
|
|
|
const rst = new ReplSetTest({nodes: 1});
|
|
rst.startSet();
|
|
rst.initiate();
|
|
|
|
const directConn = rst.getPrimary();
|
|
const rsConn = new Mongo(rst.getURL());
|
|
assert(rsConn.isReplicaSetConnection(),
|
|
"expected " + rsConn.host + " to be a replica set connection string");
|
|
|
|
function stepDownPrimary(rst) {
|
|
const awaitShell = startParallelShell(
|
|
() => assert.commandWorked(db.adminCommand({replSetStepDown: 60, force: true})),
|
|
directConn.port);
|
|
|
|
// We wait for the primary to transition to the SECONDARY state to ensure we're waiting
|
|
// until after the parallel shell has started the replSetStepDown command and the server is
|
|
// paused at the failpoint. Do not attempt to reconnect to the node, since the node will be
|
|
// holding the global X lock at the failpoint.
|
|
const reconnectNode = false;
|
|
rst.waitForState(directConn, ReplSetTest.State.SECONDARY, null, reconnectNode);
|
|
|
|
return awaitShell;
|
|
}
|
|
|
|
const failpoint = "stepdownHangBeforePerformingPostMemberStateUpdateActions";
|
|
assert.commandWorked(
|
|
directConn.adminCommand({configureFailPoint: failpoint, mode: "alwaysOn"}));
|
|
|
|
const awaitShell = stepDownPrimary(rst);
|
|
|
|
const error = assert.throws(function() {
|
|
// DBClientRS will continue to send command requests to the node it believed to be primary
|
|
// even after it stepped down so long as it hasn't closed its connection. But this may also
|
|
// throw if the ReplicaSetMonitor's backgroud refresh has already noticed that this node is
|
|
// no longer primary.
|
|
assert.commandFailedWithCode(rsConn.getDB("test").runCommand({find: "mycoll"}),
|
|
ErrorCodes.NotMasterNoSlaveOk);
|
|
|
|
// However, once the server responds back with a "not master" error, DBClientRS will cause
|
|
// the ReplicaSetMonitor to attempt to discover the current primary, which will cause this
|
|
// to definitely throw.
|
|
rsConn.getDB("test").runCommand({find: "mycoll"});
|
|
});
|
|
assert(/Could not find host/.test(error.toString()),
|
|
"find command failed for a reason other than being unable to discover a new primary: " +
|
|
tojson(error));
|
|
|
|
try {
|
|
assert.commandWorked(directConn.adminCommand({configureFailPoint: failpoint, mode: "off"}));
|
|
} catch (e) {
|
|
if (!isNetworkError(e)) {
|
|
throw e;
|
|
}
|
|
|
|
// We ignore network errors because it's possible that depending on how quickly the server
|
|
// closes connections that the connection would get closed before the server has a chance to
|
|
// respond to the configureFailPoint command with ok=1.
|
|
}
|
|
|
|
awaitShell();
|
|
rst.stopSet();
|
|
})();
|