Files
mongo/jstests/multiVersion/genericBinVersion/upgrade_during_vectored_insert.js
Steve McClure cf59a46893 SERVER-87891: Move targeted multiversion tests (#41621)
GitOrigin-RevId: 04a80da842c063cbe06c45da01572ac690794f17
2025-09-24 19:21:00 +00:00

87 lines
3.3 KiB
JavaScript

/**
* Verifies that if we do an upgrade during a vectored insert that fails during batch application
* that it will not succeed. A regression test for BF-32345.
*/
import "jstests/multiVersion/libs/multi_rs.js";
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
import {Thread} from "jstests/libs/parallelTester.js";
import {ReplSetTest} from "jstests/libs/replsettest.js";
("use strict");
const latestVersion = "latest";
const rst = new ReplSetTest({name: jsTestName(), nodes: [{binVersion: latestVersion}, {binVersion: latestVersion}]});
rst.startSet();
rst.initiate();
const primary = rst.getPrimary();
const testDB = primary.getDB("test");
const testColl = testDB.testColl;
// Start in downgrade FCV,
jsTestLog("Downgrading FCV");
assert.commandWorked(testDB.adminCommand({setFeatureCompatibilityVersion: lastLTSFCV, confirm: true}));
// Insert a document to cause an error in batch insertion
assert.commandWorked(testColl.insert([{"_id": "5"}]));
// Switch to upgrade FCV first. We have to stop this in the middle so we can get the collmods in
// _upgradeServerMetadata to finish before allowing FCV to actually change. This is a very
// unlikely race!
let upgradeFp = configureFailPoint(primary, "hangWhileUpgrading");
jsTestLog("Switching to upgrade FCV");
let upgradeFCVThread = new Thread(function (host) {
let conn = new Mongo(host);
assert.commandWorked(conn.adminCommand({setFeatureCompatibilityVersion: latestFCV, confirm: true}));
}, primary.host);
upgradeFCVThread.start();
upgradeFp.wait();
// We'll pause the insert while we're inserting documents one-by-one, after inserting "2".
let insertFp = configureFailPoint(primary, "hangAfterCollectionInserts", {
last_id: "2",
collectionNS: testColl.getFullName(),
});
let insertThread = new Thread(
function (host, testCollFullName) {
// Disabling the session here means fewer things to block FCV.
TestData.disableImplicitSessions = true;
assert(jsTest.options().disableImplicitSessions);
let conn = new Mongo(host);
let testColl = conn.getCollection(testCollFullName);
// Run a batch that will fail on the last document due to a DuplicateKeyError.
jsTestLog("Inserting data");
let res = testColl.insert([{"_id": "1"}, {"_id": "2"}, {"_id": "3"}, {"_id": "4"}, {"_id": "5", new: 1}]);
assert.eq(4, res.nInserted);
printjson(res);
},
primary.host,
testColl.getFullName(),
);
insertThread.start();
insertFp.wait();
// Now we're in an intermediate FCV with an insert running having already checked its FCV in
// insertDocumentsAtomically. We'll let the upgrade continue now.
jsTestLog("Allowing upgrade to finish");
assert.commandWorked(primary.adminCommand({clearLog: "global"}));
upgradeFp.off();
// The FCV command will get stuck on another collMod, so we only wait here for the FCV to be set,
// not for the command to finish.
checkLog.containsJson(primary, 5853300, {featureCompatibilityVersion: latestFCV});
// Now let the insert continue in the new FCV.
jsTestLog("Allowing insert to finish");
insertFp.off();
insertThread.join();
upgradeFCVThread.join();
assert.docEq(testColl.find({}).sort({_id: 1}).toArray(), [
{"_id": "1"},
{"_id": "2"},
{"_id": "3"},
{"_id": "4"},
{"_id": "5"},
]);
rst.stopSet();