diff options
author | Christopher Caplinger <christopher.caplinger@mongodb.com> | 2022-08-15 17:59:10 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-15 19:25:35 +0000 |
commit | e455a0fa9c571753bf07d4c951bfbf881005c3a7 (patch) | |
tree | aaf4cbecd9251f68b6ddaac2513b11e7b55da9f6 /jstests | |
parent | 2c701bf03543d9feaad6ba3faf7851bb26d0ee30 (diff) | |
download | mongo-e455a0fa9c571753bf07d4c951bfbf881005c3a7.tar.gz |
SERVER-63454: Don't require tenantId for shard merge
Diffstat (limited to 'jstests')
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); |