summaryrefslogtreecommitdiff
path: root/src/mongo/db/s/transaction_coordinator_catalog_test.cpp
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2019-02-08 15:59:57 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2019-02-12 07:08:25 -0500
commit3190e51d399f1e7c776afe6a9d0bbfbb6b9caea3 (patch)
treeab6bd3d88e5cf1747c67c140f7da43083a6f1883 /src/mongo/db/s/transaction_coordinator_catalog_test.cpp
parent1e7d26609cfa19c4840fe4ef4c1462b7fed48974 (diff)
downloadmongo-3190e51d399f1e7c776afe6a9d0bbfbb6b9caea3.tar.gz
SERVER-38521 Move all TransactionCoordinator sources to be under db/s
Diffstat (limited to 'src/mongo/db/s/transaction_coordinator_catalog_test.cpp')
-rw-r--r--src/mongo/db/s/transaction_coordinator_catalog_test.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/mongo/db/s/transaction_coordinator_catalog_test.cpp b/src/mongo/db/s/transaction_coordinator_catalog_test.cpp
new file mode 100644
index 00000000000..cffa0376efb
--- /dev/null
+++ b/src/mongo/db/s/transaction_coordinator_catalog_test.cpp
@@ -0,0 +1,171 @@
+
+/**
+ * Copyright (C) 2018-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/db/s/transaction_coordinator_catalog.h"
+#include "mongo/s/shard_server_test_fixture.h"
+#include "mongo/unittest/death_test.h"
+#include "mongo/unittest/unittest.h"
+
+namespace mongo {
+namespace {
+
+class TransactionCoordinatorCatalogTest : public ShardServerTestFixture {
+protected:
+ void setUp() override {
+ ShardServerTestFixture::setUp();
+
+ _coordinatorCatalog.emplace();
+ _coordinatorCatalog->exitStepUp(Status::OK());
+ }
+
+ void tearDown() override {
+ // Make sure all of the coordinators are in a committed/aborted state before they are
+ // destroyed. Otherwise, the coordinator's destructor will invariant because it will still
+ // have outstanding futures that have not been completed (the one to remove itself from the
+ // catalog). This has the added benefit of testing whether it's okay to destroy
+ // the catalog while there are outstanding coordinators.
+ for (auto& coordinator : _coordinatorsForTest) {
+ coordinator->cancelIfCommitNotYetStarted();
+ }
+ _coordinatorsForTest.clear();
+
+ ShardServerTestFixture::tearDown();
+ }
+
+ void createCoordinatorInCatalog(OperationContext* opCtx,
+ LogicalSessionId lsid,
+ TxnNumber txnNumber) {
+ auto newCoordinator =
+ std::make_shared<TransactionCoordinator>(getServiceContext(), lsid, txnNumber);
+
+ _coordinatorCatalog->insert(opCtx, lsid, txnNumber, newCoordinator);
+ _coordinatorsForTest.push_back(newCoordinator);
+ }
+
+ boost::optional<TransactionCoordinatorCatalog> _coordinatorCatalog;
+
+ std::vector<std::shared_ptr<TransactionCoordinator>> _coordinatorsForTest;
+};
+
+TEST_F(TransactionCoordinatorCatalogTest, GetOnSessionThatDoesNotExistReturnsNone) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber = 1;
+ auto coordinator = _coordinatorCatalog->get(operationContext(), lsid, txnNumber);
+ ASSERT(coordinator == nullptr);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest,
+ GetOnSessionThatExistsButTxnNumberThatDoesntExistReturnsNone) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber = 1;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
+ auto coordinatorInCatalog = _coordinatorCatalog->get(operationContext(), lsid, txnNumber + 1);
+ ASSERT(coordinatorInCatalog == nullptr);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest, CreateFollowedByGetReturnsCoordinator) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber = 1;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
+ auto coordinatorInCatalog = _coordinatorCatalog->get(operationContext(), lsid, txnNumber);
+ ASSERT(coordinatorInCatalog != nullptr);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest, SecondCreateForSessionDoesNotOverwriteFirstCreate) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber1 = 1;
+ TxnNumber txnNumber2 = 2;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber1);
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber2);
+
+ auto coordinator1InCatalog = _coordinatorCatalog->get(operationContext(), lsid, txnNumber1);
+ ASSERT(coordinator1InCatalog != nullptr);
+}
+
+DEATH_TEST_F(TransactionCoordinatorCatalogTest,
+ CreatingACoordinatorWithASessionIdAndTxnNumberThatAlreadyExistFails,
+ "Invariant failure") {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber = 1;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
+ // Re-creating w/ same session id and txn number should cause invariant failure
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest, GetLatestOnSessionWithNoCoordinatorsReturnsNone) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ auto latestTxnNumAndCoordinator =
+ _coordinatorCatalog->getLatestOnSession(operationContext(), lsid);
+ ASSERT_FALSE(latestTxnNumAndCoordinator);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest,
+ CreateFollowedByGetLatestOnSessionReturnsOnlyCoordinator) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber = 1;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
+ auto latestTxnNumAndCoordinator =
+ _coordinatorCatalog->getLatestOnSession(operationContext(), lsid);
+
+ ASSERT_TRUE(latestTxnNumAndCoordinator);
+ ASSERT_EQ(latestTxnNumAndCoordinator->first, txnNumber);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest, CoordinatorsRemoveThemselvesFromCatalogWhenTheyComplete) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber = 1;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
+ auto coordinator = _coordinatorCatalog->get(operationContext(), lsid, txnNumber);
+
+ coordinator->cancelIfCommitNotYetStarted();
+ ASSERT(coordinator->onCompletion().isReady());
+
+ auto latestTxnNumAndCoordinator =
+ _coordinatorCatalog->getLatestOnSession(operationContext(), lsid);
+ ASSERT_FALSE(latestTxnNumAndCoordinator);
+}
+
+TEST_F(TransactionCoordinatorCatalogTest,
+ TwoCreatesFollowedByGetLatestOnSessionReturnsCoordinatorWithHighestTxnNumber) {
+ LogicalSessionId lsid = makeLogicalSessionIdForTest();
+ TxnNumber txnNumber1 = 1;
+ TxnNumber txnNumber2 = 2;
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber1);
+ createCoordinatorInCatalog(operationContext(), lsid, txnNumber2);
+ auto latestTxnNumAndCoordinator =
+ _coordinatorCatalog->getLatestOnSession(operationContext(), lsid);
+
+ ASSERT_EQ(latestTxnNumAndCoordinator->first, txnNumber2);
+}
+
+} // namespace
+} // namespace mongo