jstests/replsets/tenant_migration_conflicting_donor_start_migration_cmds.js
/**
 * Tests that if the client runs multiple donorStartMigration commands that would start conflicting
 * migrations, only one of the migrations will start and succeed.
 */
Tests that if the client runs multiple donorStartMigration commands that would start conflicting
migrations, only one of the migrations will start and succeed.
Tests that if the client runs multiple donorStartMigration commands that would start conflicting migrations only one of the migrations will start and succeed .
function testConcurrentConflictingMigrations({
    tenantMigrationTest0,
    migrationOpts0,
    tenantMigrationTest1,
    migrationOpts1,
    donorPrimary,
}) {
    jsTestLog("Start conflicting migrations concurrently");
    const res0 = tenantMigrationTest0.startMigration(migrationOpts0);
    jsTestLog(`Migration 0 opts: ${tojson(migrationOpts0)}, result: ${tojson(res0)}`);
    const res1 = tenantMigrationTest1.startMigration(migrationOpts1);
    jsTestLog(`Migration 1 opts: ${tojson(migrationOpts1)}, result: ${tojson(res1)}`);
    let configDonorsColl = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS);
    assert(res0.ok || res1.ok);
    assert(!res0.ok || !res1.ok);
    if (res0.ok) {
        assert.commandFailedWithCode(res1, ErrorCodes.ConflictingOperationInProgress);
        assertNoCertificateOrPrivateKey(res1.errmsg);
        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);
        }
        TenantMigrationTest.assertCommitted(
            tenantMigrationTest0.waitForMigrationToComplete(migrationOpts0));
        assert.commandWorked(
            tenantMigrationTest0.forgetMigration(migrationOpts0.migrationIdString));
    } else {
        assert.commandFailedWithCode(res0, ErrorCodes.ConflictingOperationInProgress);
        assertNoCertificateOrPrivateKey(res0.errmsg);
        assert.eq(1, configDonorsColl.count({_id: UUID(migrationOpts1.migrationIdString)}));
        assert.eq(1, getTenantMigrationDonorCurrentOpEntries(donorPrimary, {
                         "instanceID": UUID(migrationOpts1.migrationIdString)
                     }).length);
        if (migrationOpts0.migrationIdString != migrationOpts1.migrationIdString) {
            assert.eq(0, configDonorsColl.count({_id: UUID(migrationOpts0.migrationIdString)}));
            assert.eq(0, getTenantMigrationDonorCurrentOpEntries(donorPrimary, {
                             "instanceID": UUID(migrationOpts0.migrationIdString)
                         }).length);
        } else if (migrationOpts0.tenantId != migrationOpts1.tenantId) {
            assert.eq(0, configDonorsColl.count({tenantId: migrationOpts0.tenantId}));
            assert.eq(0, getTenantMigrationDonorCurrentOpEntries(donorPrimary, {
                             tenantId: migrationOpts0.tenantId
                         }).length);
        }
        TenantMigrationTest.assertAborted(
            tenantMigrationTest1.waitForMigrationToComplete(migrationOpts1));
        assert.commandWorked(
            tenantMigrationTest1.forgetMigration(migrationOpts1.migrationIdString));
    }
}
function testConcurrentConflictingMigrations ( { tenantMigrationTest0 , migrationOpts0 , tenantMigrationTest1 , migrationOpts1 , donorPrimary , } ) { jsTestLog ( "Start conflicting migrations concurrently" ) ; const res0 = tenantMigrationTest0 . startMigration ( migrationOpts0 ) ; jsTestLog ( ` ${ tojson ( migrationOpts0 ) } ${ tojson ( res0 ) } ` ) ; const res1 = tenantMigrationTest1 . startMigration ( migrationOpts1 ) ; jsTestLog ( ` ${ tojson ( migrationOpts1 ) } ${ tojson ( res1 ) } ` ) ; let configDonorsColl = donorPrimary . getCollection ( TenantMigrationTest . kConfigDonorsNS ) ; assert ( res0 . ok || res1 . ok ) ; assert ( ! res0 . ok || ! res1 . ok ) ; if ( res0 . ok ) { assert . commandFailedWithCode ( res1 , ErrorCodes . ConflictingOperationInProgress ) ; assertNoCertificateOrPrivateKey ( res1 . errmsg ) ; 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 ) ; } TenantMigrationTest . assertCommitted ( tenantMigrationTest0 . waitForMigrationToComplete ( migrationOpts0 ) ) ; assert . commandWorked ( tenantMigrationTest0 . forgetMigration ( migrationOpts0 . migrationIdString ) ) ; } else { assert . commandFailedWithCode ( res0 , ErrorCodes . ConflictingOperationInProgress ) ; assertNoCertificateOrPrivateKey ( res0 . errmsg ) ; assert . eq ( 1 , configDonorsColl . count ( { _id : UUID ( migrationOpts1 . migrationIdString ) } ) ) ; assert . eq ( 1 , getTenantMigrationDonorCurrentOpEntries ( donorPrimary , { "instanceID" : UUID ( migrationOpts1 . migrationIdString ) } ) . length ) ; if ( migrationOpts0 . migrationIdString != migrationOpts1 . migrationIdString ) { assert . eq ( 0 , configDonorsColl . count ( { _id : UUID ( migrationOpts0 . migrationIdString ) } ) ) ; assert . eq ( 0 , getTenantMigrationDonorCurrentOpEntries ( donorPrimary , { "instanceID" : UUID ( migrationOpts0 . migrationIdString ) } ) . length ) ; } else if ( migrationOpts0 . tenantId != migrationOpts1 . tenantId ) { assert . eq ( 0 , configDonorsColl . count ( { tenantId : migrationOpts0 . tenantId } ) ) ; assert . eq ( 0 , getTenantMigrationDonorCurrentOpEntries ( donorPrimary , { tenantId : migrationOpts0 . tenantId } ) . length ) ; } TenantMigrationTest . assertAborted ( tenantMigrationTest1 . waitForMigrationToComplete ( migrationOpts1 ) ) ; assert . commandWorked ( tenantMigrationTest1 . forgetMigration ( migrationOpts1 . migrationIdString ) ) ; } }
Tests that if the client runs multiple donorStartMigration commands that would start conflicting
 migrations, only one of the migrations will start and succeed.
Tests that if the client runs multiple donorStartMigration commands that would start conflicting migrations only one of the migrations will start and succeed .
// Verify that exactly one migration succeeded.