summaryrefslogtreecommitdiff
path: root/jstests/noPassthrough/mirror_reads.js
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/noPassthrough/mirror_reads.js')
-rw-r--r--jstests/noPassthrough/mirror_reads.js127
1 files changed, 100 insertions, 27 deletions
diff --git a/jstests/noPassthrough/mirror_reads.js b/jstests/noPassthrough/mirror_reads.js
index 6315c4df9b1..4a27724aeef 100644
--- a/jstests/noPassthrough/mirror_reads.js
+++ b/jstests/noPassthrough/mirror_reads.js
@@ -3,7 +3,7 @@
*
* @tags: [
* requires_replication,
- * requires_fcv_61
+ * requires_fcv_62
* ]
*/
@@ -17,24 +17,28 @@ function setParameter({rst, value}) {
const kBurstCount = 1000;
const kDbName = "mirrored_reads_test";
const kCollName = "test";
+// We use an arbitrarily large maxTimeMS to avoid timing out when processing the mirrored read
+// on slower builds. Otherwise, on slower builds, the primary.mirroredReads.sent metric could
+// be incremented but not the secondary.mirroredReads.processedAsSecondary metric.
+const kLargeMaxTimeMS = 100000000;
function getMirroredReadsStats(node) {
return node.getDB(kDbName).serverStatus({mirroredReads: 1}).mirroredReads;
}
-function sendAndCheckReads({rst, cmd, minRate, maxRate}) {
+function sendAndCheckReads({rst, cmd, minRate, maxRate, burstCount}) {
const primary = rst.getPrimary();
const secondaries = rst.getSecondaries();
let initialPrimaryStats = getMirroredReadsStats(primary);
- let initialSecondariesReceived = [];
+ let initialProcessedAsSecondary = [];
for (const secondary of rst.getSecondaries()) {
- let secondaryMirroredReadsReceived = getMirroredReadsStats(secondary).received;
- initialSecondariesReceived.push(secondaryMirroredReadsReceived);
+ let secondaryMirroredReadsProcessed = getMirroredReadsStats(secondary).processedAsSecondary;
+ initialProcessedAsSecondary.push(secondaryMirroredReadsProcessed);
}
- jsTestLog(`Sending ${kBurstCount} request burst of ${tojson(cmd)} to primary`);
+ jsTestLog(`Sending ${burstCount} request burst of ${tojson(cmd)} to primary`);
- for (var i = 0; i < kBurstCount; ++i) {
+ for (var i = 0; i < burstCount; ++i) {
rst.getPrimary().getDB(kDbName).runCommand(cmd);
}
@@ -43,18 +47,20 @@ function sendAndCheckReads({rst, cmd, minRate, maxRate}) {
// Verify that the commands have been observed on the primary
{
const currentPrimaryStats = getMirroredReadsStats(primary);
- assert.lte(initialPrimaryStats.seen + kBurstCount, currentPrimaryStats.seen);
+ assert.lte(initialPrimaryStats.seen + burstCount, currentPrimaryStats.seen);
}
// Verify that the reads mirrored to the secondaries have responded and secondaries receive the
// same amount of mirrored reads that were sent by the primary.
let currentPrimaryMirroredReadsStats;
let readsSent;
+ let readsSucceeded;
assert.soon(() => {
currentPrimaryMirroredReadsStats = getMirroredReadsStats(primary);
readsSent = currentPrimaryMirroredReadsStats.sent - initialPrimaryStats.sent;
let readsResolved =
currentPrimaryMirroredReadsStats.resolved - initialPrimaryStats.resolved;
+ readsSucceeded = currentPrimaryMirroredReadsStats.succeeded - initialPrimaryStats.succeeded;
// The number of reads the primary has decided to mirror to secondaries, but hasn't yet
// sent.
let readsPending = currentPrimaryMirroredReadsStats.pending;
@@ -64,23 +70,25 @@ function sendAndCheckReads({rst, cmd, minRate, maxRate}) {
tojson({
sent: readsSent,
resolved: readsResolved,
+ succeeded: readsSucceeded,
pending: readsPending,
seen: readsSeen
}));
return ((readsPending == 0) && (readsSent === readsResolved));
}, "Did not resolve all requests within time limit", 10000);
- // The number of mirrored reads received across all secondaries.
- let readsReceived = 0;
+ // The number of mirrored reads processed across all secondaries.
+ let readsProcessedAsSecondaryTotal = 0;
for (let i = 0; i < secondaries.length; i++) {
const currentSecondaryMirroredReadsStats = getMirroredReadsStats(secondaries[i]);
- const received =
- currentSecondaryMirroredReadsStats.received - initialSecondariesReceived[i];
- jsTestLog("Verifying number of reads received by secondary " + secondaries[i] + ": " +
- tojson({received: received}));
- readsReceived += received;
+ const processedAsSecondary = currentSecondaryMirroredReadsStats.processedAsSecondary -
+ initialProcessedAsSecondary[i];
+ jsTestLog("Verifying number of reads processed by secondary " + secondaries[i] + ": " +
+ tojson({processedAsSecondary: processedAsSecondary}));
+ readsProcessedAsSecondaryTotal += processedAsSecondary;
}
- assert.eq(readsReceived, readsSent);
+ assert.eq(readsProcessedAsSecondaryTotal, readsSucceeded);
+ assert.eq(readsProcessedAsSecondaryTotal, readsSent);
jsTestLog("Verifying primary statistics: " +
tojson({current: currentPrimaryMirroredReadsStats, start: initialPrimaryStats}));
@@ -91,7 +99,7 @@ function sendAndCheckReads({rst, cmd, minRate, maxRate}) {
let rate = readsMirrored / readsSeen / numNodes;
// Check that the primary has seen all the mirrored-read supporting operations we've sent it
- assert.gte(readsSeen, kBurstCount);
+ assert.gte(readsSeen, burstCount);
// Check that the rate of mirroring meets the provided criteria
assert.gte(rate, minRate);
assert.lte(rate, maxRate);
@@ -105,7 +113,13 @@ function verifyMirrorReads(rst, cmd) {
let samplingRate = 0.0;
assert.commandWorked(setParameter({rst: rst, value: {samplingRate: samplingRate}}));
- sendAndCheckReads({rst: rst, cmd: cmd, minRate: samplingRate, maxRate: samplingRate});
+ sendAndCheckReads({
+ rst: rst,
+ cmd: cmd,
+ minRate: samplingRate,
+ maxRate: samplingRate,
+ burstCount: kBurstCount
+ });
}
{
@@ -113,7 +127,13 @@ function verifyMirrorReads(rst, cmd) {
let samplingRate = 1.0;
assert.commandWorked(setParameter({rst: rst, value: {samplingRate: samplingRate}}));
- sendAndCheckReads({rst: rst, cmd: cmd, minRate: samplingRate, maxRate: samplingRate});
+ sendAndCheckReads({
+ rst: rst,
+ cmd: cmd,
+ minRate: samplingRate,
+ maxRate: samplingRate,
+ burstCount: kBurstCount
+ });
}
{
@@ -124,7 +144,40 @@ function verifyMirrorReads(rst, cmd) {
let min = samplingRate - gaussDeviation;
assert.commandWorked(setParameter({rst: rst, value: {samplingRate: samplingRate}}));
- sendAndCheckReads({rst: rst, cmd: cmd, minRate: min, maxRate: max});
+ sendAndCheckReads(
+ {rst: rst, cmd: cmd, minRate: min, maxRate: max, burstCount: kBurstCount});
+ }
+}
+
+function verifyProcessedAsSecondary(rst) {
+ // Mirror every mirror-able command.
+ const samplingRate = 1.0;
+ assert.commandWorked(setParameter({rst: rst, value: {samplingRate: samplingRate}}));
+
+ for (const secondary of rst.getSecondaries()) {
+ assert.commandWorked(secondary.getDB(kDbName).adminCommand({
+ configureFailPoint: "failCommand",
+ mode: "alwaysOn",
+ data: {
+ errorCode: ErrorCodes.MaxTimeMSExpired,
+ failCommands: ["find"],
+ }
+ }));
+ }
+
+ // With enabled fail point, check that no commands succeed or are processed, but all are
+ // resolved.
+ sendAndCheckReads({
+ rst: rst,
+ cmd: {find: kCollName, filter: {}},
+ minRate: samplingRate,
+ maxRate: samplingRate,
+ burstCount: kBurstCount
+ });
+
+ for (const secondary of rst.getSecondaries()) {
+ assert.commandWorked(secondary.getDB(kDbName).adminCommand(
+ {configureFailPoint: "failCommand", mode: "off"}));
}
}
@@ -156,20 +209,32 @@ function verifyMirrorReads(rst, cmd) {
}
jsTestLog("Verifying mirrored reads for 'find' commands");
- verifyMirrorReads(rst, {find: kCollName, filter: {}});
+ verifyMirrorReads(rst, {find: kCollName, filter: {}, maxTimeMS: kLargeMaxTimeMS});
jsTestLog("Verifying mirrored reads for 'count' commands");
- verifyMirrorReads(rst, {count: kCollName, query: {}});
+ verifyMirrorReads(rst, {count: kCollName, query: {}, maxTimeMS: kLargeMaxTimeMS});
jsTestLog("Verifying mirrored reads for 'distinct' commands");
- verifyMirrorReads(rst, {distinct: kCollName, key: "x"});
+ verifyMirrorReads(rst, {distinct: kCollName, key: "x", maxTimeMS: kLargeMaxTimeMS});
jsTestLog("Verifying mirrored reads for 'findAndModify' commands");
- verifyMirrorReads(rst, {findAndModify: kCollName, query: {}, update: {'$inc': {x: 1}}});
+ verifyMirrorReads(rst, {
+ findAndModify: kCollName,
+ query: {},
+ update: {'$inc': {x: 1}},
+ maxTimeMS: kLargeMaxTimeMS
+ });
jsTestLog("Verifying mirrored reads for 'update' commands");
- verifyMirrorReads(
- rst, {update: kCollName, updates: [{q: {_id: 1}, u: {'$inc': {x: 1}}}], ordered: false});
+ verifyMirrorReads(rst, {
+ update: kCollName,
+ updates: [{q: {_id: 1}, u: {'$inc': {x: 1}}}],
+ ordered: false,
+ maxTimeMS: kLargeMaxTimeMS
+ });
+
+ jsTestLog("Verifying processedAsSecondary field for 'find' commands");
+ verifyProcessedAsSecondary(rst);
rst.stopSet();
}
@@ -221,7 +286,15 @@ function verifyMirroringDistribution(rst) {
let before = getMirroredReadsStats(rst.getPrimary());
- sendAndCheckReads({rst: rst, cmd: {find: kCollName, filter: {}}, minRate: min, maxRate: max});
+ sendAndCheckReads({
+ rst: rst,
+ cmd: {find: kCollName, filter: {}},
+ minRate: min,
+ maxRate: max,
+ burstCount: kBurstCount,
+ checkExpectedReadsProcessed: false,
+ expectedReadsProcessed: 0
+ });
let after = getMirroredReadsStats(rst.getPrimary());