jstests/replsets/tenant_migration_donor_resume_on_stepup_and_restart.js
/**
 * Runs the donorStartMigration command to start a migration, and interrupts the migration on the
 * donor using the 'interruptFunc', and asserts that migration eventually commits.
 */
Runs the donorStartMigration command to start a migration, and interrupts the migration on the
donor using the 'interruptFunc', and asserts that migration eventually commits.
Runs the donorStartMigration command to start a migration and interrupts the migration on the donor using the ' interruptFunc ' and asserts that migration eventually commits .
function testDonorStartMigrationInterrupt(interruptFunc,
                                          {donorRestarted = false, disableForShardMerge = true}) {
    const donorRst =
        new ReplSetTest({nodes: 3, name: "donorRst", nodeOptions: migrationX509Options.donor});
    donorRst.startSet();
    donorRst.initiate();
    const tenantMigrationTest = new TenantMigrationTest({name: jsTestName(), donorRst});
    let donorPrimary = tenantMigrationTest.getDonorPrimary();
    const recipientPrimary = tenantMigrationTest.getRecipientPrimary();
    if (disableForShardMerge &&
        TenantMigrationUtil.isShardMergeEnabled(recipientPrimary.getDB("admin"))) {
        jsTest.log("Skipping test for shard merge");
        tenantMigrationTest.stop();
        donorRst.stopSet();
        return;
    }
    const migrationId = UUID();
    const migrationOpts = {
        migrationIdString: extractUUIDFromObject(migrationId),
        tenantId: kTenantId,
        recipientConnString: tenantMigrationTest.getRecipientConnString(),
    };
    const donorRstArgs = TenantMigrationUtil.createRstArgs(donorRst);
    const runMigrationThread = new Thread(TenantMigrationUtil.runMigrationAsync,
                                          migrationOpts,
                                          donorRstArgs,
                                          {retryOnRetryableErrors: true});
    runMigrationThread.start();
    assert.soon(() => donorPrimary.adminCommand({currentOp: true, desc: "tenant donor migration"})
                          .inprog.length > 0);
    sleep(Math.random() * kMaxSleepTimeMS);
    interruptFunc(donorRst);
    TenantMigrationTest.assertCommitted(runMigrationThread.returnData());
    tenantMigrationTest.waitForDonorNodesToReachState(donorRst.nodes,
                                                      migrationId,
                                                      migrationOpts.tenantId,
                                                      TenantMigrationTest.DonorState.kCommitted);
    assert.commandWorked(tenantMigrationTest.forgetMigration(migrationOpts.migrationIdString));
    donorPrimary = tenantMigrationTest.getDonorPrimary();  
    const donorStats = tenantMigrationTest.getTenantMigrationStats(donorPrimary);
    jsTestLog(`Stats at the donor primary: ${tojson(donorStats)}`);
    if (donorRestarted) {
        assert.gte(1, donorStats.totalSuccessfulMigrationsDonated);
    } else {
        assert(1 == donorStats.totalSuccessfulMigrationsDonated ||
               2 == donorStats.totalSuccessfulMigrationsDonated);
    }
    tenantMigrationTest.stop();
    donorRst.stopSet();
}
function testDonorStartMigrationInterrupt ( interruptFunc , { donorRestarted = false , disableForShardMerge = true } ) { const donorRst = new ReplSetTest ( { nodes : 3 , name : "donorRst" , nodeOptions : migrationX509Options . donor } ) ; donorRst . startSet ( ) ; donorRst . initiate ( ) ; const tenantMigrationTest = new TenantMigrationTest ( { name : jsTestName ( ) , donorRst } ) ; let donorPrimary = tenantMigrationTest . getDonorPrimary ( ) ; const recipientPrimary = tenantMigrationTest . getRecipientPrimary ( ) ; if ( disableForShardMerge && TenantMigrationUtil . isShardMergeEnabled ( recipientPrimary . getDB ( "admin" ) ) ) { jsTest . log ( "Skipping test for shard merge" ) ; tenantMigrationTest . stop ( ) ; donorRst . stopSet ( ) ; return ; } const migrationId = UUID ( ) ; const migrationOpts = { migrationIdString : extractUUIDFromObject ( migrationId ) , tenantId : kTenantId , recipientConnString : tenantMigrationTest . getRecipientConnString ( ) , } ; const donorRstArgs = TenantMigrationUtil . createRstArgs ( donorRst ) ; const runMigrationThread = new Thread ( TenantMigrationUtil . runMigrationAsync , migrationOpts , donorRstArgs , { retryOnRetryableErrors : true } ) ; runMigrationThread . start ( ) ; assert . soon ( ( ) => donorPrimary . adminCommand ( { currentOp : true , desc : "tenant donor migration" } ) . inprog . length > 0 ) ; sleep ( Math . random ( ) * kMaxSleepTimeMS ) ; interruptFunc ( donorRst ) ; TenantMigrationTest . assertCommitted ( runMigrationThread . returnData ( ) ) ; tenantMigrationTest . waitForDonorNodesToReachState ( donorRst . nodes , migrationId , migrationOpts . tenantId , TenantMigrationTest . DonorState . kCommitted ) ; assert . commandWorked ( tenantMigrationTest . forgetMigration ( migrationOpts . migrationIdString ) ) ; donorPrimary = tenantMigrationTest . getDonorPrimary ( ) ; const donorStats = tenantMigrationTest . getTenantMigrationStats ( donorPrimary ) ; jsTestLog ( ` ${ tojson ( donorStats ) } ` ) ; if ( donorRestarted ) { assert . gte ( 1 , donorStats . totalSuccessfulMigrationsDonated ) ; } else { assert ( 1 == donorStats . totalSuccessfulMigrationsDonated || 2 == donorStats . totalSuccessfulMigrationsDonated ) ; } tenantMigrationTest . stop ( ) ; donorRst . stopSet ( ) ; }
Runs the donorStartMigration command to start a migration, and interrupts the migration on the
 donor using the 'interruptFunc', and asserts that migration eventually commits.
Runs the donorStartMigration command to start a migration and interrupts the migration on the donor using the ' interruptFunc ' and asserts that migration eventually commits .
// Wait for donorStartMigration command to start. // Could change after interrupt. // If full restart happened the count could be lost completely. // The double counting happens when the failover happens after migration completes // but before the state doc GC mark is persisted. While this test is targeting this // scenario it is low probability in production. // Skip checking the stats on the recipient since enableRecipientTesting is false // so the recipient is forced to respond to recipientSyncData without starting the // migration.