diff options
author | Vesselina Ratcheva <vesselina.ratcheva@10gen.com> | 2019-02-20 13:42:23 -0500 |
---|---|---|
committer | Vesselina Ratcheva <vesselina.ratcheva@10gen.com> | 2019-02-26 14:57:59 -0500 |
commit | 58fad7d7efa275beb4a6a83f90d3dd222bbb534b (patch) | |
tree | 8dc0537629d4d7ec2ebed0b582c6f60838efe5dc /src/mongo/db/transaction_participant_test.cpp | |
parent | e61f7582788f51b2287f179c8f27ec8fa41744f7 (diff) | |
download | mongo-58fad7d7efa275beb4a6a83f90d3dd222bbb534b.tar.gz |
SERVER-39139 Disallow starting transactions on secondaries
Diffstat (limited to 'src/mongo/db/transaction_participant_test.cpp')
-rw-r--r-- | src/mongo/db/transaction_participant_test.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index 731666fb6e4..9a10fb02ed4 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -883,6 +883,51 @@ TEST_F(TxnParticipantTest, CannotAbortArbitraryPreparedTransactions) { ASSERT(_opObserver->transactionPrepared); } +TEST_F(TxnParticipantTest, CannotStartNewTransactionIfNotPrimary) { + ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( + repl::MemberState::RS_SECONDARY)); + + auto opCtxSession = std::make_unique<MongoDOperationContextSession>(opCtx()); + auto txnParticipant = TransactionParticipant::get(opCtx()); + + // Include 'autocommit=false' for transactions. + ASSERT_THROWS_CODE( + txnParticipant.beginOrContinue(opCtx(), *opCtx()->getTxnNumber(), false, true), + AssertionException, + ErrorCodes::NotMaster); +} + +TEST_F(TxnParticipantTest, CannotStartRetryableWriteIfNotPrimary) { + ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( + repl::MemberState::RS_SECONDARY)); + + auto opCtxSession = std::make_unique<MongoDOperationContextSession>(opCtx()); + auto txnParticipant = TransactionParticipant::get(opCtx()); + + // Omit the 'autocommit' field for retryable writes. + ASSERT_THROWS_CODE( + txnParticipant.beginOrContinue(opCtx(), *opCtx()->getTxnNumber(), boost::none, true), + AssertionException, + ErrorCodes::NotMaster); +} + +TEST_F(TxnParticipantTest, CannotContinueTransactionIfNotPrimary) { + // Will start the transaction. + auto sessionCheckout = checkOutSession(); + auto txnParticipant = TransactionParticipant::get(opCtx()); + ASSERT_TRUE(txnParticipant.inMultiDocumentTransaction()); + + ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( + repl::MemberState::RS_SECONDARY)); + + // Technically, the transaction should have been aborted on stepdown anyway, but it + // doesn't hurt to have this kind of coverage. + ASSERT_THROWS_CODE( + txnParticipant.beginOrContinue(opCtx(), *opCtx()->getTxnNumber(), false, false), + AssertionException, + ErrorCodes::NotMaster); +} + TEST_F(TxnParticipantTest, CannotStartNewTransactionWhilePreparedTransactionInProgress) { auto sessionCheckout = checkOutSession(); auto txnParticipant = TransactionParticipant::get(opCtx()); |