summaryrefslogtreecommitdiff
path: root/src/mongo/s/commands/internal_transactions_test_commands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/s/commands/internal_transactions_test_commands.cpp')
-rw-r--r--src/mongo/s/commands/internal_transactions_test_commands.cpp61
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;
}