summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorPavi Vetriselvan <pavithra.vetriselvan@mongodb.com>2020-11-17 15:35:15 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-19 16:40:05 +0000
commitd633efa72090a864442ef7232e1261d3b25bc27c (patch)
treeae59ded6b61efb30e74c284baf093a3e48f11604 /jstests
parentfd5f9c3fb195b78f59b7abcfc7a81318f9a5ee78 (diff)
downloadmongo-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.js2
-rw-r--r--jstests/replsets/not_primary_errors_returned_during_rollback_if_helloOk.js76
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();
+}());