diff options
author | Jack Mulrow <jack.mulrow@mongodb.com> | 2017-06-02 16:37:34 -0400 |
---|---|---|
committer | Jack Mulrow <jack.mulrow@mongodb.com> | 2017-06-06 10:29:47 -0400 |
commit | 783d11c4ea92784dc6ca0cc0419403c454c9ec9c (patch) | |
tree | a396e67154af0d178008fcf33156f4f557854c06 /jstests/sharding/after_cluster_time.js | |
parent | 6b05afb44da679600b682e0ef3c7061eb7e3403c (diff) | |
download | mongo-783d11c4ea92784dc6ca0cc0419403c454c9ec9c.tar.gz |
SERVER-29434 Don't accept empty timestamps for readConcern afterClusterTime
Diffstat (limited to 'jstests/sharding/after_cluster_time.js')
-rw-r--r-- | jstests/sharding/after_cluster_time.js | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/jstests/sharding/after_cluster_time.js b/jstests/sharding/after_cluster_time.js new file mode 100644 index 00000000000..0b299408512 --- /dev/null +++ b/jstests/sharding/after_cluster_time.js @@ -0,0 +1,111 @@ +/** + * Tests readConcern: afterClusterTime behavior in a sharded cluster. + */ +(function() { + "use strict"; + + load("jstests/replsets/rslib.js"); // For startSetIfSupportsReadMajority. + + function assertAfterClusterTimeReadFailsWithCode(db, readConcernObj, errorCode) { + return assert.commandFailedWithCode( + db.runCommand({find: "foo", readConcern: readConcernObj}), + errorCode, + "expected command with read concern options: " + tojson(readConcernObj) + " to fail"); + } + + function assertAfterClusterTimeReadSucceeds(db, readConcernObj) { + return assert.commandWorked(db.runCommand({find: "foo", readConcern: readConcernObj}), + "expected command with read concern options: " + + tojson(readConcernObj) + " to succeed"); + } + + const rst = new ReplSetTest({ + nodes: 1, + nodeOptions: { + enableMajorityReadConcern: "", + shardsvr: "", + } + }); + + if (!startSetIfSupportsReadMajority(rst)) { + jsTestLog("Skipping test since storage engine doesn't support majority read concern."); + return; + } + rst.initiate(); + + // Start the sharding test and add the majority read concern enabled replica set. + const st = new ShardingTest({ + manualAddShard: true, + }); + assert.commandWorked(st.s.adminCommand({addShard: rst.getURL()})); + + const testDB = st.s.getDB("test"); + + // Insert some data to find later. + assert.commandWorked(testDB.runCommand( + {insert: "foo", documents: [{_id: 1, x: 1}], writeConcern: {w: "majority"}})); + + // Test the afterClusterTime API without causal consistency enabled on the mongo connection. + + // Reads with afterClusterTime require read concern level majority. + assertAfterClusterTimeReadFailsWithCode( + testDB, {afterClusterTime: Timestamp(1, 1)}, ErrorCodes.InvalidOptions); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "local", afterClusterTime: Timestamp(1, 1)}, ErrorCodes.InvalidOptions); + + // Reads with afterClusterTime require a non-zero timestamp. + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: {}}, ErrorCodes.TypeMismatch); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: 10}, ErrorCodes.TypeMismatch); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: Timestamp()}, ErrorCodes.InvalidOptions); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: Timestamp(0, 0)}, ErrorCodes.InvalidOptions); + + // Reads with proper afterClusterTime arguments return committed data after the given time. + let res = assert.commandWorked(testDB.runCommand( + {find: "foo", readConcern: {level: "majority", afterClusterTime: Timestamp(1, 1)}})); + + assert.eq(res.cursor.firstBatch, + [{_id: 1, x: 1}], + "expected afterClusterTime read to return the committed document"); + + // Test the afterClusterTime API with causal consistency enabled on the mongo connection. + testDB.getMongo().setCausalConsistency(true); + + // With causal consistency enabled, the shell sets read concern to level "majority" if it is not + // specified. + assertAfterClusterTimeReadSucceeds(testDB, {afterClusterTime: Timestamp(1, 1)}); + + // Read concern levels other than majority are still not accepted. + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "local", afterClusterTime: Timestamp(1, 1)}, ErrorCodes.InvalidOptions); + + // Reads with afterClusterTime still require a non-zero timestamp. + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: {}}, ErrorCodes.TypeMismatch); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: 10}, ErrorCodes.TypeMismatch); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: Timestamp()}, ErrorCodes.InvalidOptions); + + assertAfterClusterTimeReadFailsWithCode( + testDB, {level: "majority", afterClusterTime: Timestamp(0, 0)}, ErrorCodes.InvalidOptions); + + // Reads with proper afterClusterTime arguments return committed data after the given time. + res = assert.commandWorked(testDB.runCommand( + {find: "foo", readConcern: {level: "majority", afterClusterTime: Timestamp(1, 1)}})); + + assert.eq(res.cursor.firstBatch, + [{_id: 1, x: 1}], + "expected afterClusterTime read to return the committed document"); + + st.stop(); +})(); |