diff options
author | XueruiFa <xuerui.fa@mongodb.com> | 2020-08-19 15:52:12 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-19 20:18:54 +0000 |
commit | d3169bf266e409f68784aa512511c680b5cc6aa4 (patch) | |
tree | 3d9a546e87f5cc5c0cde61329aa73af10cf9f373 /src/mongo/db | |
parent | 45a9e0a76e4a9ef995b3490d74610cab98dbcc0a (diff) | |
download | mongo-d3169bf266e409f68784aa512511c680b5cc6aa4.tar.gz |
SERVER-49377: Ensure transactions inherit API parameters of initiating command
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/initialize_api_parameters.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/initialize_api_parameters.h | 10 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.cpp | 25 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.h | 27 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant_test.cpp | 163 |
6 files changed, 226 insertions, 15 deletions
diff --git a/src/mongo/db/initialize_api_parameters.cpp b/src/mongo/db/initialize_api_parameters.cpp index e84c9384418..a0e0a95220b 100644 --- a/src/mongo/db/initialize_api_parameters.cpp +++ b/src/mongo/db/initialize_api_parameters.cpp @@ -106,4 +106,10 @@ APIParameters APIParameters::fromClient(const APIParametersFromClient& apiParams return apiParameters; } +void APIParameters::appendInfo(BSONObjBuilder* builder) const { + builder->append(kAPIVersionFieldName, _apiVersion); + builder->append(kAPIStrictFieldName, _apiStrict); + builder->append(kAPIDeprecationErrorsFieldName, _apiDeprecationErrors); +} + } // namespace mongo diff --git a/src/mongo/db/initialize_api_parameters.h b/src/mongo/db/initialize_api_parameters.h index 391e4009599..9ca8bec10b7 100644 --- a/src/mongo/db/initialize_api_parameters.h +++ b/src/mongo/db/initialize_api_parameters.h @@ -50,10 +50,16 @@ const APIParametersFromClient initializeAPIParameters(const BSONObj& requestBody class APIParameters { public: + static constexpr StringData kAPIVersionFieldName = "apiVersion"_sd; + static constexpr StringData kAPIStrictFieldName = "apiStrict"_sd; + static constexpr StringData kAPIDeprecationErrorsFieldName = "apiDeprecationErrors"_sd; + APIParameters(); static APIParameters& get(OperationContext* opCtx); static APIParameters fromClient(const APIParametersFromClient& apiParamsFromClient); + void appendInfo(BSONObjBuilder* builder) const; + const StringData getAPIVersion() const { return _apiVersion; } @@ -82,8 +88,8 @@ public: return _paramsPassed; } - void setParamsPassed(bool noParamsPassed) { - _paramsPassed = noParamsPassed; + void setParamsPassed(bool paramsPassed) { + _paramsPassed = paramsPassed; } private: diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 61940332adf..34e8ff987d4 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -630,6 +630,9 @@ void invokeWithSessionCheckedOut(OperationContext* opCtx, tenant_migration_donor::checkIfCanReadOrBlock(opCtx, request.getDatabase()); + // Use the API parameters that were stored when the transaction was initiated. + APIParameters::get(opCtx) = txnParticipant.getAPIParameters(opCtx); + try { tenant_migration_donor::migrationConflictRetry( opCtx, @@ -1149,6 +1152,13 @@ void execCommandDatabase(OperationContext* opCtx, opCtx->lockState()->setShouldConflictWithSecondaryBatchApplication(false); } + if (opCtx->inMultiDocumentTransaction() && !startTransaction) { + uassert(4937700, + "API parameters are only allowed in the first command of a multi-document " + "transaction", + !APIParameters::get(opCtx).getParamsPassed()); + } + // Remember whether or not this operation is starting a transaction, in case something // later in the execution needs to adjust its behavior based on this. opCtx->setIsStartingMultiDocumentTransaction(startTransaction); diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp index 9b7d6ae21d3..5a63291993d 100644 --- a/src/mongo/db/transaction_participant.cpp +++ b/src/mongo/db/transaction_participant.cpp @@ -745,6 +745,7 @@ TransactionParticipant::TxnResources::TxnResources(WithLock wl, opCtx->getServiceContext()->getStorageEngine()->newRecoveryUnit()), WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork); + _apiParameters = APIParameters::get(opCtx); _readConcernArgs = repl::ReadConcernArgs::get(opCtx); _uncommittedCollections = UncommittedCollections::get(opCtx).shareResources(); } @@ -821,6 +822,9 @@ void TransactionParticipant::TxnResources::release(OperationContext* opCtx) { opCtx->setWriteUnitOfWork(WriteUnitOfWork::createForSnapshotResume(opCtx, _ruState)); + auto& apiParameters = APIParameters::get(opCtx); + apiParameters = _apiParameters; + auto& readConcernArgs = repl::ReadConcernArgs::get(opCtx); readConcernArgs = _readConcernArgs; } @@ -1487,6 +1491,15 @@ void TransactionParticipant::Participant::shutdown(OperationContext* opCtx) { o(lock).txnResourceStash = boost::none; } +APIParameters TransactionParticipant::Participant::getAPIParameters(OperationContext* opCtx) const { + // If we have are in a retryable write, use the API parameters that the client passed in with + // the write, instead of the first write's API parameters. + if (o().txnResourceStash && !o().txnState.isInRetryableWriteMode()) { + return o().txnResourceStash->getAPIParameters(); + } + return APIParameters::get(opCtx); +} + bool TransactionParticipant::Observer::expiredAsOf(Date_t when) const { return o().txnState.isInProgress() && o().transactionExpireDate && o().transactionExpireDate < when; @@ -1635,6 +1648,7 @@ void TransactionParticipant::Participant::_abortTransactionOnSession(OperationCo _logSlowTransaction(opCtx, &(o().txnResourceStash->locker()->getLockerInfo(boost::none))->stats, TerminationCause::kAborted, + o().txnResourceStash->getAPIParameters(), o().txnResourceStash->getReadConcernArgs()); } @@ -1652,6 +1666,7 @@ void TransactionParticipant::Participant::_cleanUpTxnResourceOnOpCtx( opCtx, &(opCtx->lockState()->getLockerInfo(CurOp::get(*opCtx)->getLockStatsBase()))->stats, terminationCause, + APIParameters::get(opCtx), repl::ReadConcernArgs::get(opCtx)); // Reset the WUOW. We should be able to abort empty transactions that don't have WUOW. @@ -1869,6 +1884,7 @@ std::string TransactionParticipant::Participant::_transactionInfoForLog( OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs) const { invariant(lockStats); @@ -1883,6 +1899,7 @@ std::string TransactionParticipant::Participant::_transactionInfoForLog( parametersBuilder.append("txnNumber", o().activeTxnNumber); parametersBuilder.append("autocommit", p().autoCommit ? *p().autoCommit : true); + apiParameters.appendInfo(¶metersBuilder); readConcernArgs.appendInfo(¶metersBuilder); s << "parameters:" << parametersBuilder.obj().toString() << ","; @@ -1942,6 +1959,7 @@ void TransactionParticipant::Participant::_transactionInfoForLog( OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs, logv2::DynamicAttributes* pAttrs) const { invariant(lockStats); @@ -1955,6 +1973,7 @@ void TransactionParticipant::Participant::_transactionInfoForLog( parametersBuilder.append("txnNumber", o().activeTxnNumber); parametersBuilder.append("autocommit", p().autoCommit ? *p().autoCommit : true); + apiParameters.appendInfo(¶metersBuilder); readConcernArgs.appendInfo(¶metersBuilder); pAttrs->add("parameters", parametersBuilder.obj()); @@ -2009,6 +2028,7 @@ BSONObj TransactionParticipant::Participant::_transactionInfoBSONForLog( OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs) const { invariant(lockStats); @@ -2021,6 +2041,7 @@ BSONObj TransactionParticipant::Participant::_transactionInfoBSONForLog( parametersBuilder.append("txnNumber", o().activeTxnNumber); parametersBuilder.append("autocommit", p().autoCommit ? *p().autoCommit : true); + apiParameters.appendInfo(¶metersBuilder); readConcernArgs.appendInfo(¶metersBuilder); BSONObjBuilder logLine; @@ -2085,6 +2106,7 @@ void TransactionParticipant::Participant::_logSlowTransaction( OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs) { // Only log multi-document transactions. if (!o().txnState.isInRetryableWriteMode()) { @@ -2099,7 +2121,8 @@ void TransactionParticipant::Participant::_logSlowTransaction( Milliseconds(serverGlobalParams.slowMS)) .first) { logv2::DynamicAttributes attr; - _transactionInfoForLog(opCtx, lockStats, terminationCause, readConcernArgs, &attr); + _transactionInfoForLog( + opCtx, lockStats, terminationCause, apiParameters, readConcernArgs, &attr); LOGV2_OPTIONS(51802, {logv2::LogComponent::kTransaction}, "transaction", attr); } } diff --git a/src/mongo/db/transaction_participant.h b/src/mongo/db/transaction_participant.h index 10314d38188..8fad2122368 100644 --- a/src/mongo/db/transaction_participant.h +++ b/src/mongo/db/transaction_participant.h @@ -37,6 +37,7 @@ #include "mongo/db/commands/txn_cmds_gen.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/concurrency/locker.h" +#include "mongo/db/initialize_api_parameters.h" #include "mongo/db/logical_session_id.h" #include "mongo/db/multi_key_path_tracker.h" #include "mongo/db/ops/update_request.h" @@ -207,6 +208,13 @@ public: void release(OperationContext* opCtx); /** + * Returns the stored API parameters. + */ + const APIParameters& getAPIParameters() const { + return _apiParameters; + } + + /** * Returns the read concern arguments. */ const repl::ReadConcernArgs& getReadConcernArgs() const { @@ -218,6 +226,7 @@ public: std::unique_ptr<Locker> _locker; std::unique_ptr<Locker::LockSnapshot> _lockSnapshot; std::unique_ptr<RecoveryUnit> _recoveryUnit; + APIParameters _apiParameters; repl::ReadConcernArgs _readConcernArgs; WriteUnitOfWork::RecoveryUnitState _ruState; std::shared_ptr<UncommittedCollections::UncommittedCollectionsMap> _uncommittedCollections; @@ -583,6 +592,12 @@ public: */ void shutdown(OperationContext* opCtx); + /** + * Returns the API parameters stored in the transaction resources stash if it exists and we + * are not in a retryable write. Otherwise, returns the API parameters decorating the opCtx. + */ + APIParameters getAPIParameters(OperationContext* opCtx) const; + // // Methods for use in C++ unit tests, only. Beware: these methods may not adhere to the // concurrency control rules. @@ -592,22 +607,26 @@ public: OperationContext* opCtx, const SingleThreadedLockStats* lockStats, bool committed, + const APIParameters& apiParameters, const repl::ReadConcernArgs& readConcernArgs) const { TerminationCause terminationCause = committed ? TerminationCause::kCommitted : TerminationCause::kAborted; - return _transactionInfoForLog(opCtx, lockStats, terminationCause, readConcernArgs); + return _transactionInfoForLog( + opCtx, lockStats, terminationCause, apiParameters, readConcernArgs); } BSONObj getTransactionInfoBSONForLogForTest( OperationContext* opCtx, const SingleThreadedLockStats* lockStats, bool committed, + const APIParameters& apiParameters, const repl::ReadConcernArgs& readConcernArgs) const { TerminationCause terminationCause = committed ? TerminationCause::kCommitted : TerminationCause::kAborted; - return _transactionInfoBSONForLog(opCtx, lockStats, terminationCause, readConcernArgs); + return _transactionInfoBSONForLog( + opCtx, lockStats, terminationCause, apiParameters, readConcernArgs); } @@ -701,6 +720,7 @@ public: void _logSlowTransaction(OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs); // This method returns a string with information about a slow transaction. The format of the @@ -710,17 +730,20 @@ public: std::string _transactionInfoForLog(OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs) const; void _transactionInfoForLog(OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs, logv2::DynamicAttributes* pAttrs) const; BSONObj _transactionInfoBSONForLog(OperationContext* opCtx, const SingleThreadedLockStats* lockStats, TerminationCause terminationCause, + APIParameters apiParameters, repl::ReadConcernArgs readConcernArgs) const; // Bumps up the transaction number of this transaction and perform the necessary cleanup. diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index 2579f47687a..18c8dd9486c 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -1317,6 +1317,41 @@ TEST_F(TxnParticipantTest, StashInNestedSessionIsANoop) { } } +TEST_F(TxnParticipantTest, CorrectlyStashAPIParameters) { + auto sessionCheckout = checkOutSession(); + auto txnParticipant = TransactionParticipant::get(opCtx()); + + auto defaultAPIParams = txnParticipant.getAPIParameters(opCtx()); + ASSERT_EQ("1", defaultAPIParams.getAPIVersion()); + ASSERT_FALSE(defaultAPIParams.getAPIStrict()); + ASSERT_FALSE(defaultAPIParams.getAPIDeprecationErrors()); + + txnParticipant.unstashTransactionResources(opCtx(), "insert"); + + APIParameters updatedAPIParams = APIParameters(); + updatedAPIParams.setAPIVersion("2"); + updatedAPIParams.setAPIStrict(true); + updatedAPIParams.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = updatedAPIParams; + + // Verify that API parameters on the opCtx were updated correctly. + auto opCtxAPIParams = APIParameters::get(opCtx()); + ASSERT_EQ("2", opCtxAPIParams.getAPIVersion()); + ASSERT_TRUE(opCtxAPIParams.getAPIStrict()); + ASSERT_TRUE(opCtxAPIParams.getAPIDeprecationErrors()); + + txnParticipant.stashTransactionResources(opCtx()); + + // Reset the API parameters on the opCtx to the default values. + APIParameters::get(opCtx()) = defaultAPIParams; + + // Verify that 'getAPIParameters()' will return the stashed API parameters. + APIParameters storedAPIParams = txnParticipant.getAPIParameters(opCtx()); + ASSERT_EQ("2", storedAPIParams.getAPIVersion()); + ASSERT_TRUE(storedAPIParams.getAPIStrict()); + ASSERT_TRUE(storedAPIParams.getAPIDeprecationErrors()); +} + /** * Test fixture for testing behavior that depends on a server's cluster role. * @@ -2851,6 +2886,44 @@ TEST_F(TransactionsMetricsTest, ReportUnstashedResourcesForARetryableWrite) { ASSERT_BSONOBJ_EQ(unstashedStateBuilder.obj(), reportBuilder.obj()); } +TEST_F(TransactionsMetricsTest, UseAPIParametersOnOpCtxForARetryableWrite) { + ASSERT(opCtx()->lockState()); + ASSERT(opCtx()->recoveryUnit()); + + APIParameters firstAPIParameters = APIParameters(); + firstAPIParameters.setAPIVersion("2"); + firstAPIParameters.setAPIStrict(true); + firstAPIParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = firstAPIParameters; + + MongoDOperationContextSession opCtxSession(opCtx()); + auto txnParticipant = TransactionParticipant::get(opCtx()); + txnParticipant.beginOrContinue(opCtx(), *opCtx()->getTxnNumber(), boost::none, boost::none); + + APIParameters secondAPIParameters = APIParameters(); + secondAPIParameters.setAPIVersion("3"); + APIParameters::get(opCtx()) = secondAPIParameters; + + // 'getAPIParameters()' should return the API parameters decorating opCtx if we are in a + // retryable write. + APIParameters storedAPIParameters = txnParticipant.getAPIParameters(opCtx()); + ASSERT_EQ("3", storedAPIParameters.getAPIVersion()); + ASSERT_FALSE(storedAPIParameters.getAPIStrict()); + ASSERT_FALSE(storedAPIParameters.getAPIDeprecationErrors()); + + // Stash secondAPIParameters. + txnParticipant.stashTransactionResources(opCtx()); + + APIParameters thirdAPIParameters = APIParameters(); + thirdAPIParameters.setAPIVersion("4"); + APIParameters::get(opCtx()) = thirdAPIParameters; + + // 'getAPIParameters()' should still return API parameters, even if there are stashed API + // parameters in TxnResources. + storedAPIParameters = txnParticipant.getAPIParameters(opCtx()); + ASSERT_EQ("4", storedAPIParameters.getAPIVersion()); +} + namespace { /* @@ -2974,13 +3047,18 @@ void setupAdditiveMetrics(const int metricValue, OperationContext* opCtx) { void buildParametersInfoString(StringBuilder* sb, LogicalSessionId sessionId, const TxnNumber txnNum, + const APIParameters apiParameters, const repl::ReadConcernArgs readConcernArgs, bool autocommitVal) { BSONObjBuilder lsidBuilder; sessionId.serialize(&lsidBuilder); auto autocommitString = autocommitVal ? "true" : "false"; + auto apiStrictString = apiParameters.getAPIStrict() ? "true" : "false"; + auto apiDeprecationErrorsString = apiParameters.getAPIDeprecationErrors() ? "true" : "false"; (*sb) << "parameters:{ lsid: " << lsidBuilder.done().toString() << ", txnNumber: " << txnNum - << ", autocommit: " << autocommitString + << ", autocommit: " << autocommitString << ", apiVersion: \"" + << apiParameters.getAPIVersion() << "\", apiStrict: " << apiStrictString + << ", apiDeprecationErrors: " << apiDeprecationErrorsString << ", readConcern: " << readConcernArgs.toBSON().getObjectField("readConcern") << " },"; } @@ -3056,8 +3134,12 @@ std::string buildTransactionInfoString(OperationContext* opCtx, // In cases where we call getTransactionInfoForLogForTest after aborting a transaction // and check if the output matches this function's output, we must explicitly set autocommitVal // to true. - buildParametersInfoString( - ¶metersInfo, sessionId, txnNum, repl::ReadConcernArgs::get(opCtx), autocommitVal); + buildParametersInfoString(¶metersInfo, + sessionId, + txnNum, + APIParameters::get(opCtx), + repl::ReadConcernArgs::get(opCtx), + autocommitVal); StringBuilder readTimestampInfo; readTimestampInfo @@ -3265,6 +3347,12 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterCommit) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3282,7 +3370,7 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterCommit) { const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none); ASSERT(lockerInfo); std::string testTransactionInfo = txnParticipant.getTransactionInfoForLogForTest( - opCtx(), &lockerInfo->stats, true, readConcernArgs); + opCtx(), &lockerInfo->stats, true, apiParameters, readConcernArgs); std::string expectedTransactionInfo = buildTransactionInfoString(opCtx(), @@ -3305,6 +3393,12 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterCommit) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3326,7 +3420,7 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterCommit) { const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none); ASSERT(lockerInfo); std::string testTransactionInfo = txnParticipant.getTransactionInfoForLogForTest( - opCtx(), &lockerInfo->stats, true, readConcernArgs); + opCtx(), &lockerInfo->stats, true, apiParameters, readConcernArgs); std::string expectedTransactionInfo = buildTransactionInfoString(opCtx(), @@ -3347,6 +3441,12 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterAbort) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3364,7 +3464,7 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterAbort) { ASSERT(lockerInfo); std::string testTransactionInfo = txnParticipant.getTransactionInfoForLogForTest( - opCtx(), &lockerInfo->stats, false, readConcernArgs); + opCtx(), &lockerInfo->stats, false, apiParameters, readConcernArgs); std::string expectedTransactionInfo = buildTransactionInfoString(opCtx(), @@ -3388,6 +3488,12 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterAbort) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3408,7 +3514,7 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterAbort) { ASSERT(lockerInfo); std::string testTransactionInfo = txnParticipant.getTransactionInfoForLogForTest( - opCtx(), &lockerInfo->stats, false, readConcernArgs); + opCtx(), &lockerInfo->stats, false, apiParameters, readConcernArgs); std::string expectedTransactionInfo = buildTransactionInfoString(opCtx(), @@ -3426,6 +3532,12 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterAbort) { DEATH_TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogWithNoLockerInfoStats, "invariant") { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3442,7 +3554,8 @@ DEATH_TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogWithNoLockerInfoS txnParticipant.unstashTransactionResources(opCtx(), "commitTransaction"); txnParticipant.commitUnpreparedTransaction(opCtx()); - txnParticipant.getTransactionInfoForLogForTest(opCtx(), nullptr, true, readConcernArgs); + txnParticipant.getTransactionInfoForLogForTest( + opCtx(), nullptr, true, apiParameters, readConcernArgs); } TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowCommit) { @@ -3450,6 +3563,12 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowCommit) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3491,7 +3610,7 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowCommit) { ASSERT(lockerInfo); BSONObj expected = txnParticipant.getTransactionInfoBSONForLogForTest( - opCtx(), &lockerInfo->stats, true, readConcernArgs); + opCtx(), &lockerInfo->stats, true, apiParameters, readConcernArgs); ASSERT_EQUALS(1, countBSONFormatLogLinesIsSubset(expected)); } @@ -3500,6 +3619,12 @@ TEST_F(TransactionsMetricsTest, LogPreparedTransactionInfoAfterSlowCommit) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3539,7 +3664,7 @@ TEST_F(TransactionsMetricsTest, LogPreparedTransactionInfoAfterSlowCommit) { ASSERT(lockerInfo); BSONObj expected = txnParticipant.getTransactionInfoBSONForLogForTest( - opCtx(), &lockerInfo->stats, true, readConcernArgs); + opCtx(), &lockerInfo->stats, true, apiParameters, readConcernArgs); ASSERT_EQUALS(1, countBSONFormatLogLinesIsSubset(expected)); } @@ -3601,6 +3726,12 @@ TEST_F(TransactionsMetricsTest, LogPreparedTransactionInfoAfterSlowAbort) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3657,6 +3788,12 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterExceptionInPrepare) { auto tickSource = initMockTickSource(); auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" @@ -3715,6 +3852,12 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowStashedAbort) { auto sessionCheckout = checkOutSession(); + APIParameters apiParameters = APIParameters(); + apiParameters.setAPIVersion("2"); + apiParameters.setAPIStrict(true); + apiParameters.setAPIDeprecationErrors(true); + APIParameters::get(opCtx()) = apiParameters; + repl::ReadConcernArgs readConcernArgs; ASSERT_OK( readConcernArgs.initialize(BSON("find" |