diff options
Diffstat (limited to 'src/mongo/s/commands/internal_transactions_test_commands.cpp')
-rw-r--r-- | src/mongo/s/commands/internal_transactions_test_commands.cpp | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/mongo/s/commands/internal_transactions_test_commands.cpp b/src/mongo/s/commands/internal_transactions_test_commands.cpp index 81ac508f06e..9e827f8d35c 100644 --- a/src/mongo/s/commands/internal_transactions_test_commands.cpp +++ b/src/mongo/s/commands/internal_transactions_test_commands.cpp @@ -26,9 +26,17 @@ * exception statement from all source files in the program, then also delete * it in the license file. */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand + #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/cluster_transaction_api.h" #include "mongo/db/commands.h" +#include "mongo/db/transaction_api.h" +#include "mongo/logv2/log.h" #include "mongo/s/commands/internal_transactions_test_commands_gen.h" +#include "mongo/s/grid.h" +#include "mongo/s/transaction_router_resource_yielder.h" namespace mongo { namespace { @@ -41,7 +49,56 @@ public: public: using InvocationBase::InvocationBase; - void typedRun(OperationContext* opCtx){}; + TestInternalTransactionsReply typedRun(OperationContext* opCtx) { + Grid::get(opCtx)->assertShardingIsInitialized(); + + auto fixedExec = Grid::get(opCtx)->getExecutorPool()->getFixedExecutor(); + auto txn = txn_api::TransactionWithRetries( + opCtx, + fixedExec, + std::make_unique<txn_api::details::SEPTransactionClient>( + opCtx, + fixedExec, + std::make_unique<txn_api::details::ClusterSEPTransactionClientBehaviors>( + opCtx->getServiceContext())), + TransactionRouterResourceYielder::makeForLocalHandoff()); + + struct SharedBlock { + SharedBlock(std::vector<TestInternalTransactionsCommandInfo> commandInfos_) + : commandInfos(commandInfos_) {} + + std::vector<TestInternalTransactionsCommandInfo> commandInfos; + std::vector<BSONObj> responses; + }; + auto sharedBlock = std::make_shared<SharedBlock>(request().getCommandInfos()); + + // Swallow errors and let clients inspect the responses array to determine success / + // failure. + (void)txn.runSyncNoThrow( + opCtx, + [sharedBlock](const txn_api::TransactionClient& txnClient, ExecutorPtr txnExec) { + for (const auto& commandInfo : sharedBlock->commandInfos) { + const auto& dbName = commandInfo.getDbName(); + const auto& command = commandInfo.getCommand(); + auto assertSucceeds = commandInfo.getAssertSucceeds(); + + auto res = txnClient.runCommand(dbName, command).get(); + sharedBlock->responses.emplace_back( + CommandHelpers::filterCommandReplyForPassthrough( + res.removeField("recoveryToken"))); + + if (assertSucceeds) { + // Note this only inspects the top level ok field for non-write + // commands. + uassertStatusOK(getStatusFromWriteCommandReply(res)); + } + } + + return SemiFuture<void>::makeReady(); + }); + + return TestInternalTransactionsReply(std::move(sharedBlock->responses)); + }; NamespaceString ns() const override { return NamespaceString(request().getDbName(), ""); @@ -64,6 +121,8 @@ public: return "Internal command for testing internal transactions"; } + // This command can use the transaction API to run commands on different databases, so a single + // user database doesn't apply and we restrict this to only the admin database. bool adminOnly() const override { return true; } |