diff options
author | Pavi Vetriselvan <pavithra.vetriselvan@mongodb.com> | 2020-11-17 15:35:15 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-11-19 16:40:05 +0000 |
commit | d633efa72090a864442ef7232e1261d3b25bc27c (patch) | |
tree | ae59ded6b61efb30e74c284baf093a3e48f11604 /jstests | |
parent | fd5f9c3fb195b78f59b7abcfc7a81318f9a5ee78 (diff) | |
download | mongo-d633efa72090a864442ef7232e1261d3b25bc27c.tar.gz |
SERVER-50414 Reads should return not primary error messages during rollback if client sent helloOk
Diffstat (limited to 'jstests')
-rw-r--r-- | jstests/concurrency/fsm_libs/cluster.js | 2 | ||||
-rw-r--r-- | jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js | 76 |
2 files changed, 77 insertions, 1 deletions
diff --git a/jstests/concurrency/fsm_libs/cluster.js b/jstests/concurrency/fsm_libs/cluster.js index b33f5f465c4..0689938a823 100644 --- a/jstests/concurrency/fsm_libs/cluster.js +++ b/jstests/concurrency/fsm_libs/cluster.js @@ -511,7 +511,7 @@ var Cluster = function(options) { res.databases.forEach(dbInfo => { // Don't perform listCollections on the admin or config database through a mongos // connection when stepping down the config server primary, because both are stored - // on the config server, and listCollections may return a not master error if the + // on the config server, and listCollections may return a NotPrimaryError if the // mongos is stale. // // TODO SERVER-30949: listCollections through mongos should automatically retry on diff --git a/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js b/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js new file mode 100644 index 00000000000..48fd2a88847 --- /dev/null +++ b/jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js @@ -0,0 +1,76 @@ +/* + * Tests that reads that fail during rollback with a NotPrimaryError will replace their + * "not master" error messages with "not primary" if the client sends "helloOk:true" as a part + * of their isMaster request. + * + * In practice, drivers will send "helloOk: true" in the initial handshake when + * opening a connection to the database. + * @tags: [requires_majority_read_concern] + */ + +(function() { +"use strict"; + +load("jstests/replsets/libs/rollback_test.js"); +load("jstests/replsets/rslib.js"); + +const dbName = "test"; +const collName = "not_primary_errors_returned_during_rollback_if_helloOk"; + +// Set up Rollback Test. +let rollbackTest = new RollbackTest(); + +// Insert a document to be read later. +assert.commandWorked(rollbackTest.getPrimary().getDB(dbName)[collName].insert({})); + +let rollbackNode = rollbackTest.transitionToRollbackOperations(); + +setFailPoint(rollbackNode, "rollbackHangAfterTransitionToRollback"); + +// Start rollback. +rollbackTest.transitionToSyncSourceOperationsBeforeRollback(); +rollbackTest.transitionToSyncSourceOperationsDuringRollback(); + +jsTestLog("Reconnecting to " + rollbackNode.host + " after rollback"); +reconnect(rollbackNode.getDB(dbName)); + +// Wait for rollback to hang. +checkLog.contains(rollbackNode, "rollbackHangAfterTransitionToRollback fail point enabled."); + +// Make sure we can't read during rollback. Since we want to exercise the real check for +// primary in the 'find' command, we have to disable the best-effort check for primary in service +// entry point. +setFailPoint(rollbackNode, "skipCheckingForNotPrimaryInCommandDispatch"); +jsTestLog("Reading during rollback returns not master error message"); +let res = assert.commandFailedWithCode(rollbackNode.getDB(dbName).runCommand({"find": collName}), + ErrorCodes.NotPrimaryOrSecondary, + "find did not fail with NotPrimaryOrSecondary"); + +// Since we did not send "helloOk: true", the error message should include "not master or +// secondary". +assert(res.errmsg.includes("not master or secondary"), res); + +// An isMaster response will not contain "helloOk: true" if the client does not send +// helloOk in the request. +res = assert.commandWorked(rollbackNode.getDB(dbName).adminCommand({isMaster: 1})); +assert.eq(res.helloOk, undefined); + +// Run the isMaster command with "helloOk: true" on the secondary. +res = assert.commandWorked(rollbackNode.getDB(dbName).adminCommand({isMaster: 1, helloOk: true})); +// The response should contain "helloOk: true", which indicates to the client that the +// server supports the hello command. +assert.eq(res.helloOk, true); + +jsTestLog("Reading during rollback returns not primary error message"); +res = assert.commandFailedWithCode(rollbackNode.getDB(dbName).runCommand({"find": collName}), + ErrorCodes.NotPrimaryOrSecondary, + "find did not fail with NotPrimaryOrSecondary"); +// Since we sent "helloOk: true", the error message should include "not primary or secondary". +assert(res.errmsg.includes("not primary or secondary"), res); +assert(!res.errmsg.includes("not master"), res); + +clearFailPoint(rollbackNode, "rollbackHangAfterTransitionToRollback"); + +rollbackTest.transitionToSteadyStateOperations(); +rollbackTest.stop(); +}()); |