summaryrefslogtreecommitdiff
path: root/jstests
diff options
context:
space:
mode:
authorChristopher Caplinger <christopher.caplinger@mongodb.com>2022-08-15 17:59:10 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-15 19:25:35 +0000
commite455a0fa9c571753bf07d4c951bfbf881005c3a7 (patch)
treeaaf4cbecd9251f68b6ddaac2513b11e7b55da9f6 /jstests
parent2c701bf03543d9feaad6ba3faf7851bb26d0ee30 (diff)
downloadmongo-e455a0fa9c571753bf07d4c951bfbf881005c3a7.tar.gz
SERVER-63454: Don't require tenantId for shard merge
Diffstat (limited to 'jstests')
-rw-r--r--jstests/auth/lib/commands_lib.js8
-rw-r--r--jstests/replsets/libs/tenant_migration_test.js33
-rw-r--r--jstests/replsets/libs/tenant_migration_util.js13
-rw-r--r--jstests/replsets/tenant_migration_advance_stable_ts_after_clone.js5
-rw-r--r--jstests/replsets/tenant_migration_buildindex_shard_merge.js5
-rw-r--r--jstests/replsets/tenant_migration_concurrent_migrations.js2
-rw-r--r--jstests/replsets/tenant_migration_concurrent_migrations_stress_test.js12
-rw-r--r--jstests/replsets/tenant_migration_concurrent_reads_on_donor.js10
-rw-r--r--jstests/replsets/tenant_migration_concurrent_reads_on_recipient.js4
-rw-r--r--jstests/replsets/tenant_migration_concurrent_writes_on_recipient.js12
-rw-r--r--jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js116
-rw-r--r--jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js4
-rw-r--r--jstests/replsets/tenant_migration_donor_shutdown_while_blocking_reads.js2
-rw-r--r--jstests/replsets/tenant_migration_donor_state_machine.js15
-rw-r--r--jstests/replsets/tenant_migration_donor_unblock_reads_and_writes_on_completion.js9
-rw-r--r--jstests/replsets/tenant_migration_drop_state_doc_collection.js9
-rw-r--r--jstests/replsets/tenant_migration_fetch_committed_transactions_shard_merge.js2
-rw-r--r--jstests/replsets/tenant_migration_invalid_inputs.js39
-rw-r--r--jstests/replsets/tenant_migration_recipient_aborts_merge_on_donor_failure.js2
-rw-r--r--jstests/replsets/tenant_migration_recipient_current_op.js20
-rw-r--r--jstests/replsets/tenant_migration_recipient_rollback_recovery.js13
-rw-r--r--jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js16
-rw-r--r--jstests/replsets/tenant_migration_recipient_shard_merge_oplog_catchup.js4
-rw-r--r--jstests/replsets/tenant_migration_recipient_vote_imported_files.js1
-rw-r--r--jstests/replsets/tenant_migration_shard_merge_import_write_conflict_retry.js2
-rw-r--r--jstests/replsets/tenant_migration_shard_merge_invalid_inputs.js162
-rw-r--r--jstests/replsets/tenant_migration_shard_merge_recipient_creates_blockers_during_migration.js2
-rw-r--r--jstests/replsets/tenant_migration_shard_merge_recipient_current_op.js5
-rw-r--r--jstests/replsets/tenant_migration_timeseries_retryable_write_oplog_cloning.js5
-rw-r--r--jstests/replsets/tenant_migrations_back_to_back.js4
30 files changed, 340 insertions, 196 deletions
diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js
index e809bcbc427..99ef42720d5 100644
--- a/jstests/auth/lib/commands_lib.js
+++ b/jstests/auth/lib/commands_lib.js
@@ -3704,7 +3704,7 @@ var authCommandsLib = {
command: {
donorStartMigration: 1,
protocol: isShardMergeEnabled ? "shard merge" : "multitenant migrations",
- tenantId: "testTenantId",
+ tenantId: isShardMergeEnabled ? "" : "testTenantId",
migrationId: UUID(),
recipientConnectionString: "recipient-rs/localhost:1234",
readPreference: {mode: "primary"},
@@ -3730,7 +3730,8 @@ var authCommandsLib = {
recipientSyncData: 1,
migrationId: UUID(),
donorConnectionString: "donor-rs/localhost:1234",
- tenantId: "testTenantId",
+ protocol: isShardMergeEnabled ? "shard merge" : "multitenant migrations",
+ tenantId: isShardMergeEnabled ? "" : "testTenantId",
readPreference: {mode: "primary"},
startMigrationDonorTimestamp: Timestamp(1, 1),
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
@@ -3754,7 +3755,8 @@ var authCommandsLib = {
recipientForgetMigration: 1,
migrationId: UUID(),
donorConnectionString: "donor-rs/localhost:1234",
- tenantId: "testTenantId",
+ protocol: isShardMergeEnabled ? "shard merge" : "multitenant migrations",
+ tenantId: isShardMergeEnabled ? "" : "testTenantId",
readPreference: {mode: "primary"},
},
skipSharded: true,
diff --git a/jstests/replsets/libs/tenant_migration_test.js b/jstests/replsets/libs/tenant_migration_test.js
index e1d4b472dff..04619679e33 100644
--- a/jstests/replsets/libs/tenant_migration_test.js
+++ b/jstests/replsets/libs/tenant_migration_test.js
@@ -204,10 +204,9 @@ function TenantMigrationTest({
this.waitForMigrationToComplete = function(
migrationOpts, retryOnRetryableErrors = false, forgetMigration = false) {
// Assert that the migration has already been started.
- const tenantId = migrationOpts.tenantId;
- assert(this.getDonorPrimary()
- .getCollection(TenantMigrationTest.kConfigDonorsNS)
- .findOne({tenantId}));
+ assert(this.getDonorPrimary().getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
+ _id: UUID(migrationOpts.migrationIdString)
+ }));
const donorStartReply = this.runDonorStartMigration(
migrationOpts, {waitForMigrationToComplete: true, retryOnRetryableErrors});
@@ -246,12 +245,12 @@ function TenantMigrationTest({
const cmdObj = {
donorStartMigration: 1,
- tenantId,
migrationId: UUID(migrationIdString),
+ tenantId,
recipientConnectionString,
readPreference,
donorCertificateForRecipient,
- recipientCertificateForDonor
+ recipientCertificateForDonor,
};
const stateRes = TenantMigrationUtil.runTenantMigrationCommand(cmdObj, this.getDonorRst(), {
@@ -440,7 +439,7 @@ function TenantMigrationTest({
assert.soon(
() => {
result = this.isRecipientNodeInExpectedState(
- node, migrationId, tenantId, expectedState, expectedAccessState);
+ {node, migrationId, tenantId, expectedState, expectedAccessState});
return result.value;
},
() => {
@@ -458,11 +457,16 @@ function TenantMigrationTest({
* Asserts that the migration 'migrationId' and 'tenantId' is in the expected state on all the
* given recipient nodes.
*/
- this.assertRecipientNodesInExpectedState = function(
- nodes, migrationId, tenantId, expectedState, expectedAccessState) {
+ this.assertRecipientNodesInExpectedState = function({
+ nodes,
+ migrationId,
+ tenantId,
+ expectedState,
+ expectedAccessState,
+ }) {
nodes.forEach(node => {
let result = this.isRecipientNodeInExpectedState(
- node, migrationId, tenantId, expectedState, expectedAccessState);
+ {node, migrationId, tenantId, expectedState, expectedAccessState});
assert(result.value, () => {
return "assertRecipientNodesInExpectedState failed: " +
buildErrorMsg(migrationId,
@@ -478,8 +482,13 @@ function TenantMigrationTest({
* Returns true if the durable and in-memory state for the migration 'migrationId' and
* 'tenantId' is in the expected state, and false otherwise.
*/
- this.isRecipientNodeInExpectedState = function(
- node, migrationId, tenantId, expectedState, expectedAccessState) {
+ this.isRecipientNodeInExpectedState = function({
+ node,
+ migrationId,
+ tenantId,
+ expectedState,
+ expectedAccessState,
+ }) {
const configRecipientsColl =
this.getRecipientPrimary().getCollection("config.tenantMigrationRecipients");
const configDoc = configRecipientsColl.findOne({_id: migrationId});
diff --git a/jstests/replsets/libs/tenant_migration_util.js b/jstests/replsets/libs/tenant_migration_util.js
index d5b62fac17f..d0e9354f1c1 100644
--- a/jstests/replsets/libs/tenant_migration_util.js
+++ b/jstests/replsets/libs/tenant_migration_util.js
@@ -39,9 +39,14 @@ var TenantMigrationUtil = (function() {
* flag is enabled.
*/
function donorStartMigrationWithProtocol(cmd, db) {
- // If we don't pass "protocol", the server uses "multitenant migrations" by default.
- if (cmd['protocol'] === undefined && isShardMergeEnabled(db)) {
- return Object.assign(Object.assign({}, cmd), {protocol: "shard merge"});
+ // If we don't pass "protocol" and shard merge is enabled, we set the protocol to
+ // "shard merge". Otherwise, the provided protocol is used, which defaults to
+ // "multitenant migrations" if not provided.
+ if (cmd["protocol"] === undefined && isShardMergeEnabled(db)) {
+ const cmdCopy = Object.assign({}, cmd);
+ delete cmdCopy.tenantId;
+ cmdCopy.protocol = "shard merge";
+ return cmdCopy;
}
return cmd;
@@ -139,8 +144,8 @@ var TenantMigrationUtil = (function() {
const cmdObj = {
donorStartMigration: 1,
migrationId: UUID(migrationOpts.migrationIdString),
- recipientConnectionString: migrationOpts.recipientConnString,
tenantId: migrationOpts.tenantId,
+ recipientConnectionString: migrationOpts.recipientConnString,
readPreference: migrationOpts.readPreference || {mode: "primary"},
donorCertificateForRecipient: migrationOpts.donorCertificateForRecipient ||
migrationCertificates.donorCertificateForRecipient,
diff --git a/jstests/replsets/tenant_migration_advance_stable_ts_after_clone.js b/jstests/replsets/tenant_migration_advance_stable_ts_after_clone.js
index 56d75a3ada8..edff60a2879 100644
--- a/jstests/replsets/tenant_migration_advance_stable_ts_after_clone.js
+++ b/jstests/replsets/tenant_migration_advance_stable_ts_after_clone.js
@@ -26,15 +26,14 @@ const kTenantIdPrefix = "testTenantId";
const kUnrelatedDbNameDonor = "unrelatedDBDonor";
const kUnrelatedDbNameRecipient = "unrelatedDBRecipient";
const collName = "foo";
-const tenantId = kTenantIdPrefix + "-0";
+const tenantId = `${kTenantIdPrefix}-0`;
const migrationId = UUID();
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationId),
- tenantId: tenantId,
};
const tmt = new TenantMigrationTest({name: jsTestName()});
-tmt.insertDonorDB(tenantId + "_db", collName);
+tmt.insertDonorDB(`${tenantId}_db`, collName);
const donorPrimary = tmt.getDonorPrimary();
const recipientPrimary = tmt.getRecipientPrimary();
diff --git a/jstests/replsets/tenant_migration_buildindex_shard_merge.js b/jstests/replsets/tenant_migration_buildindex_shard_merge.js
index e18e266ed36..03b51100ca3 100644
--- a/jstests/replsets/tenant_migration_buildindex_shard_merge.js
+++ b/jstests/replsets/tenant_migration_buildindex_shard_merge.js
@@ -50,11 +50,9 @@ function createIndexShouldFail(primaryHost, dbName, collName, indexSpec) {
}
const migrationId = UUID();
-// TODO (SERVER-63454): remove tenantId, and remove kTenant2DbName, db2, tenant2IndexThread, etc.
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationId),
recipientConnString: tenantMigrationTest.getRecipientConnString(),
- tenantId: kTenant1Id,
};
const donorRstArgs = TenantMigrationUtil.createRstArgs(tenantMigrationTest.getDonorRst());
@@ -74,9 +72,6 @@ var initFpCount =
.count;
const tenant1IndexThread =
new Thread(createIndexShouldFail, donorPrimary.host, kTenant1DbName, kNonEmptyCollName, {b: 1});
-// Even though tenantId1 is passed to donorStartMigration, the donor aborts this index too
-// because protocol is "shard merge".
-// TODO (SERVER-63454): remove comment above.
const tenant2IndexThread =
new Thread(createIndexShouldFail, donorPrimary.host, kTenant2DbName, kNonEmptyCollName, {y: 1});
tenant1IndexThread.start();
diff --git a/jstests/replsets/tenant_migration_concurrent_migrations.js b/jstests/replsets/tenant_migration_concurrent_migrations.js
index 752c18fffca..ef8d7638f68 100644
--- a/jstests/replsets/tenant_migration_concurrent_migrations.js
+++ b/jstests/replsets/tenant_migration_concurrent_migrations.js
@@ -152,7 +152,7 @@ const kTenantIdPrefix = "testTenantId";
const connPoolStatsBefore = assert.commandWorked(donorPrimary.adminCommand({connPoolStats: 1}));
- let blockFp = configureFailPoint(
+ const blockFp = configureFailPoint(
donorPrimary, "pauseTenantMigrationBeforeLeavingBlockingState", {tenantId: tenantId1});
assert.commandWorked(tenantMigrationTest0.startMigration(migrationOpts0));
assert.commandWorked(tenantMigrationTest1.startMigration(migrationOpts1));
diff --git a/jstests/replsets/tenant_migration_concurrent_migrations_stress_test.js b/jstests/replsets/tenant_migration_concurrent_migrations_stress_test.js
index 18c41480f70..3f95d39fe99 100644
--- a/jstests/replsets/tenant_migration_concurrent_migrations_stress_test.js
+++ b/jstests/replsets/tenant_migration_concurrent_migrations_stress_test.js
@@ -1,9 +1,13 @@
/**
* Stress test runs many concurrent migrations against the same recipient.
+ *
+ * TODO SERVER-61231: shard merge can't handle concurrent migrations.
+ *
* @tags: [
* incompatible_with_amazon_linux,
* incompatible_with_macos,
* incompatible_with_windows_tls,
+ * incompatible_with_shard_merge,
* requires_majority_read_concern,
* requires_persistence,
* serverless,
@@ -45,14 +49,6 @@ const tenantMigrationTest = new TenantMigrationTest({
const donorPrimary = tenantMigrationTest.getDonorPrimary();
const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
-if (TenantMigrationUtil.isShardMergeEnabled(donorPrimary.getDB("admin"))) {
- // This test runs multiple concurrent migrations, which shard merge can't handle.
- jsTestLog(
- "Skip: featureFlagShardMerge is enabled and this test runs multiple concurrent migrations, which shard merge can't handle.");
- tenantMigrationTest.stop();
- return;
-}
-
setLogVerbosity([donorPrimary, recipientPrimary], {
"tenantMigration": {"verbosity": 0},
"replication": {"verbosity": 0},
diff --git a/jstests/replsets/tenant_migration_concurrent_reads_on_donor.js b/jstests/replsets/tenant_migration_concurrent_reads_on_donor.js
index 8d61e04c981..360c7a4276d 100644
--- a/jstests/replsets/tenant_migration_concurrent_reads_on_donor.js
+++ b/jstests/replsets/tenant_migration_concurrent_reads_on_donor.js
@@ -125,7 +125,7 @@ function testRejectReadsAfterMigrationCommitted(testCase, dbName, collName) {
donorRst.awaitLastOpCommitted();
const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationIdString),
});
const nodes = testCase.isSupportedOnSecondaries ? donorRst.nodes : [donorPrimary];
nodes.forEach(node => {
@@ -181,7 +181,7 @@ function testDoNotRejectReadsAfterMigrationAborted(testCase, dbName, collName) {
donorRst.awaitLastOpCommitted();
const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationIdString),
});
const nodes = testCase.isSupportedOnSecondaries ? donorRst.nodes : [donorPrimary];
nodes.forEach(node => {
@@ -234,7 +234,7 @@ function testBlockReadsAfterMigrationEnteredBlocking(testCase, dbName, collName)
donorRst.awaitLastOpCommitted();
const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationIdString),
});
const command = testCase.requiresReadTimestamp
? testCase.command(collName, donorDoc.blockTimestamp)
@@ -297,7 +297,7 @@ function testRejectBlockedReadsAfterMigrationCommitted(testCase, dbName, collNam
donorRst.awaitLastOpCommitted();
const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationIdString),
});
const command = testCase.requiresReadTimestamp
? testCase.command(collName, donorDoc.blockTimestamp)
@@ -365,7 +365,7 @@ function testUnblockBlockedReadsAfterMigrationAborted(testCase, dbName, collName
donorRst.awaitLastOpCommitted();
const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationIdString),
});
const command = testCase.requiresReadTimestamp
? testCase.command(collName, donorDoc.blockTimestamp)
diff --git a/jstests/replsets/tenant_migration_concurrent_reads_on_recipient.js b/jstests/replsets/tenant_migration_concurrent_reads_on_recipient.js
index 71d12c1f044..0867c371d9f 100644
--- a/jstests/replsets/tenant_migration_concurrent_reads_on_recipient.js
+++ b/jstests/replsets/tenant_migration_concurrent_reads_on_recipient.js
@@ -131,7 +131,7 @@ function testRejectOnlyReadsWithAtClusterTimeLessThanRejectReadsBeforeTimestamp(
const recipientDoc =
recipientPrimary.getCollection(TenantMigrationTest.kConfigRecipientsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationOpts.migrationIdString),
});
assert.lt(preMigrationTimestamp, recipientDoc.rejectReadsBeforeTimestamp);
@@ -276,7 +276,7 @@ function testDoNotRejectReadsAfterMigrationAbortedAfterReachingRejectReadsBefore
const recipientDoc =
recipientPrimary.getCollection(TenantMigrationTest.kConfigRecipientsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationOpts.migrationIdString),
});
const nodes = testCase.isSupportedOnSecondaries ? recipientRst.nodes : [recipientPrimary];
diff --git a/jstests/replsets/tenant_migration_concurrent_writes_on_recipient.js b/jstests/replsets/tenant_migration_concurrent_writes_on_recipient.js
index a1196fd3eff..cdd870c6c37 100644
--- a/jstests/replsets/tenant_migration_concurrent_writes_on_recipient.js
+++ b/jstests/replsets/tenant_migration_concurrent_writes_on_recipient.js
@@ -41,12 +41,12 @@ function cleanup(dbName) {
const tenantId = `${kTenantId}Commit`;
const donorDB = `${tenantId}_test`;
tenantMigrationTest.insertDonorDB(donorDB, "test");
- const ns = tenantId + "_testDb.testColl";
+ const ns = `${tenantId}_testDb.testColl`;
const tenantCollOnRecipient = recipientPrimary.getCollection(ns);
const migrationOpts = {
migrationIdString: extractUUIDFromObject(UUID()),
- tenantId: tenantId,
+ tenantId,
recipientConnString: tenantMigrationTest.getRecipientConnString(),
};
@@ -108,12 +108,12 @@ function cleanup(dbName) {
const tenantId = `${kTenantId}AbortBeforeReturnAfterReachingTs`;
const donorDB = `${tenantId}_test`;
tenantMigrationTest.insertDonorDB(donorDB, "test");
- const ns = tenantId + "_testDb.testColl";
+ const ns = `${tenantId}_testDb.testColl`;
const tenantCollOnRecipient = recipientPrimary.getCollection(ns);
const migrationOpts = {
migrationIdString: extractUUIDFromObject(UUID()),
- tenantId: tenantId,
+ tenantId,
recipientConnString: tenantMigrationTest.getRecipientConnString(),
};
@@ -150,12 +150,12 @@ function cleanup(dbName) {
const tenantId = `${kTenantId}AbortAfterReturnAfterReachingTs`;
const donorDB = `${tenantId}_test`;
tenantMigrationTest.insertDonorDB(donorDB, "test");
- const ns = tenantId + "_testDb.testColl";
+ const ns = `${tenantId}_testDb.testColl`;
const tenantCollOnRecipient = recipientPrimary.getCollection(ns);
const migrationOpts = {
migrationIdString: extractUUIDFromObject(UUID()),
- tenantId: kTenantId + "AbortAfterReturnAfterReachingTs",
+ tenantId: `${kTenantId}AbortAfterReturnAfterReachingTs`,
recipientConnString: tenantMigrationTest.getRecipientConnString(),
};
diff --git a/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js b/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js
index 053b98c41e4..ed21502a4b4 100644
--- a/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js
+++ b/jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js
@@ -16,13 +16,16 @@
load("jstests/libs/uuid_util.js");
load("jstests/replsets/libs/tenant_migration_test.js");
+function getRecipientSyncDataMetrics(recipientPrimary) {
+ return recipientPrimary.adminCommand({serverStatus: 1}).metrics.commands.recipientSyncData;
+}
+
/**
* Asserts that the number of recipientDataSync commands executed on the given recipient primary is
* equal to the given number.
*/
function checkNumRecipientSyncDataCmdExecuted(recipientPrimary, expectedNumExecuted) {
- const recipientSyncDataMetrics =
- recipientPrimary.adminCommand({serverStatus: 1}).metrics.commands.recipientSyncData;
+ const recipientSyncDataMetrics = getRecipientSyncDataMetrics(recipientPrimary);
assert.eq(0, recipientSyncDataMetrics.failed);
assert.eq(expectedNumExecuted, recipientSyncDataMetrics.total);
}
@@ -54,50 +57,43 @@ function generateUniqueTenantId() {
return kTenantIdPrefix + tenantCounter++;
}
-function setup() {
- const {donor: donorNodeOptions} = TenantMigrationUtil.makeX509OptionsForTest();
- donorNodeOptions.setParameter = donorNodeOptions.setParameter || {};
- Object.assign(donorNodeOptions.setParameter, {
- tenantMigrationGarbageCollectionDelayMS: 1 * 1000,
- ttlMonitorSleepSecs: 1,
- });
- const donorRst = new ReplSetTest({
- nodes: 1,
- name: 'donorRst',
- nodeOptions: donorNodeOptions,
- });
-
- donorRst.startSet();
- donorRst.initiate();
-
- const tenantMigrationTest =
- new TenantMigrationTest({name: jsTestName(), donorRst, quickGarbageCollection: true});
-
- const donorPrimary = donorRst.getPrimary();
- const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
-
- return {
- tenantMigrationTest,
- donorRst,
- donorPrimary,
- recipientPrimary,
- teardown: function() {
- tenantMigrationTest.stop();
- donorRst.stopSet();
- },
- };
+const {donor: donorNodeOptions} = TenantMigrationUtil.makeX509OptionsForTest();
+donorNodeOptions.setParameter = donorNodeOptions.setParameter || {};
+Object.assign(donorNodeOptions.setParameter, {
+ tenantMigrationGarbageCollectionDelayMS: 1 * 1000,
+ ttlMonitorSleepSecs: 1,
+});
+const donorRst = new ReplSetTest({
+ nodes: 1,
+ name: 'donorRst',
+ nodeOptions: donorNodeOptions,
+});
+
+donorRst.startSet();
+donorRst.initiate();
+
+const tenantMigrationTest =
+ new TenantMigrationTest({name: jsTestName(), donorRst, quickGarbageCollection: true});
+
+const donorPrimary = donorRst.getPrimary();
+const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
+
+function teardown() {
+ tenantMigrationTest.stop();
+ donorRst.stopSet();
}
// Test that a retry of a donorStartMigration command joins the existing migration that has
// completed but has not been garbage-collected.
(() => {
const tenantId = `${generateUniqueTenantId()}RetryAfterMigrationCompletes`;
+ const migrationId = UUID();
const migrationOpts = {
- migrationIdString: extractUUIDFromObject(UUID()),
+ migrationIdString: extractUUIDFromObject(migrationId),
tenantId,
};
- const {tenantMigrationTest, recipientPrimary, teardown} = setup();
+ const recipientSyncDataMetrics = getRecipientSyncDataMetrics(recipientPrimary);
TenantMigrationTest.assertCommitted(
tenantMigrationTest.runMigration(migrationOpts, {automaticForgetMigration: false}));
@@ -106,21 +102,22 @@ function setup() {
// If the second donorStartMigration had started a duplicate migration, the recipient would have
// received four recipientSyncData commands instead of two.
- checkNumRecipientSyncDataCmdExecuted(recipientPrimary, 2);
+ checkNumRecipientSyncDataCmdExecuted(recipientPrimary, recipientSyncDataMetrics.total + 2);
assert.commandWorked(tenantMigrationTest.forgetMigration(migrationOpts.migrationIdString));
- teardown();
+ tenantMigrationTest.waitForMigrationGarbageCollection(migrationId, tenantId);
})();
// Test that a retry of a donorStartMigration command joins the ongoing migration.
(() => {
const tenantId = `${generateUniqueTenantId()}RetryBeforeMigrationCompletes`;
+ const migrationId = UUID();
const migrationOpts = {
- migrationIdString: extractUUIDFromObject(UUID()),
+ migrationIdString: extractUUIDFromObject(migrationId),
tenantId,
};
- const {tenantMigrationTest, recipientPrimary, teardown} = setup();
+ const recipientSyncDataMetrics = getRecipientSyncDataMetrics(recipientPrimary);
assert.commandWorked(tenantMigrationTest.startMigration(migrationOpts));
assert.commandWorked(tenantMigrationTest.startMigration(migrationOpts));
@@ -132,10 +129,10 @@ function setup() {
// If the second donorStartMigration had started a duplicate migration, the recipient would have
// received four recipientSyncData commands instead of two.
- checkNumRecipientSyncDataCmdExecuted(recipientPrimary, 2);
+ checkNumRecipientSyncDataCmdExecuted(recipientPrimary, recipientSyncDataMetrics.total + 2);
assert.commandWorked(tenantMigrationTest.forgetMigration(migrationOpts.migrationIdString));
- teardown();
+ tenantMigrationTest.waitForMigrationGarbageCollection(migrationId, tenantId);
})();
/**
@@ -228,6 +225,8 @@ function testConcurrentConflictingMigrations({
tenantMigrationTest0.waitForMigrationToComplete(migrationOpts0));
assert.commandWorked(
tenantMigrationTest0.forgetMigration(migrationOpts0.migrationIdString));
+ tenantMigrationTest0.waitForMigrationGarbageCollection(migrationOpts0.migrationIdString,
+ migrationOpts0.tenantId);
} else {
assert.commandFailedWithCode(res0, ErrorCodes.ConflictingOperationInProgress);
assertNoCertificateOrPrivateKey(res0.errmsg);
@@ -250,12 +249,13 @@ function testConcurrentConflictingMigrations({
tenantMigrationTest1.waitForMigrationToComplete(migrationOpts1));
assert.commandWorked(
tenantMigrationTest1.forgetMigration(migrationOpts1.migrationIdString));
+ tenantMigrationTest1.waitForMigrationGarbageCollection(migrationOpts1.migrationIdString,
+ migrationOpts1.tenantId);
}
}
// Test migrations with different migrationIds but identical settings.
(() => {
- const {tenantMigrationTest, donorPrimary, teardown} = setup();
const makeTestParams = () => {
const migrationOpts0 = {
migrationIdString: extractUUIDFromObject(UUID()),
@@ -274,14 +274,18 @@ function testConcurrentConflictingMigrations({
testStartingConflictingMigrationAfterInitialMigrationCommitted(makeTestParams());
testConcurrentConflictingMigrations(makeTestParams());
- teardown();
})();
// Test reusing a migrationId for different migration settings.
// Test different tenantIds.
(() => {
- const {tenantMigrationTest, donorPrimary, teardown} = setup();
+ if (TenantMigrationUtil.isShardMergeEnabled(donorPrimary.getDB("admin"))) {
+ jsTestLog(
+ "Skip: featureFlagShardMerge is enabled and this test tests migrations with different tenant ids.");
+ return;
+ }
+
const makeTestParams = () => {
const migrationOpts0 = {
migrationIdString: extractUUIDFromObject(UUID()),
@@ -300,18 +304,10 @@ function testConcurrentConflictingMigrations({
testStartingConflictingMigrationAfterInitialMigrationCommitted(makeTestParams());
testConcurrentConflictingMigrations(makeTestParams());
- teardown();
})();
// Test different recipient connection strings.
(() => {
- const {
- tenantMigrationTest: tenantMigrationTest0,
- donorRst,
- donorPrimary,
- teardown,
- } = setup();
-
const tenantMigrationTest1 = new TenantMigrationTest({name: `${jsTestName()}1`, donorRst});
const makeTestParams = () => {
@@ -323,7 +319,7 @@ function testConcurrentConflictingMigrations({
// no need to set it here.
const migrationOpts1 = Object.extend({}, migrationOpts0, true);
return {
- tenantMigrationTest0,
+ tenantMigrationTest0: tenantMigrationTest,
migrationOpts0,
tenantMigrationTest1,
migrationOpts1,
@@ -335,13 +331,10 @@ function testConcurrentConflictingMigrations({
testConcurrentConflictingMigrations(makeTestParams());
tenantMigrationTest1.stop();
- teardown();
})();
// Test different cloning read preference.
(() => {
- const {tenantMigrationTest, donorPrimary, teardown} = setup();
-
const makeTestParams = () => {
const migrationOpts0 = {
migrationIdString: extractUUIDFromObject(UUID()),
@@ -360,7 +353,6 @@ function testConcurrentConflictingMigrations({
testStartingConflictingMigrationAfterInitialMigrationCommitted(makeTestParams());
testConcurrentConflictingMigrations(makeTestParams());
- teardown();
})();
const kDonorCertificateAndPrivateKey =
@@ -374,8 +366,6 @@ const kExpiredRecipientCertificateAndPrivateKey = TenantMigrationUtil.getCertifi
// Test different donor certificates.
(() => {
- const {tenantMigrationTest, donorPrimary, teardown} = setup();
-
const makeTestParams = () => {
const migrationOpts0 = {
migrationIdString: extractUUIDFromObject(UUID()),
@@ -396,13 +386,10 @@ const kExpiredRecipientCertificateAndPrivateKey = TenantMigrationUtil.getCertifi
testStartingConflictingMigrationAfterInitialMigrationCommitted(makeTestParams());
testConcurrentConflictingMigrations(makeTestParams());
- teardown();
})();
// Test different recipient certificates.
(() => {
- const {tenantMigrationTest, donorPrimary, teardown} = setup();
-
const makeTestParams = () => {
const migrationOpts0 = {
migrationIdString: extractUUIDFromObject(UUID()),
@@ -423,6 +410,7 @@ const kExpiredRecipientCertificateAndPrivateKey = TenantMigrationUtil.getCertifi
testStartingConflictingMigrationAfterInitialMigrationCommitted(makeTestParams());
testConcurrentConflictingMigrations(makeTestParams());
- teardown();
})();
+
+teardown();
})();
diff --git a/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js b/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js
index 38399baccf5..a8278e285dc 100644
--- a/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js
+++ b/jstests/replsets/tenant_migration_conflicting_recipient_sync_data_cmds.js
@@ -163,7 +163,7 @@ assert.commandWorked(primary.adminCommand({
// Only one instance should have succeeded in persisting the state doc, other should have failed
// with ErrorCodes.ConflictingOperationInProgress.
- assert.eq(1, configRecipientsColl.count({tenantId: tenantId}));
+ assert.eq(1, configRecipientsColl.count({}));
// Run another recipientSyncData cmd for the tenant. Since the previous migration hasn't been
// garbage collected, the migration is considered as active. So this command should fail with
@@ -176,7 +176,7 @@ assert.commandWorked(primary.adminCommand({
assert.commandFailedWithCode(res2, ErrorCodes.ConflictingOperationInProgress);
// Collection count should remain the same.
- assert.eq(1, configRecipientsColl.count({tenantId: tenantId}));
+ assert.eq(1, configRecipientsColl.count({}));
fpPauseBeforeRunTenantMigrationRecipientInstance.off();
})();
diff --git a/jstests/replsets/tenant_migration_donor_shutdown_while_blocking_reads.js b/jstests/replsets/tenant_migration_donor_shutdown_while_blocking_reads.js
index b55ba5cb6a2..f4e2106a07f 100644
--- a/jstests/replsets/tenant_migration_donor_shutdown_while_blocking_reads.js
+++ b/jstests/replsets/tenant_migration_donor_shutdown_while_blocking_reads.js
@@ -43,7 +43,7 @@ assert.commandWorked(tenantMigrationTest.startMigration(migrationOpts));
fp.wait();
const donorDoc =
- donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({tenantId: kTenantId});
+ donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({_id: migrationId});
assert.neq(null, donorDoc);
let readThread = new Thread((host, dbName, collName, afterClusterTime) => {
diff --git a/jstests/replsets/tenant_migration_donor_state_machine.js b/jstests/replsets/tenant_migration_donor_state_machine.js
index cd251bb6657..ba1e7d40fc0 100644
--- a/jstests/replsets/tenant_migration_donor_state_machine.js
+++ b/jstests/replsets/tenant_migration_donor_state_machine.js
@@ -50,7 +50,7 @@ function testDonorForgetMigrationAfterMigrationCompletes(
});
assert.soon(() => 0 === donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).count({
- tenantId: tenantId
+ _id: migrationId,
}));
assert.soon(() => 0 ===
donorPrimary.adminCommand({serverStatus: 1})
@@ -68,7 +68,7 @@ function testDonorForgetMigrationAfterMigrationCompletes(
assert.soon(() => 0 ===
recipientPrimary.getCollection(TenantMigrationTest.kConfigRecipientsNS).count({
- tenantId: tenantId
+ _id: migrationId,
}));
assert.soon(() => 0 ===
recipientPrimary.adminCommand({serverStatus: 1})
@@ -149,11 +149,10 @@ function testStats(node, {
assert.eq(mtab.donor.state, TenantMigrationTest.DonorAccessState.kBlockWritesAndReads);
assert(mtab.donor.blockTimestamp);
- let donorDoc = configDonorsColl.findOne({tenantId: kTenantId});
+ let donorDoc = configDonorsColl.findOne({_id: migrationId});
let blockOplogEntry =
donorPrimary.getDB("local")
- .oplog.rs
- .find({ns: TenantMigrationTest.kConfigDonorsNS, op: "u", "o.tenantId": kTenantId})
+ .oplog.rs.find({ns: TenantMigrationTest.kConfigDonorsNS, op: "u", "o._id": migrationId})
.sort({"$natural": -1})
.limit(1)
.next();
@@ -173,7 +172,7 @@ function testStats(node, {
TenantMigrationTest.assertCommitted(
tenantMigrationTest.waitForMigrationToComplete(migrationOpts));
- donorDoc = configDonorsColl.findOne({tenantId: kTenantId});
+ donorDoc = configDonorsColl.findOne({_id: migrationId});
let commitOplogEntry = donorPrimary.getDB("local").oplog.rs.findOne(
{ns: TenantMigrationTest.kConfigDonorsNS, op: "u", o: donorDoc});
assert.eq(donorDoc.state, TenantMigrationTest.DonorState.kCommitted);
@@ -215,7 +214,7 @@ function testStats(node, {
tenantMigrationTest.runMigration(migrationOpts, {automaticForgetMigration: false}));
abortRecipientFp.off();
- const donorDoc = configDonorsColl.findOne({tenantId: kTenantId});
+ const donorDoc = configDonorsColl.findOne({_id: migrationId});
const abortOplogEntry = donorPrimary.getDB("local").oplog.rs.findOne(
{ns: TenantMigrationTest.kConfigDonorsNS, op: "u", o: donorDoc});
assert.eq(donorDoc.state, TenantMigrationTest.DonorState.kAborted);
@@ -257,7 +256,7 @@ function testStats(node, {
tenantMigrationTest.runMigration(migrationOpts, {automaticForgetMigration: false}));
abortDonorFp.off();
- const donorDoc = configDonorsColl.findOne({tenantId: kTenantId});
+ const donorDoc = configDonorsColl.findOne({_id: migrationId});
const abortOplogEntry = donorPrimary.getDB("local").oplog.rs.findOne(
{ns: TenantMigrationTest.kConfigDonorsNS, op: "u", o: donorDoc});
assert.eq(donorDoc.state, TenantMigrationTest.DonorState.kAborted);
diff --git a/jstests/replsets/tenant_migration_donor_unblock_reads_and_writes_on_completion.js b/jstests/replsets/tenant_migration_donor_unblock_reads_and_writes_on_completion.js
index b1ca0dcc56c..40173bdeab8 100644
--- a/jstests/replsets/tenant_migration_donor_unblock_reads_and_writes_on_completion.js
+++ b/jstests/replsets/tenant_migration_donor_unblock_reads_and_writes_on_completion.js
@@ -107,7 +107,7 @@ const kCollName = "testColl";
// Run a read command against one of the secondaries, and wait for it to block.
const laggedSecondary = donorRst.getSecondary();
- const donorDoc = donorsColl.findOne({tenantId: tenantId});
+ const donorDoc = donorsColl.findOne({_id: migrationId});
assert.neq(null, donorDoc);
const readThread = startReadThread(laggedSecondary, dbName, kCollName, donorDoc.blockTimestamp);
assert.soon(() => TenantMigrationUtil.getNumBlockedReads(laggedSecondary, tenantId) == 1);
@@ -155,7 +155,7 @@ const kCollName = "testColl";
// Run a read command against one of the secondaries, and wait for it to block.
const laggedSecondary = donorRst.getSecondary();
- const donorDoc = donorsColl.findOne({tenantId: tenantId});
+ const donorDoc = donorsColl.findOne({_id: migrationId});
assert.neq(null, donorDoc);
const readThread = startReadThread(laggedSecondary, dbName, kCollName, donorDoc.blockTimestamp);
assert.soon(() => TenantMigrationUtil.getNumBlockedReads(laggedSecondary, tenantId) == 1);
@@ -200,7 +200,7 @@ const kCollName = "testColl";
blockingFp.wait();
// Run a read command and a write command against the primary, and wait for them to block.
- const donorDoc = donorsColl.findOne({tenantId: tenantId});
+ const donorDoc = donorsColl.findOne({_id: migrationId});
assert.neq(null, donorDoc);
const readThread = startReadThread(donorPrimary, dbName, kCollName, donorDoc.blockTimestamp);
const writeThread = startWriteThread(donorPrimary, dbName, kCollName);
@@ -212,8 +212,7 @@ const kCollName = "testColl";
// Cannot mark the state doc as garbage collectable before the migration commits or aborts.
assert.commandFailedWithCode(
- donorsColl.update({tenantId: tenantId}, {$set: {expireAt: new Date()}}),
- ErrorCodes.BadValue);
+ donorsColl.update({_id: migrationId}, {$set: {expireAt: new Date()}}), ErrorCodes.BadValue);
// Can drop the state doc collection but this will not cause all blocked reads and writes to
// hang.
diff --git a/jstests/replsets/tenant_migration_drop_state_doc_collection.js b/jstests/replsets/tenant_migration_drop_state_doc_collection.js
index 0eee1ca2f93..ad858d0096c 100644
--- a/jstests/replsets/tenant_migration_drop_state_doc_collection.js
+++ b/jstests/replsets/tenant_migration_drop_state_doc_collection.js
@@ -35,7 +35,7 @@ function makeTenantId() {
function makeMigrationOpts(tenantMigrationTest, tenantId) {
return {
migrationIdString: extractUUIDFromObject(UUID()),
- tenantId: tenantId,
+ tenantId,
recipientConnString: tenantMigrationTest.getRecipientConnString()
};
}
@@ -69,7 +69,8 @@ function testDroppingStateDocCollections(tenantMigrationTest, fpName, {
let fp;
if (fpName) {
- fp = configureFailPoint(donorPrimary, fpName, {tenantId: tenantId});
+ fp = configureFailPoint(
+ donorPrimary, fpName, {migrationId: migrationOptsBeforeDrop.migrationIdString});
assert.commandWorked(tenantMigrationTest.startMigration(migrationOptsBeforeDrop));
fp.wait();
} else {
@@ -80,7 +81,7 @@ function testDroppingStateDocCollections(tenantMigrationTest, fpName, {
if (dropDonorsCollection) {
assert(donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).drop());
let donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationOptsBeforeDrop.migrationIdString),
});
assert.eq(donorDoc, null);
@@ -99,7 +100,7 @@ function testDroppingStateDocCollections(tenantMigrationTest, fpName, {
}));
let recipientDoc =
recipientPrimary.getCollection(TenantMigrationTest.kConfigRecipientsNS).findOne({
- tenantId: tenantId
+ _id: UUID(migrationOptsBeforeDrop.migrationIdString),
});
assert.eq(recipientDoc, null);
const currOpRecipient = assert.commandWorked(
diff --git a/jstests/replsets/tenant_migration_fetch_committed_transactions_shard_merge.js b/jstests/replsets/tenant_migration_fetch_committed_transactions_shard_merge.js
index df1660b66c9..7129ad46dfa 100644
--- a/jstests/replsets/tenant_migration_fetch_committed_transactions_shard_merge.js
+++ b/jstests/replsets/tenant_migration_fetch_committed_transactions_shard_merge.js
@@ -122,8 +122,6 @@ jsTestLog("Running a migration");
const migrationId = UUID();
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationId),
- // TODO(SERVER-63454): Remove tenantId when it is no longer required for shard merge.
- tenantId,
};
const fpAfterFetchingCommittedTransactions =
diff --git a/jstests/replsets/tenant_migration_invalid_inputs.js b/jstests/replsets/tenant_migration_invalid_inputs.js
index e2b5c1687ab..15548f54555 100644
--- a/jstests/replsets/tenant_migration_invalid_inputs.js
+++ b/jstests/replsets/tenant_migration_invalid_inputs.js
@@ -7,6 +7,7 @@
* @tags: [
* incompatible_with_macos,
* incompatible_with_windows_tls,
+ * incompatible_with_shard_merge,
* requires_persistence,
* requires_fcv_51,
* serverless,
@@ -38,17 +39,16 @@ assert.commandFailedWithCode(
donorPrimary.adminCommand(
TenantMigrationUtil.donorStartMigrationWithProtocol({
donorStartMigration: 1,
- protocol: 'multitenant migrations',
migrationId: UUID(),
recipientConnectionString: tenantMigrationTest.getRecipientRst().getURL(),
- readPreference: readPreference,
+ readPreference,
donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
},
donorPrimary.getDB("admin"))),
ErrorCodes.InvalidOptions);
-// Test unsupported database prefixes.
+// Test empty tenantId and unsupported database prefixes.
const unsupportedtenantIds = ['', 'admin', 'local', 'config'];
unsupportedtenantIds.forEach((invalidTenantId) => {
assert.commandFailedWithCode(
@@ -58,12 +58,12 @@ unsupportedtenantIds.forEach((invalidTenantId) => {
migrationId: UUID(),
recipientConnectionString: tenantMigrationTest.getRecipientRst().getURL(),
tenantId: invalidTenantId,
- readPreference: readPreference,
+ readPreference,
donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
},
donorPrimary.getDB("admin"))),
- ErrorCodes.BadValue);
+ [ErrorCodes.InvalidOptions, ErrorCodes.BadValue]);
});
// Test migrating a tenant to the donor itself.
@@ -73,8 +73,8 @@ assert.commandFailedWithCode(
donorStartMigration: 1,
migrationId: UUID(),
recipientConnectionString: tenantMigrationTest.getDonorRst().getURL(),
- tenantId: tenantId,
- readPreference: readPreference,
+ tenantId,
+ readPreference,
donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
},
@@ -89,8 +89,8 @@ assert.commandFailedWithCode(
migrationId: UUID(),
recipientConnectionString:
tenantMigrationTest.getRecipientRst().getURL() + "," + donorPrimary.host,
- tenantId: tenantId,
- readPreference: readPreference,
+ tenantId,
+ readPreference,
donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
},
@@ -104,8 +104,8 @@ assert.commandFailedWithCode(
donorStartMigration: 1,
migrationId: UUID(),
recipientConnectionString: recipientPrimary.host,
- tenantId: tenantId,
- readPreference: readPreference,
+ tenantId,
+ readPreference,
donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
},
@@ -117,11 +117,10 @@ jsTestLog("Testing 'recipientSyncData' command provided with invalid options.");
// Test missing tenantId field for protocol 'multitenant migrations'.
assert.commandFailedWithCode(recipientPrimary.adminCommand({
recipientSyncData: 1,
- protocol: 'multitenant migrations',
migrationId: UUID(),
donorConnectionString: tenantMigrationTest.getDonorRst().getURL(),
startMigrationDonorTimestamp: Timestamp(1, 1),
- readPreference: readPreference,
+ readPreference,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
}),
ErrorCodes.InvalidOptions);
@@ -134,10 +133,10 @@ unsupportedtenantIds.forEach((invalidTenantId) => {
donorConnectionString: tenantMigrationTest.getDonorRst().getURL(),
tenantId: invalidTenantId,
startMigrationDonorTimestamp: Timestamp(1, 1),
- readPreference: readPreference,
+ readPreference,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
}),
- ErrorCodes.BadValue);
+ [ErrorCodes.InvalidOptions, ErrorCodes.BadValue]);
});
// Test migrating a tenant from the recipient itself.
@@ -147,7 +146,7 @@ assert.commandFailedWithCode(recipientPrimary.adminCommand({
donorConnectionString: tenantMigrationTest.getRecipientRst().getURL(),
tenantId: tenantId,
startMigrationDonorTimestamp: Timestamp(1, 1),
- readPreference: readPreference,
+ readPreference,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
}),
ErrorCodes.BadValue);
@@ -156,10 +155,10 @@ assert.commandFailedWithCode(recipientPrimary.adminCommand({
assert.commandFailedWithCode(recipientPrimary.adminCommand({
recipientSyncData: 1,
migrationId: UUID(),
- donorConnectionString: tenantMigrationTest.getDonorRst().getURL() + "," + recipientPrimary.host,
+ donorConnectionString: `${tenantMigrationTest.getDonorRst().getURL()},${recipientPrimary.host}`,
tenantId: tenantId,
startMigrationDonorTimestamp: Timestamp(1, 1),
- readPreference: readPreference,
+ readPreference,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
}),
ErrorCodes.BadValue);
@@ -171,7 +170,7 @@ assert.commandFailedWithCode(recipientPrimary.adminCommand({
donorConnectionString: recipientPrimary.host,
tenantId: tenantId,
startMigrationDonorTimestamp: Timestamp(1, 1),
- readPreference: readPreference,
+ readPreference,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
}),
ErrorCodes.BadValue);
@@ -185,7 +184,7 @@ nullTimestamps.forEach((nullTs) => {
donorConnectionString: tenantMigrationTest.getDonorRst().getURL(),
tenantId: tenantId,
startMigrationDonorTimestamp: Timestamp(1, 1),
- readPreference: readPreference,
+ readPreference,
returnAfterReachingDonorTimestamp: nullTs,
recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
}),
diff --git a/jstests/replsets/tenant_migration_recipient_aborts_merge_on_donor_failure.js b/jstests/replsets/tenant_migration_recipient_aborts_merge_on_donor_failure.js
index 858c322f64d..4b9b85f905d 100644
--- a/jstests/replsets/tenant_migration_recipient_aborts_merge_on_donor_failure.js
+++ b/jstests/replsets/tenant_migration_recipient_aborts_merge_on_donor_failure.js
@@ -4,6 +4,7 @@
* @tags: [
* incompatible_with_macos,
* incompatible_with_windows_tls,
+ * featureFlagShardMerge,
* requires_majority_read_concern,
* requires_persistence,
* serverless,
@@ -47,7 +48,6 @@ load("jstests/replsets/libs/tenant_migration_util.js");
const migrationUuid = UUID();
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationUuid),
- tenantId,
readPreference: {mode: 'primary'}
};
diff --git a/jstests/replsets/tenant_migration_recipient_current_op.js b/jstests/replsets/tenant_migration_recipient_current_op.js
index 19d1bbdbd6d..0ca466c7a27 100644
--- a/jstests/replsets/tenant_migration_recipient_current_op.js
+++ b/jstests/replsets/tenant_migration_recipient_current_op.js
@@ -59,13 +59,21 @@ for (const db of dbsToClone) {
// correct.
function checkStandardFieldsOK(res) {
assert.eq(res.inprog.length, 1, res);
- assert.eq(bsonWoCompare(res.inprog[0].instanceID, kMigrationId), 0, res);
- assert.eq(res.inprog[0].donorConnectionString, tenantMigrationTest.getDonorRst().getURL(), res);
- assert.eq(bsonWoCompare(res.inprog[0].readPreference, kReadPreference), 0, res);
+ const {
+ instanceID,
+ donorConnectionString,
+ readPreference,
+ numRestartsDueToDonorConnectionFailure,
+ numRestartsDueToRecipientFailure,
+ tenantId
+ } = res.inprog[0];
+ assert.eq(bsonWoCompare(instanceID, kMigrationId), 0, res);
+ assert.eq(donorConnectionString, tenantMigrationTest.getDonorRst().getURL(), res);
+ assert.eq(bsonWoCompare(readPreference, kReadPreference), 0, res);
// We don't test failovers in this test so we don't expect these counters to be incremented.
- assert.eq(res.inprog[0].numRestartsDueToDonorConnectionFailure, 0, res);
- assert.eq(res.inprog[0].numRestartsDueToRecipientFailure, 0, res);
- assert.eq(bsonWoCompare(res.inprog[0].tenantId, kTenantId), 0, res);
+ assert.eq(numRestartsDueToDonorConnectionFailure, 0, res);
+ assert.eq(numRestartsDueToRecipientFailure, 0, res);
+ assert.eq(bsonWoCompare(tenantId, kTenantId), 0, res);
}
// Check currentOp fields' expected value once the recipient is in state "consistent" or later.
diff --git a/jstests/replsets/tenant_migration_recipient_rollback_recovery.js b/jstests/replsets/tenant_migration_recipient_rollback_recovery.js
index 32c562c4779..02a707d9443 100644
--- a/jstests/replsets/tenant_migration_recipient_rollback_recovery.js
+++ b/jstests/replsets/tenant_migration_recipient_rollback_recovery.js
@@ -143,12 +143,13 @@ function testRollbackInitialState() {
let steadyStateFunc = (tenantMigrationTest) => {
// Verify that the migration restarted successfully on the new primary despite rollback.
TenantMigrationTest.assertCommitted(migrationThread.returnData());
- tenantMigrationTest.assertRecipientNodesInExpectedState(
- tenantMigrationTest.getRecipientRst().nodes,
- migrationId,
- migrationOpts.tenantId,
- TenantMigrationTest.RecipientState.kConsistent,
- TenantMigrationTest.RecipientAccessState.kRejectBefore);
+ tenantMigrationTest.assertRecipientNodesInExpectedState({
+ nodes: tenantMigrationTest.getRecipientRst().nodes,
+ migrationId: migrationId,
+ tenantId: migrationOpts.tenantId,
+ expectedState: TenantMigrationTest.RecipientState.kConsistent,
+ expectedAccessState: TenantMigrationTest.RecipientAccessState.kRejectBefore
+ });
assert.commandWorked(tenantMigrationTest.forgetMigration(migrationOpts.migrationIdString));
};
diff --git a/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js b/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js
index e6dc611f85c..9fe0b9adea5 100644
--- a/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js
+++ b/jstests/replsets/tenant_migration_recipient_shard_merge_learn_files.js
@@ -38,14 +38,9 @@ tenantMigrationTest.insertDonorDB(tenantDB, collName);
const failpoint = "fpBeforeMarkingCloneSuccess";
const waitInFailPoint = configureFailPoint(recipientPrimary, failpoint, {action: "hang"});
-// In order to prevent the copying of "testTenantId" databases via logical cloning from donor to
-// recipient, start migration on a tenant id which is non-existent on the donor.
const migrationUuid = UUID();
-const kDummyTenantId = "nonExistentTenantId";
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationUuid),
- // TODO (SERVER-63454): Remove kDummyTenantId.
- tenantId: kDummyTenantId,
readPreference: {mode: 'primary'}
};
@@ -55,12 +50,13 @@ assert.commandWorked(
waitInFailPoint.wait();
-tenantMigrationTest.assertRecipientNodesInExpectedState(
- tenantMigrationTest.getRecipientRst().nodes,
- migrationUuid,
+tenantMigrationTest.assertRecipientNodesInExpectedState({
+ nodes: tenantMigrationTest.getRecipientRst().nodes,
+ migrationId: migrationUuid,
tenantId,
- TenantMigrationTest.RecipientState.kLearnedFilenames,
- TenantMigrationTest.RecipientAccessState.kReject);
+ expectedState: TenantMigrationTest.RecipientState.kLearnedFilenames,
+ expectedAccessState: TenantMigrationTest.RecipientAccessState.kReject
+});
waitInFailPoint.off();
diff --git a/jstests/replsets/tenant_migration_recipient_shard_merge_oplog_catchup.js b/jstests/replsets/tenant_migration_recipient_shard_merge_oplog_catchup.js
index a2b8008bcb1..8cb4bbf41c2 100644
--- a/jstests/replsets/tenant_migration_recipient_shard_merge_oplog_catchup.js
+++ b/jstests/replsets/tenant_migration_recipient_shard_merge_oplog_catchup.js
@@ -33,13 +33,9 @@ const failpoint = "pauseTenantMigrationBeforeLeavingDataSyncState";
const pauseTenantMigrationBeforeLeavingDataSyncState =
configureFailPoint(donorPrimary, failpoint, {action: "hang"});
-// Start migration on a tenant id which is non-existent on the donor.
const migrationUuid = UUID();
-const kDummyTenantId = "nonExistentTenantId";
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationUuid),
- // TODO (SERVER-63454): Remove kDummyTenantId.
- tenantId: kDummyTenantId,
readPreference: {mode: 'primary'}
};
diff --git a/jstests/replsets/tenant_migration_recipient_vote_imported_files.js b/jstests/replsets/tenant_migration_recipient_vote_imported_files.js
index b1a489155b1..d5d5138bcf6 100644
--- a/jstests/replsets/tenant_migration_recipient_vote_imported_files.js
+++ b/jstests/replsets/tenant_migration_recipient_vote_imported_files.js
@@ -57,7 +57,6 @@ const migrationId = UUID();
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationId),
recipientConnString: tenantMigrationTest.getRecipientConnString(),
- tenantId: kTenantId,
};
const donorRstArgs = TenantMigrationUtil.createRstArgs(tenantMigrationTest.getDonorRst());
diff --git a/jstests/replsets/tenant_migration_shard_merge_import_write_conflict_retry.js b/jstests/replsets/tenant_migration_shard_merge_import_write_conflict_retry.js
index cded13b4ddf..11c8d1d2816 100644
--- a/jstests/replsets/tenant_migration_shard_merge_import_write_conflict_retry.js
+++ b/jstests/replsets/tenant_migration_shard_merge_import_write_conflict_retry.js
@@ -66,10 +66,8 @@ configureFailPoint(
jsTestLog("Run migration");
// The old multitenant migrations won't copy myDatabase since it doesn't start with testTenantId,
// but shard merge copies everything so we still expect myDatabase on the recipient, below.
-const kTenantId = "testTenantId";
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationId),
- tenantId: kTenantId,
};
TenantMigrationTest.assertCommitted(
tenantMigrationTest.runMigration(migrationOpts, {enableDonorStartMigrationFsync: true}));
diff --git a/jstests/replsets/tenant_migration_shard_merge_invalid_inputs.js b/jstests/replsets/tenant_migration_shard_merge_invalid_inputs.js
new file mode 100644
index 00000000000..b4c74dfd1cd
--- /dev/null
+++ b/jstests/replsets/tenant_migration_shard_merge_invalid_inputs.js
@@ -0,0 +1,162 @@
+/**
+ * Tests that the donorStartMigration and recipientSyncData commands for a shard merge throw an
+ * error if a tenantId is provided or if the prefix is invalid (i.e. '', 'admin', 'local' or
+ * 'config') or if the recipient connection string matches the donor's connection string or doesn't
+ * correspond to a replica set with a least one host.
+ *
+ * @tags: [
+ * incompatible_with_eft,
+ * incompatible_with_macos,
+ * incompatible_with_windows_tls,
+ * featureFlagShardMerge,
+ * requires_persistence,
+ * requires_fcv_51,
+ * serverless,
+ * ]
+ */
+
+(function() {
+"use strict";
+
+load("jstests/replsets/libs/tenant_migration_test.js");
+load("jstests/replsets/libs/tenant_migration_util.js");
+
+const tenantMigrationTest =
+ new TenantMigrationTest({name: jsTestName(), enableRecipientTesting: false});
+
+const donorPrimary = tenantMigrationTest.getDonorPrimary();
+const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
+
+const tenantId = "testTenantId";
+const readPreference = {
+ mode: 'primary'
+};
+const migrationCertificates = TenantMigrationUtil.makeMigrationCertificatesForTest();
+
+jsTestLog("Testing 'donorStartMigration' command provided with invalid options.");
+
+// Test erroneously included tenantId field and unsupported database prefixes.
+const unsupportedtenantIds = [tenantId, 'admin', 'local', 'config'];
+unsupportedtenantIds.forEach((invalidTenantId) => {
+ const cmd = {
+ donorStartMigration: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ tenantId: invalidTenantId,
+ recipientConnectionString: tenantMigrationTest.getRecipientRst().getURL(),
+ readPreference,
+ donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+ };
+ assert.commandFailedWithCode(donorPrimary.adminCommand(cmd),
+ [ErrorCodes.InvalidOptions, ErrorCodes.BadValue]);
+});
+
+// Test merging to the donor itself.
+assert.commandFailedWithCode(donorPrimary.adminCommand({
+ donorStartMigration: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ recipientConnectionString: tenantMigrationTest.getDonorRst().getURL(),
+ readPreference,
+ donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+}),
+ ErrorCodes.BadValue);
+
+// Test merging to a recipient that shares one or more hosts with the donor.
+assert.commandFailedWithCode(donorPrimary.adminCommand({
+ donorStartMigration: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ recipientConnectionString:
+ tenantMigrationTest.getRecipientRst().getURL() + "," + donorPrimary.host,
+ readPreference,
+ donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+}),
+ ErrorCodes.BadValue);
+
+// Test merging to a standalone recipient.
+assert.commandFailedWithCode(donorPrimary.adminCommand({
+ donorStartMigration: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ recipientConnectionString: recipientPrimary.host,
+ readPreference,
+ donorCertificateForRecipient: migrationCertificates.donorCertificateForRecipient,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+}),
+ ErrorCodes.BadValue);
+
+jsTestLog("Testing 'recipientSyncData' command provided with invalid options.");
+
+// Test erroneously included tenantId field and unsupported database prefixes.
+unsupportedtenantIds.forEach((invalidTenantId) => {
+ assert.commandFailedWithCode(recipientPrimary.adminCommand({
+ recipientSyncData: 1,
+ migrationId: UUID(),
+ donorConnectionString: tenantMigrationTest.getDonorRst().getURL(),
+ tenantId: invalidTenantId,
+ protocol: 'shard merge',
+ startMigrationDonorTimestamp: Timestamp(1, 1),
+ readPreference,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+ }),
+ [ErrorCodes.InvalidOptions, ErrorCodes.BadValue]);
+});
+
+// Test merging from the recipient itself.
+assert.commandFailedWithCode(recipientPrimary.adminCommand({
+ recipientSyncData: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ donorConnectionString: tenantMigrationTest.getRecipientRst().getURL(),
+ startMigrationDonorTimestamp: Timestamp(1, 1),
+ readPreference,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+}),
+ ErrorCodes.BadValue);
+
+// Test merging from a donor that shares one or more hosts with the recipient.
+assert.commandFailedWithCode(recipientPrimary.adminCommand({
+ recipientSyncData: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ donorConnectionString: `${tenantMigrationTest.getDonorRst().getURL()},${recipientPrimary.host}`,
+ startMigrationDonorTimestamp: Timestamp(1, 1),
+ readPreference,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+}),
+ ErrorCodes.BadValue);
+
+// Test merging from a standalone donor.
+assert.commandFailedWithCode(recipientPrimary.adminCommand({
+ recipientSyncData: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ donorConnectionString: recipientPrimary.host,
+ startMigrationDonorTimestamp: Timestamp(1, 1),
+ readPreference,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+}),
+ ErrorCodes.BadValue);
+
+// Test 'returnAfterReachingDonorTimestamp' can't be null.
+const nullTimestamps = [Timestamp(0, 0), Timestamp(0, 1)];
+nullTimestamps.forEach((nullTs) => {
+ assert.commandFailedWithCode(donorPrimary.adminCommand({
+ recipientSyncData: 1,
+ migrationId: UUID(),
+ protocol: 'shard merge',
+ donorConnectionString: tenantMigrationTest.getDonorRst().getURL(),
+ startMigrationDonorTimestamp: Timestamp(1, 1),
+ readPreference,
+ returnAfterReachingDonorTimestamp: nullTs,
+ recipientCertificateForDonor: migrationCertificates.recipientCertificateForDonor,
+ }),
+ ErrorCodes.BadValue);
+});
+
+tenantMigrationTest.stop();
+})();
diff --git a/jstests/replsets/tenant_migration_shard_merge_recipient_creates_blockers_during_migration.js b/jstests/replsets/tenant_migration_shard_merge_recipient_creates_blockers_during_migration.js
index 7cdd2ed9deb..ed375658f20 100644
--- a/jstests/replsets/tenant_migration_shard_merge_recipient_creates_blockers_during_migration.js
+++ b/jstests/replsets/tenant_migration_shard_merge_recipient_creates_blockers_during_migration.js
@@ -65,8 +65,6 @@ const waitInFailPoint = configureFailPoint(recipientPrimary, failpoint, {action:
const migrationId = UUID();
const migrationOpts = {
migrationIdString: extractUUIDFromObject(migrationId),
- // TODO (SERVER-63454): Remove tenantId.
- tenantId,
};
assert.commandWorked(tenantMigrationTest.startMigration(migrationOpts));
diff --git a/jstests/replsets/tenant_migration_shard_merge_recipient_current_op.js b/jstests/replsets/tenant_migration_shard_merge_recipient_current_op.js
index 977a0340534..dbb0717ae03 100644
--- a/jstests/replsets/tenant_migration_shard_merge_recipient_current_op.js
+++ b/jstests/replsets/tenant_migration_shard_merge_recipient_current_op.js
@@ -33,7 +33,6 @@ const kReadPreference = {
};
const migrationOpts = {
migrationIdString: extractUUIDFromObject(kMigrationId),
- tenantId: kTenantId,
readPreference: kReadPreference
};
@@ -60,7 +59,6 @@ function checkStandardFieldsOK(res) {
// We don't test failovers in this test so we don't expect these counters to be incremented.
assert.eq(res.inprog[0].numRestartsDueToDonorConnectionFailure, 0, res);
assert.eq(res.inprog[0].numRestartsDueToRecipientFailure, 0, res);
- assert.eq(bsonWoCompare(res.inprog[0].tenantId, kTenantId), 0, res);
}
// Check currentOp fields' expected value once the recipient is in state "consistent" or later.
@@ -101,8 +99,7 @@ const fpAfterDataConsistent = configureFailPoint(
const fpAfterForgetMigration = configureFailPoint(
recipientPrimary, "fpAfterReceivingRecipientForgetMigration", {action: "hang"});
-jsTestLog("Starting tenant migration with migrationId: " + kMigrationId +
- ", tenantId: " + kTenantId);
+jsTestLog(`Starting tenant migration with migrationId: ${kMigrationId}`);
assert.commandWorked(
tenantMigrationTest.startMigration(migrationOpts, {enableDonorStartMigrationFsync: true}));
diff --git a/jstests/replsets/tenant_migration_timeseries_retryable_write_oplog_cloning.js b/jstests/replsets/tenant_migration_timeseries_retryable_write_oplog_cloning.js
index 2a62d8e5fb5..bd5759a35ca 100644
--- a/jstests/replsets/tenant_migration_timeseries_retryable_write_oplog_cloning.js
+++ b/jstests/replsets/tenant_migration_timeseries_retryable_write_oplog_cloning.js
@@ -118,9 +118,8 @@ function testOplogCloning(ordered) {
TenantMigrationTest.assertCommitted(
tenantMigrationTest.runMigration(migrationOpts, {automaticForgetMigration: false}));
- const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
- tenantId: kTenantId
- });
+ const donorDoc =
+ donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({_id: migrationId});
assert.commandWorked(tenantMigrationTest.forgetMigration(migrationOpts.migrationIdString));
tenantMigrationTest.waitForMigrationGarbageCollection(migrationId, kTenantId);
diff --git a/jstests/replsets/tenant_migrations_back_to_back.js b/jstests/replsets/tenant_migrations_back_to_back.js
index 11c19515923..4aaa6682de8 100644
--- a/jstests/replsets/tenant_migrations_back_to_back.js
+++ b/jstests/replsets/tenant_migrations_back_to_back.js
@@ -53,7 +53,7 @@ migrationThread.start();
waitForRejectReadsBeforeTsFp.wait();
const donorDoc =
- donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({tenantId: kTenantId});
+ donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({_id: migrationId});
assert.lt(preMigrationTimestamp, donorDoc.blockTimestamp);
waitForRejectReadsBeforeTsFp.off();
// Wait for the migration to complete.
@@ -115,7 +115,7 @@ assert.eq(res.inprog[0].lastDurableState, kBlocking, tojson(res.inprog));
// Get the block timestamp for this new migration.
const donorDoc2 =
- donor2Primary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({tenantId: kTenantId});
+ donor2Primary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({_id: migration2Id});
assert.eq(
mtabStatus.donor.state, TenantMigrationTest.DonorAccessState.kBlockWritesAndReads, mtabStatus);
assert(mtabStatus.donor.hasOwnProperty("blockTimestamp"), mtabStatus);