summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorLingzhi Deng <lingzhi.deng@mongodb.com>2019-09-03 19:30:28 +0000
committerevergreen <evergreen@mongodb.com>2019-09-03 19:30:28 +0000
commit88df2558b0c3b39b86df2ab97814d701d701d704 (patch)
tree1570ebdd1373cdf70fd558a46e1832380491d419 /jstests
parentd4ccbcfad2b7b47593054c3319f80b9ca922e066 (diff)
downloadmongo-88df2558b0c3b39b86df2ab97814d701d701d704.tar.gz
SERVER-39310: Call checkCanServeReadsFor() in 'getMore'
- added call to checkCanServeReadsFor() in getmore_cmd.cpp after getting readlocks - introduced two fail points: 1. pause 'getMore' before readlocks 2. pause rollback after state transition - added testcase read_operations_during_rollback.js - added assert.includes (cherry picked from commit dd9be1adf2425c7ddd746ff6da75d564474ebed3) (cherry picked from commit b885fa6feb7da00dc367e917c53ba16a41b75af4)
Diffstat (limited to 'jstests')
-rw-r--r--jstests/replsets/read_operations_during_rollback.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/jstests/replsets/read_operations_during_rollback.js b/jstests/replsets/read_operations_during_rollback.js
new file mode 100644
index 00000000000..209e2003c26
--- /dev/null
+++ b/jstests/replsets/read_operations_during_rollback.js
@@ -0,0 +1,95 @@
+/*
+ * This test makes sure 'find' and 'getMore' commands fail correctly during rollback.
+ */
+(function() {
+ "use strict";
+
+ load("jstests/replsets/libs/rollback_test.js");
+
+ const dbName = "test";
+ const collName = "coll";
+
+ let setFailPoint = (node, failpoint) => {
+ jsTestLog("Setting fail point " + failpoint);
+ assert.commandWorked(node.adminCommand({configureFailPoint: failpoint, mode: "alwaysOn"}));
+ };
+
+ let clearFailPoint = (node, failpoint) => {
+ jsTestLog("Clearing fail point " + failpoint);
+ assert.commandWorked(node.adminCommand({configureFailPoint: failpoint, mode: "off"}));
+ };
+
+ // 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");
+
+ setFailPoint(rollbackNode, "GetMoreHangBeforeReadLock");
+
+ const joinGetMoreThread = startParallelShell(() => {
+ db.getMongo().setSlaveOk();
+ const cursorID =
+ assert.commandWorked(db.runCommand({"find": "coll", batchSize: 0})).cursor.id;
+ let res = assert.throws(function() {
+ db.runCommand({"getMore": cursorID, collection: "coll"});
+ }, [], "network error");
+ // Make sure the connection of an outstanding read operation gets closed during rollback
+ // even though the read was started before rollback.
+ assert.includes(res.toString(), "network error while attempting to run command");
+ }, rollbackNode.port);
+
+ const cursorIdToBeReadDuringRollback =
+ assert
+ .commandWorked(rollbackNode.getDB(dbName).runCommand({"find": collName, batchSize: 0}))
+ .cursor.id;
+
+ // Wait for 'getMore' to hang.
+ checkLog.contains(rollbackNode, "GetMoreHangBeforeReadLock fail point enabled.");
+
+ // 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.");
+
+ clearFailPoint(rollbackNode, "GetMoreHangBeforeReadLock");
+
+ jsTestLog("Wait for 'getMore' thread to join.");
+ joinGetMoreThread();
+
+ jsTestLog("Reading during rollback.");
+ // Make sure that read operations fail during rollback.
+ assert.commandFailedWithCode(rollbackNode.getDB(dbName).runCommand({"find": collName}),
+ ErrorCodes.NotMasterOrSecondary);
+ assert.commandFailedWithCode(
+ rollbackNode.getDB(dbName).runCommand(
+ {"getMore": cursorIdToBeReadDuringRollback, collection: collName}),
+ ErrorCodes.NotMasterOrSecondary);
+
+ // Disable the best-effort check for primary-ness in the service entry point, so that we
+ // exercise the real check for primary-ness in 'find' and 'getMore' commands.
+ setFailPoint(rollbackNode, "skipCheckingForNotMasterInCommandDispatch");
+ jsTestLog("Reading during rollback (again with command dispatch checks disabled).");
+ assert.commandFailedWithCode(rollbackNode.getDB(dbName).runCommand({"find": collName}),
+ ErrorCodes.NotMasterOrSecondary);
+ assert.commandFailedWithCode(
+ rollbackNode.getDB(dbName).runCommand(
+ {"getMore": cursorIdToBeReadDuringRollback, collection: collName}),
+ ErrorCodes.NotMasterOrSecondary);
+
+ clearFailPoint(rollbackNode, "rollbackHangAfterTransitionToRollback");
+
+ rollbackTest.transitionToSteadyStateOperations();
+
+ // Check the replica set.
+ rollbackTest.stop();
+}());