jstests/sharding/internal_txns/libs/chunk_migration_test.js
/*
     * Below are the steps in this test:
     * 1. Runs the commands specified in each 'testCase' inside an internal transaction of the
     *    specified type.
     * 2. Run migration0, i.e. migrate chunk [MinKey, 1] from shard0 to shard2.
     * 3. Retry writes in an internal transaction and retryable write.
     * 4. Restart shard2.
     * 5. Retry writes in an internal transaction and retryable write.
     * 6. Run migration1, i.e. migrate chunk [MinKey, 1] from shard2 to shard1.
     * 7. Retry writes in an internal transaction and retryable write.
     *
     * - If the type is non-retryable, verifies that none of the transactions has a
     *   config.transactions entry on the recipient after migration0 and returns early after step 3.
     * - If the type is retryable, verifies that the retryable write statements in each transaction
     *   are retryable on the recipient after each migration completes regardless of whether the
     *   transaction committed or aborted on the donor. For each transaction that aborts on the
     *   initial try, additionally verifies that the transaction does not have a config.transactions
     *   entry on the recipient after migration0.
     */
Below are the steps in this test:
1. Runs the commands specified in each 'testCase' inside an internal transaction of the
specified type.
2.

- If the type is non-retryable, verifies that none of the transactions has a
config.transactions entry on the recipient after migration0 and returns early after step 3.
- If the type is retryable, verifies that the retryable write statements in each transaction
are retryable on the recipient after each migration completes regardless of whether the
transaction committed or aborted on the donor. For each transaction that aborts on the
initial try, additionally verifies that the transaction does not have a config.transactions
entry on the recipient after migration0.
Below are the steps in this test : 1 . Runs the commands specified in each ' testCase ' inside an internal transaction of the specified type . 2 . - If the type is non - retryable verifies that none of the transactions has a config . transactions entry on the recipient after migration0 and returns early after step 3 . - If the type is retryable verifies that the retryable write statements in each transaction are retryable on the recipient after each migration completes regardless of whether the transaction committed or aborted on the donor . For each transaction that aborts on the initial try additionally verifies that the transaction does not have a config . transactions entry on the recipient after migration0 .
function testTransactionsBeforeChunkMigration(txnType, migrationOpts, testCases) {
        jsTest.log("Start running retryable internal transactions before migration0");
        for (let testCase of testCases) {
            runInternalTransactionOnInitialTry(txnType, testCase);
        }
        jsTest.log("Finished running retryable internal transactions before migration0");
        assert.commandWorked(st.s.adminCommand(migrationOpts.migration0.cmdObj));
        if (txnType == kInternalTxnType.kNonRetryable) {
            for (let testCase of testCases) {
                assertNoConfigTxnEntryOnRecipient(migrationOpts.migration0,
                                                  testCase.childLsidForNonRetryableWrite);
            }
            return;
        }
        for (let testCase of testCases) {
            if (testCase.abortOnInitialTry) {
                assertNoConfigTxnEntryOnRecipient(migrationOpts.migration0, testCase.parentLsid);
                assertNoConfigTxnEntryOnRecipient(migrationOpts.migration0,
                                                  testCase.childLsidForRetryableWrite);
            }
        }
        jsTest.log("Start retrying retryable internal transactions after migration0");
        for (let testCase of testCases) {
            runInternalTransactionOnRetry(
                txnType, testCase, testCase.abortOnInitialTry );
            runRetryableWriteOnRetry(testCase);
        }
        jsTest.log("Finished retrying retryable internal transactions after migration0");
        migrationOpts.migration0.recipientRst.stopSet(null , true );
        migrationOpts.migration0.recipientRst.startSet({restart: true});
        migrationOpts.migration0.recipientRst.getPrimary();
        jsTest.log("Start retrying retryable internal transactions after restarting the " +
                   "recipient after migration0");
        for (let testCase of testCases) {
            runInternalTransactionOnRetry(txnType, testCase, false );
            runRetryableWriteOnRetry(testCase);
        }
        jsTest.log("Finished retrying retryable internal transactions after restarting the " +
                   "recipient after migration0");
        assert.commandWorked(st.s.adminCommand(migrationOpts.migration1.cmdObj));
        jsTest.log("Start retrying retryable internal transactions after migration1");
        for (let testCase of testCases) {
            runInternalTransactionOnRetry(txnType, testCase, false );
            runRetryableWriteOnRetry(testCase);
        }
        jsTest.log("Finished retrying retryable internal transactions after migration1");
    }
function testTransactionsBeforeChunkMigration ( txnType , migrationOpts , testCases ) { jsTest . log ( "Start running retryable internal transactions before migration0" ) ; for ( let testCase of testCases ) { runInternalTransactionOnInitialTry ( txnType , testCase ) ; } jsTest . log ( "Finished running retryable internal transactions before migration0" ) ; assert . commandWorked ( st . s . adminCommand ( migrationOpts . migration0 . cmdObj ) ) ; if ( txnType == kInternalTxnType . kNonRetryable ) { for ( let testCase of testCases ) { assertNoConfigTxnEntryOnRecipient ( migrationOpts . migration0 , testCase . childLsidForNonRetryableWrite ) ; } return ; } for ( let testCase of testCases ) { if ( testCase . abortOnInitialTry ) { assertNoConfigTxnEntryOnRecipient ( migrationOpts . migration0 , testCase . parentLsid ) ; assertNoConfigTxnEntryOnRecipient ( migrationOpts . migration0 , testCase . childLsidForRetryableWrite ) ; } } jsTest . log ( "Start retrying retryable internal transactions after migration0" ) ; for ( let testCase of testCases ) { runInternalTransactionOnRetry ( txnType , testCase , testCase . abortOnInitialTry ) ; runRetryableWriteOnRetry ( testCase ) ; } jsTest . log ( "Finished retrying retryable internal transactions after migration0" ) ; migrationOpts . migration0 . recipientRst . stopSet ( null , true ) ; migrationOpts . migration0 . recipientRst . startSet ( { restart : true } ) ; migrationOpts . migration0 . recipientRst . getPrimary ( ) ; jsTest . log ( "Start retrying retryable internal transactions after restarting the " + "recipient after migration0" ) ; for ( let testCase of testCases ) { runInternalTransactionOnRetry ( txnType , testCase , false ) ; runRetryableWriteOnRetry ( testCase ) ; } jsTest . log ( "Finished retrying retryable internal transactions after restarting the " + "recipient after migration0" ) ; assert . commandWorked ( st . s . adminCommand ( migrationOpts . migration1 . cmdObj ) ) ; jsTest . log ( "Start retrying retryable internal transactions after migration1" ) ; for ( let testCase of testCases ) { runInternalTransactionOnRetry ( txnType , testCase , false ) ; runRetryableWriteOnRetry ( testCase ) ; } jsTest . log ( "Finished retrying retryable internal transactions after migration1" ) ; }
Below are the steps in this test:
 1.
Below are the steps in this test : 1 .
/* isRetryAfterAbort */ // Also retry the write statements as retryable writes. /* signal */ /*forRestart */ /* isRetryAfterAbort */ // Also retry the write statements as retryable writes. /* isRetryAfterAbort */ // Also retry the write statements as retryable writes.