mirror of https://github.com/mongodb/mongo
123 lines
4.3 KiB
JavaScript
123 lines
4.3 KiB
JavaScript
/**
|
|
* Test readCommitted lookup/graphLookup. 'db' must be the test database for either the replica set
|
|
* primary or mongos instance. 'secondary' is the shard/replica set secondary. If 'db' is backed
|
|
* by a mongos instance then the associated cluster should have only a single shard. 'rst' is the
|
|
* ReplSetTest instance associated with the replica set/shard.
|
|
*/
|
|
|
|
import {restartServerReplication, stopServerReplication} from "jstests/libs/write_concern_util.js";
|
|
|
|
export function testReadCommittedLookup(db, secondary, rst) {
|
|
/**
|
|
* stopServerReplication uses the 'stopReplProducer' fail point to stop server replication on
|
|
* the given secondary.
|
|
*/
|
|
function pauseReplication(sec) {
|
|
stopServerReplication(sec);
|
|
}
|
|
|
|
/**
|
|
* Turns off the 'stopReplProducer' fail point to resume server replication on the
|
|
* given secondary.
|
|
*/
|
|
function resumeReplication(sec) {
|
|
restartServerReplication(sec);
|
|
}
|
|
|
|
const aggCmdLookupObj = {
|
|
aggregate: "local",
|
|
pipeline: [
|
|
{
|
|
$lookup: {
|
|
from: "foreign",
|
|
localField: "foreignKey",
|
|
foreignField: "matchedField",
|
|
as: "match",
|
|
},
|
|
},
|
|
],
|
|
cursor: {},
|
|
readConcern: {
|
|
level: "majority",
|
|
},
|
|
};
|
|
|
|
const aggCmdGraphLookupObj = {
|
|
aggregate: "local",
|
|
pipeline: [
|
|
{
|
|
$graphLookup: {
|
|
from: "foreign",
|
|
startWith: "$foreignKey",
|
|
connectFromField: "foreignKey",
|
|
connectToField: "matchedField",
|
|
as: "match",
|
|
},
|
|
},
|
|
],
|
|
cursor: {},
|
|
readConcern: {
|
|
level: "majority",
|
|
},
|
|
};
|
|
|
|
// Seed matching data.
|
|
const majorityWriteConcernObj = {writeConcern: {w: "majority", wtimeout: 60 * 1000}};
|
|
db.local.deleteMany({}, majorityWriteConcernObj);
|
|
const localId = db.local.insertOne({foreignKey: "x"}, majorityWriteConcernObj).insertedId;
|
|
db.foreign.deleteMany({}, majorityWriteConcernObj);
|
|
const foreignId = db.foreign.insertOne({matchedField: "x"}, majorityWriteConcernObj).insertedId;
|
|
|
|
const expectedMatchedResult = [
|
|
{
|
|
_id: localId,
|
|
foreignKey: "x",
|
|
match: [{_id: foreignId, matchedField: "x"}],
|
|
},
|
|
];
|
|
const expectedUnmatchedResult = [
|
|
{
|
|
_id: localId,
|
|
foreignKey: "x",
|
|
match: [],
|
|
},
|
|
];
|
|
|
|
// Confirm lookup/graphLookup return the matched result.
|
|
let result = assert.commandWorked(db.runCommand(aggCmdLookupObj)).cursor.firstBatch;
|
|
assert.eq(result, expectedMatchedResult);
|
|
|
|
result = assert.commandWorked(db.runCommand(aggCmdGraphLookupObj)).cursor.firstBatch;
|
|
assert.eq(result, expectedMatchedResult);
|
|
|
|
// Run finds on the two collections to ensure that no background tasks can trigger refreshes on
|
|
// the primary.
|
|
assert.commandWorked(db.runCommand({find: "local", $readPreference: {mode: "secondary"}}));
|
|
assert.commandWorked(db.runCommand({find: "foreign", $readPreference: {mode: "secondary"}}));
|
|
|
|
// Stop oplog application on the secondary so that it won't acknowledge updates.
|
|
pauseReplication(secondary);
|
|
|
|
// Update foreign data to no longer match, without a majority write concern.
|
|
db.foreign.updateOne({_id: foreignId}, {$set: {matchedField: "non-match"}});
|
|
|
|
// lookup/graphLookup should not see the update, since it has not been acknowledged by the
|
|
// secondary.
|
|
result = assert.commandWorked(db.runCommand(aggCmdLookupObj)).cursor.firstBatch;
|
|
assert.eq(result, expectedMatchedResult);
|
|
|
|
result = assert.commandWorked(db.runCommand(aggCmdGraphLookupObj)).cursor.firstBatch;
|
|
assert.eq(result, expectedMatchedResult);
|
|
|
|
// Restart oplog application on the secondary and wait for it's snapshot to catch up.
|
|
resumeReplication(secondary);
|
|
rst.awaitLastOpCommitted();
|
|
|
|
// Now lookup/graphLookup should report that the documents don't match.
|
|
result = assert.commandWorked(db.runCommand(aggCmdLookupObj)).cursor.firstBatch;
|
|
assert.eq(result, expectedUnmatchedResult);
|
|
|
|
result = assert.commandWorked(db.runCommand(aggCmdGraphLookupObj)).cursor.firstBatch;
|
|
assert.eq(result, expectedUnmatchedResult);
|
|
}
|