jstests/replsets/tenant_migration_recipient_rollback_recovery.js
/**
 * Starts a recipient ReplSetTest and creates a TenantMigrationTest for it. Runs 'setUpFunc' after
 * initiating the recipient. Then, runs 'rollbackOpsFunc' while replication is disabled on the
 * secondaries, shuts down the primary and restarts it after re-election to force the operations in
 * 'rollbackOpsFunc' to be rolled back. Finally, runs 'steadyStateFunc' after it is back in the
 * replication steady state.
 */
Starts a recipient ReplSetTest and creates a TenantMigrationTest for it. Runs 'setUpFunc' after
initiating the recipient. Then, runs 'rollbackOpsFunc' while replication is disabled on the
secondaries, shuts down the primary and restarts it after re-election to force the operations in
'rollbackOpsFunc' to be rolled back. Finally, runs 'steadyStateFunc' after it is back in the
replication steady state.
Starts a recipient ReplSetTest and creates a TenantMigrationTest for it . Runs ' setUpFunc ' after initiating the recipient . Then runs ' rollbackOpsFunc ' while replication is disabled on the secondaries shuts down the primary and restarts it after re - election to force the operations in ' rollbackOpsFunc ' to be rolled back . Finally runs ' steadyStateFunc ' after it is back in the replication steady state .
function testRollBack(setUpFunc, rollbackOpsFunc, steadyStateFunc) {
    const donorRst = new ReplSetTest({
        name: "donorRst",
        nodes: 1,
        nodeOptions: Object.assign({}, migrationX509Options.donor, {
            setParameter: {
                tenantMigrationGarbageCollectionDelayMS: kGarbageCollectionDelayMS,
                ttlMonitorSleepSecs: 1,
            }
        })
    });
    donorRst.startSet();
    donorRst.initiate();
    const donorRstArgs = TenantMigrationUtil.createRstArgs(donorRst);
    const recipientRst = new ReplSetTest({
        name: "recipientRst",
        nodes: 3,
        nodeOptions: Object.assign({}, migrationX509Options.recipient, {
            setParameter: {
                tenantMigrationGarbageCollectionDelayMS: kGarbageCollectionDelayMS,
                ttlMonitorSleepSecs: 1,
            }
        })
    });
    recipientRst.startSet();
    recipientRst.initiate();
    const tenantMigrationTest =
        new TenantMigrationTest({name: jsTestName(), donorRst, recipientRst});
    setUpFunc(tenantMigrationTest, donorRstArgs);
    let originalRecipientPrimary = recipientRst.getPrimary();
    const originalRecipientSecondaries = recipientRst.getSecondaries();
    assert.commandWorked(originalRecipientPrimary.adminCommand(
        {setDefaultRWConcern: 1, defaultWriteConcern: {w: 1}, writeConcern: {w: "majority"}}));
    recipientRst.awaitLastOpCommitted();
    stopServerReplication(originalRecipientSecondaries);
    rollbackOpsFunc(tenantMigrationTest, donorRstArgs);
    recipientRst.stop(originalRecipientPrimary);
    restartServerReplication(originalRecipientSecondaries);
    const newRecipientPrimary = recipientRst.getPrimary();
    assert.neq(originalRecipientPrimary, newRecipientPrimary);
    originalRecipientPrimary =
        recipientRst.start(originalRecipientPrimary, {waitForConnect: true}, true );
    originalRecipientPrimary.setSecondaryOk();
    recipientRst.awaitReplication();
    steadyStateFunc(tenantMigrationTest);
    donorRst.stopSet();
    recipientRst.stopSet();
}
function testRollBack ( setUpFunc , rollbackOpsFunc , steadyStateFunc ) { const donorRst = new ReplSetTest ( { name : "donorRst" , nodes : 1 , nodeOptions : Object . assign ( { } , migrationX509Options . donor , { setParameter : { tenantMigrationGarbageCollectionDelayMS : kGarbageCollectionDelayMS , ttlMonitorSleepSecs : 1 , } } ) } ) ; donorRst . startSet ( ) ; donorRst . initiate ( ) ; const donorRstArgs = TenantMigrationUtil . createRstArgs ( donorRst ) ; const recipientRst = new ReplSetTest ( { name : "recipientRst" , nodes : 3 , nodeOptions : Object . assign ( { } , migrationX509Options . recipient , { setParameter : { tenantMigrationGarbageCollectionDelayMS : kGarbageCollectionDelayMS , ttlMonitorSleepSecs : 1 , } } ) } ) ; recipientRst . startSet ( ) ; recipientRst . initiate ( ) ; const tenantMigrationTest = new TenantMigrationTest ( { name : jsTestName ( ) , donorRst , recipientRst } ) ; setUpFunc ( tenantMigrationTest , donorRstArgs ) ; let originalRecipientPrimary = recipientRst . getPrimary ( ) ; const originalRecipientSecondaries = recipientRst . getSecondaries ( ) ; assert . commandWorked ( originalRecipientPrimary . adminCommand ( { setDefaultRWConcern : 1 , defaultWriteConcern : { w : 1 } , writeConcern : { w : "majority" } } ) ) ; recipientRst . awaitLastOpCommitted ( ) ; stopServerReplication ( originalRecipientSecondaries ) ; rollbackOpsFunc ( tenantMigrationTest , donorRstArgs ) ; recipientRst . stop ( originalRecipientPrimary ) ; restartServerReplication ( originalRecipientSecondaries ) ; const newRecipientPrimary = recipientRst . getPrimary ( ) ; assert . neq ( originalRecipientPrimary , newRecipientPrimary ) ; originalRecipientPrimary = recipientRst . start ( originalRecipientPrimary , { waitForConnect : true } , true ) ; originalRecipientPrimary . setSecondaryOk ( ) ; recipientRst . awaitReplication ( ) ; steadyStateFunc ( tenantMigrationTest ) ; donorRst . stopSet ( ) ; recipientRst . stopSet ( ) ; }
Starts a recipient ReplSetTest and creates a TenantMigrationTest for it.
Starts a recipient ReplSetTest and creates a TenantMigrationTest for it .
// The default WC is majority and stopServerReplication will prevent satisfying any majority // writes. // Disable replication on the secondaries so that writes during this step will be rolled back. // Shut down the primary and re-enable replication to allow one of the secondaries to get // elected, and make the writes above get rolled back on the original primary when it comes // back up. // Restart the original primary. /* restart */