jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js
/**
 * Tests that the donor throws a ConflictingOperationInProgress error if the client runs a
 * donorStartMigration command to start a migration that conflicts with an existing migration that
 * has committed but not garbage-collected (i.e. the donor has not received donorForgetMigration).
 */
Tests that the donor throws a ConflictingOperationInProgress error if the client runs a
donorStartMigration command to start a migration that conflicts with an existing migration that
has committed but not garbage-collected .
Tests that the donor throws a ConflictingOperationInProgress error if the client runs a donorStartMigration command to start a migration that conflicts with an existing migration that has committed but not garbage - collected .
function testStartingConflictingMigrationAfterInitialMigrationCommitted({
    tenantMigrationTest0,
    migrationOpts0,
    tenantMigrationTest1,
    migrationOpts1,
    donorPrimary,
}) {
    jsTestLog("Start conflicting migration after first commits");
    const res0 =
        tenantMigrationTest0.runMigration(migrationOpts0, {automaticForgetMigration: false});
    jsTestLog(`Migration 0 opts: ${tojson(migrationOpts0)}, result: ${tojson(res0)}`);
    TenantMigrationTest.assertCommitted(res0);
    const res1 = tenantMigrationTest1.runMigration(migrationOpts1);
    jsTestLog(`Migration 1 opts: ${tojson(migrationOpts1)}, result: ${tojson(res1)}`);
    assert.commandFailedWithCode(res1, ErrorCodes.ConflictingOperationInProgress);
    assertNoCertificateOrPrivateKey(res1.errmsg);
    let configDonorsColl = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS);
    assert.eq(1, configDonorsColl.count({_id: UUID(migrationOpts0.migrationIdString)}));
    assert.eq(1, getTenantMigrationDonorCurrentOpEntries(donorPrimary, {
                     "instanceID": UUID(migrationOpts0.migrationIdString)
                 }).length);
    if (migrationOpts0.migrationIdString != migrationOpts1.migrationIdString) {
        assert.eq(0, configDonorsColl.count({_id: UUID(migrationOpts1.migrationIdString)}));
        assert.eq(0, getTenantMigrationDonorCurrentOpEntries(donorPrimary, {
                         "instanceID": UUID(migrationOpts1.migrationIdString)
                     }).length);
    } else if (migrationOpts0.tenantId != migrationOpts1.tenantId) {
        assert.eq(0, configDonorsColl.count({tenantId: migrationOpts1.tenantId}));
        assert.eq(0, getTenantMigrationDonorCurrentOpEntries(donorPrimary, {
                         tenantId: migrationOpts1.tenantId
                     }).length);
    }
    assert.commandWorked(tenantMigrationTest0.forgetMigration(migrationOpts0.migrationIdString));
    tenantMigrationTest0.waitForMigrationGarbageCollection(migrationOpts0.migrationIdString,
                                                           migrationOpts0.tenantId);
}
function testStartingConflictingMigrationAfterInitialMigrationCommitted ( { tenantMigrationTest0 , migrationOpts0 , tenantMigrationTest1 , migrationOpts1 , donorPrimary , } ) { jsTestLog ( "Start conflicting migration after first commits" ) ; const res0 = tenantMigrationTest0 . runMigration ( migrationOpts0 , { automaticForgetMigration : false } ) ; jsTestLog ( ` ${ tojson ( migrationOpts0 ) } ${ tojson ( res0 ) } ` ) ; TenantMigrationTest . assertCommitted ( res0 ) ; const res1 = tenantMigrationTest1 . runMigration ( migrationOpts1 ) ; jsTestLog ( ` ${ tojson ( migrationOpts1 ) } ${ tojson ( res1 ) } ` ) ; assert . commandFailedWithCode ( res1 , ErrorCodes . ConflictingOperationInProgress ) ; assertNoCertificateOrPrivateKey ( res1 . errmsg ) ; let configDonorsColl = donorPrimary . getCollection ( TenantMigrationTest . kConfigDonorsNS ) ; assert . eq ( 1 , configDonorsColl . count ( { _id : UUID ( migrationOpts0 . migrationIdString ) } ) ) ; assert . eq ( 1 , getTenantMigrationDonorCurrentOpEntries ( donorPrimary , { "instanceID" : UUID ( migrationOpts0 . migrationIdString ) } ) . length ) ; if ( migrationOpts0 . migrationIdString != migrationOpts1 . migrationIdString ) { assert . eq ( 0 , configDonorsColl . count ( { _id : UUID ( migrationOpts1 . migrationIdString ) } ) ) ; assert . eq ( 0 , getTenantMigrationDonorCurrentOpEntries ( donorPrimary , { "instanceID" : UUID ( migrationOpts1 . migrationIdString ) } ) . length ) ; } else if ( migrationOpts0 . tenantId != migrationOpts1 . tenantId ) { assert . eq ( 0 , configDonorsColl . count ( { tenantId : migrationOpts1 . tenantId } ) ) ; assert . eq ( 0 , getTenantMigrationDonorCurrentOpEntries ( donorPrimary , { tenantId : migrationOpts1 . tenantId } ) . length ) ; } assert . commandWorked ( tenantMigrationTest0 . forgetMigration ( migrationOpts0 . migrationIdString ) ) ; tenantMigrationTest0 . waitForMigrationGarbageCollection ( migrationOpts0 . migrationIdString , migrationOpts0 . tenantId ) ; }
Tests that the donor throws a ConflictingOperationInProgress error if the client runs a
 donorStartMigration command to start a migration that conflicts with an existing migration that
 has committed but not garbage-collected (i.e.
Tests that the donor throws a ConflictingOperationInProgress error if the client runs a donorStartMigration command to start a migration that conflicts with an existing migration that has committed but not garbage - collected ( i . e .
// If the second donorStartMigration had started a duplicate migration, there would be two donor // state docs and TenantMigrationDonorService instances.