summaryrefslogtreecommitdiff
path: root/jstests/replsets/secondary_reads_timestamp_visibility.js
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2018-04-10 15:13:59 -0400
committerLouis Williams <louis.williams@mongodb.com>2018-04-24 15:53:46 -0400
commite75fd5732ff4ecc269ab8a9cba601b79af460daa (patch)
tree8c13c041157e22fa5e76a40db3628725e53b48b4 /jstests/replsets/secondary_reads_timestamp_visibility.js
parentb57eee5a295ede1fd67299dc9990c272c1f66ea3 (diff)
downloadmongo-e75fd5732ff4ecc269ab8a9cba601b79af460daa.tar.gz
SERVER-34385 Unit tests for secondary reads during oplog application
Diffstat (limited to 'jstests/replsets/secondary_reads_timestamp_visibility.js')
-rw-r--r--jstests/replsets/secondary_reads_timestamp_visibility.js83
1 files changed, 83 insertions, 0 deletions
diff --git a/jstests/replsets/secondary_reads_timestamp_visibility.js b/jstests/replsets/secondary_reads_timestamp_visibility.js
new file mode 100644
index 00000000000..47b7163d7f5
--- /dev/null
+++ b/jstests/replsets/secondary_reads_timestamp_visibility.js
@@ -0,0 +1,83 @@
+/**
+ * Tests that reads on a secondary during batch application only see changes that occur at the last
+ * applied timestamp, whichis advanced at the completion of each batch.
+ *
+ * This test uses a failpoint to block right before batch application finishes, while holding the
+ * PBWM lock, and before advancing the last applied timestamp for readers.
+ *
+ */
+(function() {
+ "use strict";
+
+ load('jstests/replsets/libs/secondary_reads_test.js');
+
+ const name = "secondaryReadsTimestampVisibility";
+ const collName = "testColl";
+ let secondaryReadsTest = new SecondaryReadsTest(name);
+ let replSet = secondaryReadsTest.getReplset();
+
+ let primaryDB = secondaryReadsTest.getPrimaryDB();
+ let secondaryDB = secondaryReadsTest.getSecondaryDB();
+
+ let primaryColl = primaryDB.getCollection(collName);
+
+ // Create a collection and an index. Insert some data.
+ primaryDB.runCommand({drop: collName});
+ assert.commandWorked(primaryDB.runCommand({create: collName}));
+ assert.commandWorked(primaryDB.runCommand(
+ {createIndexes: collName, indexes: [{key: {y: 1}, name: "y_1", unique: true}]}));
+ for (let i = 0; i < 100; i++) {
+ assert.commandWorked(primaryColl.insert({_id: i, x: 0, y: i + 1}));
+ }
+
+ replSet.awaitReplication();
+
+ // Sanity check.
+ assert.eq(secondaryDB.getCollection(collName).find({x: 0}).itcount(), 100);
+ assert.eq(secondaryDB.getCollection(collName).find({y: {$gte: 1, $lt: 101}}).itcount(), 100);
+
+ // Prevent a batch from completing on the secondary.
+ let pauseAwait = secondaryReadsTest.pauseSecondaryBatchApplication();
+
+ // Update x to 1 in each document with default writeConcern and make sure we see the correct
+ // data on the primary.
+ let updates = [];
+ for (let i = 0; i < 100; i++) {
+ updates[i] = {q: {_id: i}, u: {x: 1, y: i}};
+ }
+ assert.commandWorked(primaryDB.runCommand({update: collName, updates: updates}));
+ assert.eq(primaryColl.find({x: 1}).itcount(), 100);
+ assert.eq(primaryColl.find({y: {$gte: 0, $lt: 100}}).itcount(), 100);
+
+ // Wait for the batch application to pause.
+ pauseAwait();
+
+ let levels = ["local", "available", "majority"];
+
+ // We should see the previous, un-replicated state on the secondary with every readconcern.
+ for (let i in levels) {
+ assert.eq(secondaryDB.getCollection(collName).find({x: 0}).readConcern(levels[i]).itcount(),
+ 100);
+ assert.eq(secondaryDB.getCollection(collName).find({x: 1}).readConcern(levels[i]).itcount(),
+ 0);
+ assert.eq(secondaryDB.getCollection(collName)
+ .find({y: {$gte: 1, $lt: 101}})
+ .readConcern(levels[i])
+ .itcount(),
+ 100);
+ }
+
+ // Disable the failpoint and let the batch complete.
+ secondaryReadsTest.resumeSecondaryBatchApplication();
+
+ replSet.awaitReplication();
+
+ for (let i in levels) {
+ // We should see the previous state on the secondary with every readconcern.
+ assert.eq(secondaryDB.getCollection(collName).find({x: 0}).readConcern(levels[i]).itcount(),
+ 0);
+ assert.eq(secondaryDB.getCollection(collName).find({x: 1}).readConcern(levels[i]).itcount(),
+ 100);
+ }
+ secondaryReadsTest.stop();
+})();