jstests/replsets/tenant_migration_concurrent_reads_on_donor.js
/**
 * Tests that the donor unblocks blocked reads (reads with atClusterTime/afterClusterTime >=
 * blockingTimestamp) once the migration aborts.
 */
Tests that the donor unblocks blocked reads (reads with atClusterTime/afterClusterTime >
blockingTimestamp) once the migration aborts.
Tests that the donor unblocks blocked reads ( reads with atClusterTime / afterClusterTime > blockingTimestamp ) once the migration aborts .
function testUnblockBlockedReadsAfterMigrationAborted(testCase, dbName, collName) {
    if (testCase.isLinearizableRead) {
        return;
    }
    const tenantId = dbName.split('_')[0];
    const migrationIdString = extractUUIDFromObject(UUID());
    const migrationOpts = {
        migrationIdString,
        tenantId,
    };
    const donorRst = tenantMigrationTest.getDonorRst();
    const donorPrimary = donorRst.getPrimary();
    let blockingFp =
        configureFailPoint(donorPrimary, "pauseTenantMigrationBeforeLeavingBlockingState");
    let abortFp =
        configureFailPoint(donorPrimary, "abortTenantMigrationBeforeLeavingBlockingState");
    assert.commandWorked(tenantMigrationTest.startMigration(migrationOpts));
    let resumeMigrationThread =
        new Thread(resumeMigrationAfterBlockingRead, donorPrimary.host, tenantId, 1);
    resumeMigrationThread.start();
    blockingFp.wait();
    donorRst.awaitLastOpCommitted();
    const donorDoc = donorPrimary.getCollection(TenantMigrationTest.kConfigDonorsNS).findOne({
        tenantId: tenantId
    });
    const command = testCase.requiresReadTimestamp
        ? testCase.command(collName, donorDoc.blockTimestamp)
        : testCase.command(collName);
    const nodes = testCase.isSupportedOnSecondaries ? donorRst.nodes : [donorPrimary];
    nodes.forEach(node => {
        const db = node.getDB(dbName);
        runCommand(db, command, null, testCase.isTransaction);
    });
    const shouldBlock = !testCase.isLinearizableRead;
    checkTenantMigrationAccessBlocker(donorPrimary, tenantId, {
        numBlockedReads: shouldBlock ? 1 : 0,
        numTenantMigrationAbortedErrors: 0
    });
    resumeMigrationThread.join();
    abortFp.off();
    TenantMigrationTest.assertAborted(
        tenantMigrationTest.waitForMigrationToComplete(migrationOpts));
    assert.commandWorked(tenantMigrationTest.forgetMigration(migrationIdString));
    tenantMigrationTest.waitForMigrationGarbageCollection(migrationIdString);
}
function testUnblockBlockedReadsAfterMigrationAborted ( testCase , dbName , collName ) { if ( testCase . isLinearizableRead ) { return ; } const tenantId = dbName . split ( '_' ) [ 0 ] ; const migrationIdString = extractUUIDFromObject ( UUID ( ) ) ; const migrationOpts = { migrationIdString , tenantId , } ; const donorRst = tenantMigrationTest . getDonorRst ( ) ; const donorPrimary = donorRst . getPrimary ( ) ; let blockingFp = configureFailPoint ( donorPrimary , "pauseTenantMigrationBeforeLeavingBlockingState" ) ; let abortFp = configureFailPoint ( donorPrimary , "abortTenantMigrationBeforeLeavingBlockingState" ) ; assert . commandWorked ( tenantMigrationTest . startMigration ( migrationOpts ) ) ; let resumeMigrationThread = new Thread ( resumeMigrationAfterBlockingRead , donorPrimary . host , tenantId , 1 ) ; resumeMigrationThread . start ( ) ; blockingFp . wait ( ) ; donorRst . awaitLastOpCommitted ( ) ; const donorDoc = donorPrimary . getCollection ( TenantMigrationTest . kConfigDonorsNS ) . findOne ( { tenantId : tenantId } ) ; const command = testCase . requiresReadTimestamp ? testCase . command ( collName , donorDoc . blockTimestamp ) : testCase . command ( collName ) ; const nodes = testCase . isSupportedOnSecondaries ? donorRst . nodes : [ donorPrimary ] ; nodes . forEach ( node => { const db = node . getDB ( dbName ) ; runCommand ( db , command , null , testCase . isTransaction ) ; } ) ; const shouldBlock = ! testCase . isLinearizableRead ; checkTenantMigrationAccessBlocker ( donorPrimary , tenantId , { numBlockedReads : shouldBlock ? 1 : 0 , numTenantMigrationAbortedErrors : 0 } ) ; resumeMigrationThread . join ( ) ; abortFp . off ( ) ; TenantMigrationTest . assertAborted ( tenantMigrationTest . waitForMigrationToComplete ( migrationOpts ) ) ; assert . commandWorked ( tenantMigrationTest . forgetMigration ( migrationIdString ) ) ; tenantMigrationTest . waitForMigrationGarbageCollection ( migrationIdString ) ; }
Tests that the donor unblocks blocked reads (reads with atClusterTime/afterClusterTime >
 blockingTimestamp) once the migration aborts.
Tests that the donor unblocks blocked reads ( reads with atClusterTime / afterClusterTime > blockingTimestamp ) once the migration aborts .
// Linearizable reads are not blocked. // Run the commands after the migration enters the blocking state. // Wait for the last oplog entry on the primary to be visible in the committed snapshot view of // the oplog on all secondaries to ensure that snapshot reads on the secondaries with // unspecified atClusterTime have read timestamp >= blockTimestamp. // The migration should unpause and abort after the read is blocked. Verify that the read // unblocks. // Reads just get unblocked if the migration aborts. // Verify that the migration failed due to the simulated error.