mirror of https://github.com/mongodb/mongo
128 lines
4.8 KiB
JavaScript
128 lines
4.8 KiB
JavaScript
/**
|
|
* Tests createIndexes returns the expected tenant migration error or succeeds when sent through
|
|
* mongoq after a tenant migration commits or aborts.
|
|
*
|
|
* @tags: [requires_fcv_52, serverless]
|
|
*/
|
|
|
|
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
|
|
import {Thread} from "jstests/libs/parallelTester.js";
|
|
import {ShardedServerlessTest} from "jstests/serverless/libs/sharded_serverless_test.js";
|
|
|
|
// A function, not a constant, to ensure unique UUIDs.
|
|
function donorStartMigrationCmd(tenantID, realConnUrl) {
|
|
return {
|
|
donorStartMigration: 1,
|
|
tenantId: tenantID.str,
|
|
migrationId: UUID(),
|
|
recipientConnectionString: realConnUrl,
|
|
readPreference: {mode: "primary"}
|
|
};
|
|
}
|
|
|
|
let createIndexesCmd = {createIndexes: "foo", indexes: [{key: {x: 1}, name: "x_1"}]};
|
|
|
|
let st = new ShardedServerlessTest();
|
|
let donor = st.rs0;
|
|
let recipient = st.rs1;
|
|
let mongoq = st.q0;
|
|
let adminDB = donor.getPrimary().getDB('admin');
|
|
|
|
(() => {
|
|
jsTest.log("Starting test calling createIndexes after the migration has committed.");
|
|
const kTenantID = ObjectId();
|
|
const kDbName = kTenantID.str + "_testDB";
|
|
let db = mongoq.getDB(kDbName);
|
|
|
|
assert.commandWorked(
|
|
mongoq.adminCommand({enableSharding: kDbName, primaryShard: st.shard0.shardName}));
|
|
|
|
// Run donorStartMigration command to start migration and poll the migration status with the
|
|
// same command object.
|
|
let startMigrationCmd = donorStartMigrationCmd(kTenantID, recipient.getURL());
|
|
assert.soon(function() {
|
|
let res = assert.commandWorked(adminDB.runCommand(startMigrationCmd));
|
|
return res['state'] == "committed";
|
|
}, "migration not in committed state", 1 * 10000, 1 * 1000);
|
|
|
|
assert.commandFailedWithCode(db.runCommand(createIndexesCmd),
|
|
ErrorCodes.TenantMigrationCommitted);
|
|
})();
|
|
|
|
(() => {
|
|
jsTest.log("Starting test calling createIndexes after the migration has aborted.");
|
|
const kTenantID = ObjectId();
|
|
const kDbName = kTenantID.str + "_testDB";
|
|
let db = mongoq.getDB(kDbName);
|
|
|
|
assert.commandWorked(
|
|
mongoq.adminCommand({enableSharding: kDbName, primaryShard: st.shard0.shardName}));
|
|
|
|
let abortFailPoint =
|
|
configureFailPoint(adminDB, "abortTenantMigrationBeforeLeavingBlockingState");
|
|
|
|
let startMigrationCmd = donorStartMigrationCmd(kTenantID, recipient.getURL());
|
|
assert.soon(function() {
|
|
let res = assert.commandWorked(adminDB.runCommand(startMigrationCmd));
|
|
return res['state'] == "aborted";
|
|
}, "migration not in aborted state", 1 * 10000, 1 * 1000);
|
|
|
|
assert.commandWorked(db.runCommand(createIndexesCmd));
|
|
|
|
abortFailPoint.off();
|
|
})();
|
|
|
|
(() => {
|
|
jsTest.log("Starting test calling createIndexes during migration blocking state then aborts.");
|
|
const kTenantID = ObjectId();
|
|
const kDbName = kTenantID.str + "_testDB";
|
|
|
|
assert.commandWorked(
|
|
mongoq.adminCommand({enableSharding: kDbName, primaryShard: st.shard0.shardName}));
|
|
|
|
let blockingFailPoint =
|
|
configureFailPoint(adminDB, "pauseTenantMigrationBeforeLeavingBlockingState");
|
|
let abortFailPoint =
|
|
configureFailPoint(adminDB, "abortTenantMigrationBeforeLeavingBlockingState");
|
|
|
|
// Start the migration asynchronously and then immediately return the current state of the
|
|
// migration.
|
|
let startMigrationCmd = donorStartMigrationCmd(kTenantID, recipient.getURL());
|
|
assert.commandWorked(adminDB.runCommand(startMigrationCmd));
|
|
|
|
blockingFailPoint.wait();
|
|
|
|
// Send createIndexes command to mongoq in an individual thread.
|
|
let createIndexesThread = new Thread((mongoqConnString, kDbName, createIndexesCmd) => {
|
|
let mongoqConn = new Mongo(mongoqConnString);
|
|
// Expect to receive an ok response for the createIndexes command.
|
|
assert.commandWorked(mongoqConn.getDB(kDbName).runCommand(createIndexesCmd));
|
|
}, st.q0.host, kDbName, createIndexesCmd);
|
|
createIndexesThread.start();
|
|
|
|
// Poll the numBlockedWrites of tenant migration access blocker from donor and expect it's
|
|
// increased by the blocked createIndexes command.
|
|
assert.soon(function() {
|
|
let mtab = donor.getPrimary()
|
|
.getDB('admin')
|
|
.adminCommand({serverStatus: 1})
|
|
.tenantMigrationAccessBlocker[kTenantID.str]
|
|
.donor;
|
|
return mtab.numBlockedWrites > 0;
|
|
}, "no blocked writes found", 1 * 10000, 1 * 1000);
|
|
|
|
blockingFailPoint.off();
|
|
|
|
// Expect to get aborted state when polling the migration state from donor.
|
|
assert.soon(function() {
|
|
let res = assert.commandWorked(adminDB.runCommand(startMigrationCmd));
|
|
return res['state'] == "aborted";
|
|
}, "migration not in aborted state", 1 * 10000, 1 * 1000);
|
|
|
|
createIndexesThread.join();
|
|
|
|
abortFailPoint.off();
|
|
})();
|
|
|
|
st.stop();
|