summaryrefslogtreecommitdiff
path: root/jstests/sharding/causal_consistency_shell_support.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/sharding/causal_consistency_shell_support.js')
-rw-r--r--jstests/sharding/causal_consistency_shell_support.js354
1 files changed, 176 insertions, 178 deletions
diff --git a/jstests/sharding/causal_consistency_shell_support.js b/jstests/sharding/causal_consistency_shell_support.js
index f66b772aa9a..8466209d367 100644
--- a/jstests/sharding/causal_consistency_shell_support.js
+++ b/jstests/sharding/causal_consistency_shell_support.js
@@ -4,186 +4,184 @@
* response, and that the server rejects commands with afterClusterTime ahead of cluster time.
*/
(function() {
- "use strict";
-
- load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority.
-
- // Verifies the command works and properly updates operation or cluster time.
- function runCommandAndCheckLogicalTimes(cmdObj, db, shouldAdvance) {
- const session = db.getSession();
-
- // Extract initial operation and cluster time.
- let operationTime = session.getOperationTime();
- let clusterTimeObj = session.getClusterTime();
-
- assert.commandWorked(db.runCommand(cmdObj));
-
- // Verify cluster and operation time.
- if (shouldAdvance) {
- assert(bsonWoCompare(session.getOperationTime(), operationTime) > 0,
- "expected the shell's operationTime to increase after running command: " +
- tojson(cmdObj));
- assert(
- bsonWoCompare(session.getClusterTime().clusterTime, clusterTimeObj.clusterTime) > 0,
- "expected the shell's clusterTime value to increase after running command: " +
- tojson(cmdObj));
- } else {
- // Don't expect either clusterTime or operationTime to not change, because they may be
- // incremented by unrelated activity in the cluster.
- }
+"use strict";
+
+load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority.
+
+// Verifies the command works and properly updates operation or cluster time.
+function runCommandAndCheckLogicalTimes(cmdObj, db, shouldAdvance) {
+ const session = db.getSession();
+
+ // Extract initial operation and cluster time.
+ let operationTime = session.getOperationTime();
+ let clusterTimeObj = session.getClusterTime();
+
+ assert.commandWorked(db.runCommand(cmdObj));
+
+ // Verify cluster and operation time.
+ if (shouldAdvance) {
+ assert(bsonWoCompare(session.getOperationTime(), operationTime) > 0,
+ "expected the shell's operationTime to increase after running command: " +
+ tojson(cmdObj));
+ assert(bsonWoCompare(session.getClusterTime().clusterTime, clusterTimeObj.clusterTime) > 0,
+ "expected the shell's clusterTime value to increase after running command: " +
+ tojson(cmdObj));
+ } else {
+ // Don't expect either clusterTime or operationTime to not change, because they may be
+ // incremented by unrelated activity in the cluster.
}
-
- // Verifies the command works and correctly updates the shell's operationTime.
- function commandWorksAndUpdatesOperationTime(cmdObj, db) {
- const session = db.getSession();
-
- // Use the latest cluster time returned as a new operationTime and run command.
- const clusterTimeObj = session.getClusterTime();
- session.advanceOperationTime(clusterTimeObj.clusterTime);
- assert.commandWorked(testDB.runCommand(cmdObj));
-
- // Verify the response contents and that new operation time is >= passed in time.
- assert(bsonWoCompare(session.getOperationTime(), clusterTimeObj.clusterTime) >= 0,
- "expected the shell's operationTime to be >= to:" + clusterTimeObj.clusterTime +
- " after running command: " + tojson(cmdObj));
- }
-
- // Manually create a shard so tests on storage engines that don't support majority readConcern
- // can exit early.
- const rsName = "causal_consistency_shell_support_rs";
- const rst = new ReplSetTest({
- nodes: 1,
- name: rsName,
- nodeOptions: {
- enableMajorityReadConcern: "",
- shardsvr: "",
- }
- });
-
- if (!startSetIfSupportsReadMajority(rst)) {
- jsTest.log("skipping test since storage engine doesn't support committed reads");
- rst.stopSet();
- return;
+}
+
+// Verifies the command works and correctly updates the shell's operationTime.
+function commandWorksAndUpdatesOperationTime(cmdObj, db) {
+ const session = db.getSession();
+
+ // Use the latest cluster time returned as a new operationTime and run command.
+ const clusterTimeObj = session.getClusterTime();
+ session.advanceOperationTime(clusterTimeObj.clusterTime);
+ assert.commandWorked(testDB.runCommand(cmdObj));
+
+ // Verify the response contents and that new operation time is >= passed in time.
+ assert(bsonWoCompare(session.getOperationTime(), clusterTimeObj.clusterTime) >= 0,
+ "expected the shell's operationTime to be >= to:" + clusterTimeObj.clusterTime +
+ " after running command: " + tojson(cmdObj));
+}
+
+// Manually create a shard so tests on storage engines that don't support majority readConcern
+// can exit early.
+const rsName = "causal_consistency_shell_support_rs";
+const rst = new ReplSetTest({
+ nodes: 1,
+ name: rsName,
+ nodeOptions: {
+ enableMajorityReadConcern: "",
+ shardsvr: "",
}
- rst.initiate();
-
- // Start the sharding test and add the majority readConcern enabled replica set.
- const name = "causal_consistency_shell_support";
- const st = new ShardingTest({name: name, shards: 1, manualAddShard: true});
- assert.commandWorked(st.s.adminCommand({addShard: rst.getURL()}));
-
- const testDB = st.s.getDB("test");
- const session = testDB.getSession();
-
- // Verify causal consistency is disabled unless explicitly set.
- assert.eq(testDB.getMongo()._causalConsistency,
- false,
- "causal consistency should be disabled by default");
- testDB.getMongo().setCausalConsistency(true);
-
- // Verify causal consistency is enabled for the connection and for each supported command.
- assert.eq(testDB.getMongo()._causalConsistency,
- true,
- "calling setCausalConsistency() didn't enable causal consistency");
-
- // Verify cluster times are tracked even before causal consistency is set (so the first
- // operation with causal consistency set can use valid cluster times).
- session.resetOperationTime_forTesting();
-
- assert.commandWorked(testDB.runCommand({insert: "foo", documents: [{x: 1}]}));
- assert.neq(session.getOperationTime(), null);
- assert.neq(session.getClusterTime(), null);
-
- session.resetOperationTime_forTesting();
-
- assert.commandWorked(testDB.runCommand({find: "foo"}));
- assert.neq(session.getOperationTime(), null);
- assert.neq(session.getClusterTime(), null);
-
- // Test that write commands advance both operation and cluster time.
- runCommandAndCheckLogicalTimes({insert: "foo", documents: [{x: 2}]}, testDB, true);
- runCommandAndCheckLogicalTimes(
- {update: "foo", updates: [{q: {x: 2}, u: {$set: {x: 3}}}]}, testDB, true);
-
- // Test that each supported command works as expected and the shell's cluster times are properly
- // forwarded to the server and updated based on the response.
- testDB.getMongo().setCausalConsistency(true);
-
- // Aggregate command.
- let aggColl = "aggColl";
- let aggCmd = {aggregate: aggColl, pipeline: [{$match: {x: 1}}], cursor: {}};
-
- runCommandAndCheckLogicalTimes({insert: aggColl, documents: [{_id: 1, x: 1}]}, testDB, true);
- runCommandAndCheckLogicalTimes(aggCmd, testDB, false);
- commandWorksAndUpdatesOperationTime(aggCmd, testDB);
-
- // Count command.
- let countColl = "countColl";
- let countCmd = {count: countColl};
-
- runCommandAndCheckLogicalTimes({insert: countColl, documents: [{_id: 1, x: 1}]}, testDB, true);
- runCommandAndCheckLogicalTimes(countCmd, testDB, false);
- commandWorksAndUpdatesOperationTime(countCmd, testDB);
-
- // Distinct command.
- let distinctColl = "distinctColl";
- let distinctCmd = {distinct: distinctColl, key: "x"};
-
- runCommandAndCheckLogicalTimes(
- {insert: distinctColl, documents: [{_id: 1, x: 1}]}, testDB, true);
- runCommandAndCheckLogicalTimes(distinctCmd, testDB, false);
- commandWorksAndUpdatesOperationTime(distinctCmd, testDB);
-
- // Find command.
- let findColl = "findColl";
- let findCmd = {find: findColl};
-
- runCommandAndCheckLogicalTimes({insert: findColl, documents: [{_id: 1, x: 1}]}, testDB, true);
- runCommandAndCheckLogicalTimes(findCmd, testDB, false);
- commandWorksAndUpdatesOperationTime(findCmd, testDB);
-
- // Aggregate command with $geoNear.
- let geoNearColl = "geoNearColl";
- let geoNearCmd = {
- aggregate: geoNearColl,
- cursor: {},
- pipeline: [
- {
- $geoNear: {
- near: {type: "Point", coordinates: [-10, 10]},
- distanceField: "dist",
- spherical: true
- }
- },
- ],
- };
-
- assert.commandWorked(testDB[geoNearColl].createIndex({loc: "2dsphere"}));
- runCommandAndCheckLogicalTimes(
- {insert: geoNearColl, documents: [{_id: 1, loc: {type: "Point", coordinates: [-10, 10]}}]},
- testDB,
- true);
- runCommandAndCheckLogicalTimes(geoNearCmd, testDB, false);
- commandWorksAndUpdatesOperationTime(geoNearCmd, testDB);
-
- // GeoSearch is not supported for sharded clusters.
-
- // MapReduce doesn't currently support read concern majority.
-
- // Verify that the server rejects commands when operation time is invalid by running a command
- // with an afterClusterTime value one day ahead.
- const invalidTime = new Timestamp(session.getOperationTime().getTime() + (60 * 60 * 24), 0);
- const invalidCmd = {
- find: "foo",
- readConcern: {level: "majority", afterClusterTime: invalidTime}
- };
- assert.commandFailedWithCode(
- testDB.runCommand(invalidCmd),
- ErrorCodes.InvalidOptions,
- "expected command, " + tojson(invalidCmd) + ", to fail with code, " +
- ErrorCodes.InvalidOptions + ", because the afterClusterTime value, " + invalidTime +
- ", should not be ahead of the clusterTime, " + session.getClusterTime().clusterTime);
+});
+if (!startSetIfSupportsReadMajority(rst)) {
+ jsTest.log("skipping test since storage engine doesn't support committed reads");
rst.stopSet();
- st.stop();
+ return;
+}
+rst.initiate();
+
+// Start the sharding test and add the majority readConcern enabled replica set.
+const name = "causal_consistency_shell_support";
+const st = new ShardingTest({name: name, shards: 1, manualAddShard: true});
+assert.commandWorked(st.s.adminCommand({addShard: rst.getURL()}));
+
+const testDB = st.s.getDB("test");
+const session = testDB.getSession();
+
+// Verify causal consistency is disabled unless explicitly set.
+assert.eq(testDB.getMongo()._causalConsistency,
+ false,
+ "causal consistency should be disabled by default");
+testDB.getMongo().setCausalConsistency(true);
+
+// Verify causal consistency is enabled for the connection and for each supported command.
+assert.eq(testDB.getMongo()._causalConsistency,
+ true,
+ "calling setCausalConsistency() didn't enable causal consistency");
+
+// Verify cluster times are tracked even before causal consistency is set (so the first
+// operation with causal consistency set can use valid cluster times).
+session.resetOperationTime_forTesting();
+
+assert.commandWorked(testDB.runCommand({insert: "foo", documents: [{x: 1}]}));
+assert.neq(session.getOperationTime(), null);
+assert.neq(session.getClusterTime(), null);
+
+session.resetOperationTime_forTesting();
+
+assert.commandWorked(testDB.runCommand({find: "foo"}));
+assert.neq(session.getOperationTime(), null);
+assert.neq(session.getClusterTime(), null);
+
+// Test that write commands advance both operation and cluster time.
+runCommandAndCheckLogicalTimes({insert: "foo", documents: [{x: 2}]}, testDB, true);
+runCommandAndCheckLogicalTimes(
+ {update: "foo", updates: [{q: {x: 2}, u: {$set: {x: 3}}}]}, testDB, true);
+
+// Test that each supported command works as expected and the shell's cluster times are properly
+// forwarded to the server and updated based on the response.
+testDB.getMongo().setCausalConsistency(true);
+
+// Aggregate command.
+let aggColl = "aggColl";
+let aggCmd = {aggregate: aggColl, pipeline: [{$match: {x: 1}}], cursor: {}};
+
+runCommandAndCheckLogicalTimes({insert: aggColl, documents: [{_id: 1, x: 1}]}, testDB, true);
+runCommandAndCheckLogicalTimes(aggCmd, testDB, false);
+commandWorksAndUpdatesOperationTime(aggCmd, testDB);
+
+// Count command.
+let countColl = "countColl";
+let countCmd = {count: countColl};
+
+runCommandAndCheckLogicalTimes({insert: countColl, documents: [{_id: 1, x: 1}]}, testDB, true);
+runCommandAndCheckLogicalTimes(countCmd, testDB, false);
+commandWorksAndUpdatesOperationTime(countCmd, testDB);
+
+// Distinct command.
+let distinctColl = "distinctColl";
+let distinctCmd = {distinct: distinctColl, key: "x"};
+
+runCommandAndCheckLogicalTimes({insert: distinctColl, documents: [{_id: 1, x: 1}]}, testDB, true);
+runCommandAndCheckLogicalTimes(distinctCmd, testDB, false);
+commandWorksAndUpdatesOperationTime(distinctCmd, testDB);
+
+// Find command.
+let findColl = "findColl";
+let findCmd = {find: findColl};
+
+runCommandAndCheckLogicalTimes({insert: findColl, documents: [{_id: 1, x: 1}]}, testDB, true);
+runCommandAndCheckLogicalTimes(findCmd, testDB, false);
+commandWorksAndUpdatesOperationTime(findCmd, testDB);
+
+// Aggregate command with $geoNear.
+let geoNearColl = "geoNearColl";
+let geoNearCmd = {
+ aggregate: geoNearColl,
+ cursor: {},
+ pipeline: [
+ {
+ $geoNear: {
+ near: {type: "Point", coordinates: [-10, 10]},
+ distanceField: "dist",
+ spherical: true
+ }
+ },
+ ],
+};
+
+assert.commandWorked(testDB[geoNearColl].createIndex({loc: "2dsphere"}));
+runCommandAndCheckLogicalTimes(
+ {insert: geoNearColl, documents: [{_id: 1, loc: {type: "Point", coordinates: [-10, 10]}}]},
+ testDB,
+ true);
+runCommandAndCheckLogicalTimes(geoNearCmd, testDB, false);
+commandWorksAndUpdatesOperationTime(geoNearCmd, testDB);
+
+// GeoSearch is not supported for sharded clusters.
+
+// MapReduce doesn't currently support read concern majority.
+
+// Verify that the server rejects commands when operation time is invalid by running a command
+// with an afterClusterTime value one day ahead.
+const invalidTime = new Timestamp(session.getOperationTime().getTime() + (60 * 60 * 24), 0);
+const invalidCmd = {
+ find: "foo",
+ readConcern: {level: "majority", afterClusterTime: invalidTime}
+};
+assert.commandFailedWithCode(
+ testDB.runCommand(invalidCmd),
+ ErrorCodes.InvalidOptions,
+ "expected command, " + tojson(invalidCmd) + ", to fail with code, " +
+ ErrorCodes.InvalidOptions + ", because the afterClusterTime value, " + invalidTime +
+ ", should not be ahead of the clusterTime, " + session.getClusterTime().clusterTime);
+
+rst.stopSet();
+st.stop();
})();