jstests/replsets/tenant_migration_recipient_access_blocker_rollback.js
// 4) Performs a read on the recipient primary.
4) Performs a read on the recipient primary.
4 ) Performs a read on the recipient primary .
function runRollbackAfterLoneRecipientForgetMigrationCommand(tenantId) {
    jsTestLog("Testing a rollback after migration has been committed and completely forgotten.");
    const tenantMigrationTest = new TenantMigrationTest(
        {name: jsTestName(), recipientRst: recipientRst, sharedOptions: {nodes: 1}});
    const kMigrationId = UUID();
    const kTenantId = tenantId;
    const kReadPreference = {mode: "primary"};
    const recipientCertificateForDonor = TenantMigrationUtil.getCertificateAndPrivateKey(
        "jstests/libs/tenant_migration_recipient.pem");
    const dbName = tenantMigrationTest.tenantDB(kTenantId, "testDB");
    const collName = "testColl";
    const originalPrimary = recipientRst.getPrimary();
    const newPrimary = recipientRst.getSecondaries()[0];
    assert.commandWorked(originalPrimary.getDB(dbName)[collName].insert(
        {x: "Composer", y: "Mysore Vasudevacharya"}));
    recipientRst.awaitReplication();
    const fpOriginalPrimary = configureFailPoint(originalPrimary, "hangBeforeTaskCompletion");
    const fpNewPrimary =
        configureFailPoint(newPrimary, "pauseBeforeRunTenantMigrationRecipientInstance");
    function runRecipientForgetMigration(host, {
        migrationIdString,
        donorConnectionString,
        tenantId,
        readPreference,
        recipientCertificateForDonor
    }) {
        const db = new Mongo(host);
        return db.adminCommand({
            recipientForgetMigration: 1,
            migrationId: UUID(migrationIdString),
            donorConnectionString,
            tenantId,
            readPreference,
            recipientCertificateForDonor
        });
    }
    const recipientForgetMigrationThread =
        new Thread(runRecipientForgetMigration, originalPrimary.host, {
            migrationIdString: extractUUIDFromObject(kMigrationId),
            donorConnectionString: tenantMigrationTest.getDonorRst().getURL(),
            tenantId: kTenantId,
            readPreference: kReadPreference,
            recipientCertificateForDonor
        });
    recipientForgetMigrationThread.start();
    jsTestLog("Wait until the right before the state document's 'expireAt' is set.");
    fpOriginalPrimary.wait();
    recipientRst.awaitReplication();
    assert.eq(1, originalPrimary.getDB(dbName)[collName].find().itcount());
    jsTestLog("Halting replication on the secondaries.");
    const secondaries = recipientRst.getSecondaries();
    stopServerReplication(secondaries);
    jsTestLog("Inserting random data on recipient primary.");
    const randomColl = originalPrimary.getDB("randomDB")["random_coll"];
    assert.commandWorked(randomColl.insert({x: "Que Sera Sera"}, {writeConcern: {w: 1}}));
    jsTestLog("Stepping up one of the secondaries.");
    assert.commandWorked(newPrimary.adminCommand({replSetStepUp: 1}));
    assert.commandFailedWithCode(recipientForgetMigrationThread.returnData(),
                                 ErrorCodes.InterruptedDueToReplStateChange);
    assert.eq(1, newPrimary.getDB(dbName)[collName].find().itcount());
    jsTestLog("Restarting server replication.");
    restartServerReplication(secondaries);
    recipientRst.awaitReplication();
    jsTestLog("Stepping up the original primary back to primary.");
    const fpOriginalPrimaryBeforeStarting =
        configureFailPoint(originalPrimary, "pauseBeforeRunTenantMigrationRecipientInstance");
    assert.commandWorked(originalPrimary.adminCommand({replSetStepUp: 1}));
    jsTestLog("Perform another read against the original primary on the tenant collection.");
    assert.eq(1, originalPrimary.getDB(dbName)[collName].find().itcount());
    fpOriginalPrimaryBeforeStarting.off();
    fpOriginalPrimary.off();
    fpNewPrimary.off();
    tenantMigrationTest.stop();
}
function runRollbackAfterLoneRecipientForgetMigrationCommand ( tenantId ) { jsTestLog ( "Testing a rollback after migration has been committed and completely forgotten." ) ; const tenantMigrationTest = new TenantMigrationTest ( { name : jsTestName ( ) , recipientRst : recipientRst , sharedOptions : { nodes : 1 } } ) ; const kMigrationId = UUID ( ) ; const kTenantId = tenantId ; const kReadPreference = { mode : "primary" } ; const recipientCertificateForDonor = TenantMigrationUtil . getCertificateAndPrivateKey ( "jstests/libs/tenant_migration_recipient.pem" ) ; const dbName = tenantMigrationTest . tenantDB ( kTenantId , "testDB" ) ; const collName = "testColl" ; const originalPrimary = recipientRst . getPrimary ( ) ; const newPrimary = recipientRst . getSecondaries ( ) [ 0 ] ; assert . commandWorked ( originalPrimary . getDB ( dbName ) [ collName ] . insert ( { x : "Composer" , y : "Mysore Vasudevacharya" } ) ) ; recipientRst . awaitReplication ( ) ; const fpOriginalPrimary = configureFailPoint ( originalPrimary , "hangBeforeTaskCompletion" ) ; const fpNewPrimary = configureFailPoint ( newPrimary , "pauseBeforeRunTenantMigrationRecipientInstance" ) ; function runRecipientForgetMigration ( host , { migrationIdString , donorConnectionString , tenantId , readPreference , recipientCertificateForDonor } ) { const db = new Mongo ( host ) ; return db . adminCommand ( { recipientForgetMigration : 1 , migrationId : UUID ( migrationIdString ) , donorConnectionString , tenantId , readPreference , recipientCertificateForDonor } ) ; } const recipientForgetMigrationThread = new Thread ( runRecipientForgetMigration , originalPrimary . host , { migrationIdString : extractUUIDFromObject ( kMigrationId ) , donorConnectionString : tenantMigrationTest . getDonorRst ( ) . getURL ( ) , tenantId : kTenantId , readPreference : kReadPreference , recipientCertificateForDonor } ) ; recipientForgetMigrationThread . start ( ) ; jsTestLog ( "Wait until the right before the state document's 'expireAt' is set." ) ; fpOriginalPrimary . wait ( ) ; recipientRst . awaitReplication ( ) ; assert . eq ( 1 , originalPrimary . getDB ( dbName ) [ collName ] . find ( ) . itcount ( ) ) ; jsTestLog ( "Halting replication on the secondaries." ) ; const secondaries = recipientRst . getSecondaries ( ) ; stopServerReplication ( secondaries ) ; jsTestLog ( "Inserting random data on recipient primary." ) ; const randomColl = originalPrimary . getDB ( "randomDB" ) [ "random_coll" ] ; assert . commandWorked ( randomColl . insert ( { x : "Que Sera Sera" } , { writeConcern : { w : 1 } } ) ) ; jsTestLog ( "Stepping up one of the secondaries." ) ; assert . commandWorked ( newPrimary . adminCommand ( { replSetStepUp : 1 } ) ) ; assert . commandFailedWithCode ( recipientForgetMigrationThread . returnData ( ) , ErrorCodes . InterruptedDueToReplStateChange ) ; assert . eq ( 1 , newPrimary . getDB ( dbName ) [ collName ] . find ( ) . itcount ( ) ) ; jsTestLog ( "Restarting server replication." ) ; restartServerReplication ( secondaries ) ; recipientRst . awaitReplication ( ) ; jsTestLog ( "Stepping up the original primary back to primary." ) ; const fpOriginalPrimaryBeforeStarting = configureFailPoint ( originalPrimary , "pauseBeforeRunTenantMigrationRecipientInstance" ) ; assert . commandWorked ( originalPrimary . adminCommand ( { replSetStepUp : 1 } ) ) ; jsTestLog ( "Perform another read against the original primary on the tenant collection." ) ; assert . eq ( 1 , originalPrimary . getDB ( dbName ) [ collName ] . find ( ) . itcount ( ) ) ; fpOriginalPrimaryBeforeStarting . off ( ) ; fpOriginalPrimary . off ( ) ; fpNewPrimary . off ( ) ; tenantMigrationTest . stop ( ) ; }
4) Performs a read on the recipient primary.
4 ) Performs a read on the recipient primary .
// We will have the tenant database already on the recipient, as though the tenant migration has // already run to completion, and the state document has been cleaned up already. // Prevent the "expireAt" field from being populated. // Prevent the new primary from marking the state document as garbage collectable. // Run a delayed/retried recipientForgetMigration command after the state doc has been deleted. // It should be possible to read from the recipient now. // Now perform a rollback on the recipient primary. // Stepping up one of the secondaries should cause the original primary to rollback. // It should be possible to read from new recipient primary.