summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2017-08-18 20:19:59 -0400
committerRandolph Tan <randolph@10gen.com>2017-08-26 02:14:50 -0400
commitdc8a9cc980e84734d90ffc0f71c50c123cdd9543 (patch)
tree3357fd45cf8d3ddfdae938aed58a85e545a14344
parentec42f5f16ff7809c5b1ed29601978e9e98aa5925 (diff)
downloadmongo-dc8a9cc980e84734d90ffc0f71c50c123cdd9543.tar.gz
SERVER-28914 Create a test fixture with mock replication coordinator and ephemeral storage engine
-rw-r--r--src/mongo/db/SConscript6
-rw-r--r--src/mongo/db/ops/SConscript3
-rw-r--r--src/mongo/db/ops/write_ops_retryability_test.cpp72
-rw-r--r--src/mongo/db/repl/SConscript12
-rw-r--r--src/mongo/db/repl/mock_repl_coord_server_fixture.cpp91
-rw-r--r--src/mongo/db/repl/mock_repl_coord_server_fixture.h63
-rw-r--r--src/mongo/db/session_test.cpp86
-rw-r--r--src/mongo/db/transaction_history_iterator_test.cpp58
8 files changed, 201 insertions, 190 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index b74534df190..1302ce14683 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -1528,8 +1528,7 @@ env.CppUnitTest(
'session_test.cpp',
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/repl/replmocks',
- 'service_context_d_test_fixture',
+ '$BUILD_DIR/mongo/db/repl/mock_repl_coord_server_fixture',
'write_ops',
],
)
@@ -1540,8 +1539,7 @@ env.CppUnitTest(
'transaction_history_iterator_test.cpp',
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/repl/replmocks',
- 'service_context_d_test_fixture',
+ '$BUILD_DIR/mongo/db/repl/mock_repl_coord_server_fixture',
'write_ops',
],
)
diff --git a/src/mongo/db/ops/SConscript b/src/mongo/db/ops/SConscript
index ec3fd359719..2254606f570 100644
--- a/src/mongo/db/ops/SConscript
+++ b/src/mongo/db/ops/SConscript
@@ -188,9 +188,8 @@ env.CppUnitTest(
target='write_ops_retryability_test',
source='write_ops_retryability_test.cpp',
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/repl/mock_repl_coord_server_fixture',
'$BUILD_DIR/mongo/db/repl/oplog_entry',
- '$BUILD_DIR/mongo/db/repl/replmocks',
- '$BUILD_DIR/mongo/db/service_context_d_test_fixture',
'$BUILD_DIR/mongo/db/write_ops',
],
)
diff --git a/src/mongo/db/ops/write_ops_retryability_test.cpp b/src/mongo/db/ops/write_ops_retryability_test.cpp
index 86f581659ba..78dcc32bc39 100644
--- a/src/mongo/db/ops/write_ops_retryability_test.cpp
+++ b/src/mongo/db/ops/write_ops_retryability_test.cpp
@@ -36,6 +36,7 @@
#include "mongo/db/ops/write_ops.h"
#include "mongo/db/ops/write_ops_retryability.h"
#include "mongo/db/query/find_and_modify_request.h"
+#include "mongo/db/repl/mock_repl_coord_server_fixture.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/service_context.h"
@@ -117,62 +118,7 @@ TEST_F(WriteOpsRetryability, ParseOplogEntryForDelete) {
ASSERT_BSONOBJ_EQ(res.getUpsertedId(), BSONObj());
}
-class FindAndModifyRetryability : public ServiceContextMongoDTest {
-public:
- void setUp() override {
- ServiceContextMongoDTest::setUp();
-
- _opCtx = cc().makeOperationContext();
-
- // Insert code path assumes existence of repl coordinator!
- repl::ReplSettings replSettings;
- replSettings.setReplSetString(
- ConnectionString::forReplicaSet("sessionTxnStateTest", {HostAndPort("a:1")})
- .toString());
- replSettings.setMaster(true);
-
- auto service = getServiceContext();
- repl::ReplicationCoordinator::set(
- service, stdx::make_unique<repl::ReplicationCoordinatorMock>(service, replSettings));
-
- // Note: internal code does not allow implicit creation of non-capped oplog collection.
- DBDirectClient client(opCtx());
- ASSERT_TRUE(
- client.createCollection(NamespaceString::kRsOplogNamespace.ns(), 1024 * 1024, true));
- }
-
- void tearDown() override {
- // ServiceContextMongoDTest::tearDown() will try to create it's own opCtx, and it's not
- // allowed to have 2 present per client, so destroy this one.
- _opCtx.reset();
-
- ServiceContextMongoDTest::tearDown();
- }
-
- /**
- * Helper method for inserting new entries to the oplog. This completely bypasses
- * fixDocumentForInsert.
- */
- void insertOplogEntry(BSONObj entry) {
- AutoGetCollection autoColl(opCtx(), NamespaceString::kRsOplogNamespace, MODE_IX);
- auto coll = autoColl.getCollection();
- ASSERT_TRUE(coll != nullptr);
-
- auto status = coll->insertDocument(opCtx(),
- InsertStatement(entry),
- &CurOp::get(opCtx())->debug(),
- /* enforceQuota */ false,
- /* fromMigrate */ false);
- ASSERT_OK(status);
- }
-
- OperationContext* opCtx() {
- return _opCtx.get();
- }
-
-private:
- ServiceContext::UniqueOperationContext _opCtx;
-};
+using FindAndModifyRetryability = MockReplCoordServerFixture;
NamespaceString kNs("test.user");
@@ -200,7 +146,7 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsUpsertButOplogIsUpdate) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("x" << 1 << "z" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry oplog(
repl::OpTime(), 0, repl::OpTypeEnum::kUpdate, kNs, BSON("x" << 1), BSON("y" << 1));
@@ -227,7 +173,7 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsPostImageButOplogHasPre) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("x" << 1 << "z" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry updateOplog(repl::OpTime(),
0,
@@ -249,7 +195,7 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsUpdateButOplogIsDelete) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("x" << 1 << "z" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry oplog(repl::OpTime(), 0, repl::OpTypeEnum::kDelete, kNs, BSON("_id" << 1));
oplog.setPreImageTs(imageTs);
@@ -265,7 +211,7 @@ TEST_F(FindAndModifyRetryability, ErrorIfRequestIsPreImageButOplogHasPost) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("x" << 1 << "z" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry updateOplog(repl::OpTime(),
0,
@@ -287,7 +233,7 @@ TEST_F(FindAndModifyRetryability, UpdateWithPreImage) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("x" << 1 << "z" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry updateOplog(repl::OpTime(),
0,
@@ -315,7 +261,7 @@ TEST_F(FindAndModifyRetryability, UpdateWithPostImage) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("a" << 1 << "b" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry updateOplog(repl::OpTime(),
0,
@@ -359,7 +305,7 @@ TEST_F(FindAndModifyRetryability, BasicRemove) {
repl::OplogEntry noteOplog(
repl::OpTime(imageTs, 1), 0, repl::OpTypeEnum::kNoop, kNs, BSON("_id" << 20 << "a" << 1));
- insertOplogEntry(noteOplog.toBSON());
+ insertOplogEntry(noteOplog);
repl::OplogEntry removeOplog(
repl::OpTime(), 0, repl::OpTypeEnum::kDelete, kNs, BSON("_id" << 20));
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 117de59f608..105e279b774 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -1602,3 +1602,15 @@ env.Library(
'sync_tail',
],
)
+
+env.Library(
+ target='mock_repl_coord_server_fixture',
+ source=[
+ 'mock_repl_coord_server_fixture.cpp',
+ ],
+ LIBDEPS=[
+ 'replmocks',
+ '$BUILD_DIR/mongo/db/service_context_d_test_fixture',
+ ]
+)
+
diff --git a/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp b/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp
new file mode 100644
index 00000000000..1389a8caf94
--- /dev/null
+++ b/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2017 MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * 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 GNU Affero General 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/repl/mock_repl_coord_server_fixture.h"
+
+#include "mongo/db/client.h"
+#include "mongo/db/curop.h"
+#include "mongo/db/db_raii.h"
+#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/repl/oplog_entry.h"
+#include "mongo/db/repl/replication_coordinator_mock.h"
+#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_d_test_fixture.h"
+
+namespace mongo {
+
+void MockReplCoordServerFixture::setUp() {
+ ServiceContextMongoDTest::setUp();
+
+ _opCtx = cc().makeOperationContext();
+
+ // Insert code path assumes existence of repl coordinator!
+ repl::ReplSettings replSettings;
+ replSettings.setReplSetString(
+ ConnectionString::forReplicaSet("sessionTxnStateTest", {HostAndPort("a:1")}).toString());
+ replSettings.setMaster(true);
+
+ auto service = getServiceContext();
+ repl::ReplicationCoordinator::set(
+ service, stdx::make_unique<repl::ReplicationCoordinatorMock>(service, replSettings));
+
+ // Note: internal code does not allow implicit creation of non-capped oplog collection.
+ DBDirectClient client(opCtx());
+ ASSERT_TRUE(
+ client.createCollection(NamespaceString::kRsOplogNamespace.ns(), 1024 * 1024, true));
+}
+
+void MockReplCoordServerFixture::tearDown() {
+ // ServiceContextMongoDTest::tearDown() will try to create it's own opCtx, and it's not
+ // allowed to have 2 present per client, so destroy this one.
+ _opCtx.reset();
+
+ ServiceContextMongoDTest::tearDown();
+}
+
+void MockReplCoordServerFixture::insertOplogEntry(const repl::OplogEntry& entry) {
+ AutoGetCollection autoColl(opCtx(), NamespaceString::kRsOplogNamespace, MODE_IX);
+ auto coll = autoColl.getCollection();
+ ASSERT_TRUE(coll != nullptr);
+
+ auto status = coll->insertDocument(opCtx(),
+ InsertStatement(entry.toBSON()),
+ &CurOp::get(opCtx())->debug(),
+ /* enforceQuota */ false,
+ /* fromMigrate */ false);
+ ASSERT_OK(status);
+}
+
+OperationContext* MockReplCoordServerFixture::opCtx() {
+ return _opCtx.get();
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/repl/mock_repl_coord_server_fixture.h b/src/mongo/db/repl/mock_repl_coord_server_fixture.h
new file mode 100644
index 00000000000..71f1fa06fec
--- /dev/null
+++ b/src/mongo/db/repl/mock_repl_coord_server_fixture.h
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2017 MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * 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 GNU Affero General 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/db/operation_context.h"
+#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_d_test_fixture.h"
+#include "mongo/unittest/unittest.h"
+
+namespace mongo {
+
+class OperationContext;
+
+namespace repl {
+class OplogEntry;
+}
+
+/**
+ * This is a basic fixture that is backed by an ephemeral storage engine and a mock replication
+ * coordinator that is running as primary.
+ */
+class MockReplCoordServerFixture : public ServiceContextMongoDTest {
+public:
+ void setUp() override;
+ void tearDown() override;
+
+ /**
+ * Helper method for inserting new entries to the oplog. This completely bypasses
+ * fixDocumentForInsert.
+ */
+ void insertOplogEntry(const repl::OplogEntry& entry);
+
+ OperationContext* opCtx();
+
+private:
+ ServiceContext::UniqueOperationContext _opCtx;
+};
+
+} // namespace mongo
diff --git a/src/mongo/db/session_test.cpp b/src/mongo/db/session_test.cpp
index 0170a9f03fd..f9864e8ad2f 100644
--- a/src/mongo/db/session_test.cpp
+++ b/src/mongo/db/session_test.cpp
@@ -36,6 +36,7 @@
#include "mongo/db/db_raii.h"
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/repl/mock_repl_coord_server_fixture.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/repl/optime.h"
@@ -49,65 +50,16 @@
namespace mongo {
namespace {
-class SessionTest : public ServiceContextMongoDTest {
+class SessionTest : public MockReplCoordServerFixture {
public:
void setUp() override {
- ServiceContextMongoDTest::setUp();
-
- _opCtx = cc().makeOperationContext();
-
- // Insert code path assumes existence of repl coordinator!
- repl::ReplSettings replSettings;
- replSettings.setReplSetString(
- ConnectionString::forReplicaSet("sessionTxnStateTest", {HostAndPort("a:1")})
- .toString());
- replSettings.setMaster(true);
-
- auto service = getServiceContext();
- repl::ReplicationCoordinator::set(
- service, stdx::make_unique<repl::ReplicationCoordinatorMock>(service, replSettings));
+ MockReplCoordServerFixture::setUp();
+ auto service = opCtx()->getServiceContext();
SessionCatalog::reset_forTest(service);
SessionCatalog::create(service);
- SessionCatalog::get(service)->onStepUp(_opCtx.get());
-
- // Note: internal code does not allow implicit creation of non-capped oplog collection.
- DBDirectClient client(opCtx());
- ASSERT_TRUE(
- client.createCollection(NamespaceString::kRsOplogNamespace.ns(), 1024 * 1024, true));
- }
-
- void tearDown() override {
- // ServiceContextMongoDTest::tearDown() will try to create it's own opCtx, and it's not
- // allowed to have 2 present per client, so destroy this one.
- _opCtx.reset();
-
- ServiceContextMongoDTest::tearDown();
+ SessionCatalog::get(service)->onStepUp(opCtx());
}
-
- /**
- * Helper method for inserting new entries to the oplog. This completely bypasses
- * fixDocumentForInsert.
- */
- void insertOplogEntry(BSONObj entry) {
- AutoGetCollection autoColl(opCtx(), NamespaceString::kRsOplogNamespace, MODE_IX);
- auto coll = autoColl.getCollection();
- ASSERT_TRUE(coll != nullptr);
-
- auto status = coll->insertDocument(opCtx(),
- InsertStatement(entry),
- &CurOp::get(opCtx())->debug(),
- /* enforceQuota */ false,
- /* fromMigrate */ false);
- ASSERT_OK(status);
- }
-
- OperationContext* opCtx() {
- return _opCtx.get();
- }
-
-private:
- ServiceContext::UniqueOperationContext _opCtx;
};
TEST_F(SessionTest, CanCreateNewSessionEntry) {
@@ -514,18 +466,22 @@ TEST_F(SessionTest, CheckStatementExecuted) {
// Returns the correct oplog entry if the statement has completed.
auto optimeTs = Timestamp(50, 10);
- insertOplogEntry(BSON("ts" << optimeTs << "t" << 1LL << "h" << 0LL << "op"
- << "i"
- << "ns"
- << "a.b"
- << "o"
- << BSON("_id" << 1 << "x" << 5)
- << "txnNumber"
- << txnNum
- << "stmtId"
- << stmtId
- << "prevTs"
- << Timestamp(0, 0)));
+
+ OperationSessionInfo opSessionInfo;
+ opSessionInfo.setSessionId(sessionId);
+ opSessionInfo.setTxnNumber(txnNum);
+
+ repl::OplogEntry oplogEntry(repl::OpTime(optimeTs, 1),
+ 0,
+ repl::OpTypeEnum::kInsert,
+ NamespaceString("a.b"),
+ 0,
+ BSON("_id" << 1 << "x" << 5));
+ oplogEntry.setOperationSessionInfo(opSessionInfo);
+ oplogEntry.setStatementId(stmtId);
+ oplogEntry.setPrevWriteTsInTransaction(Timestamp(0, 0));
+ insertOplogEntry(oplogEntry);
+
{
AutoGetCollection autoColl(opCtx(), NamespaceString("a.b"), MODE_IX);
WriteUnitOfWork wuow(opCtx());
diff --git a/src/mongo/db/transaction_history_iterator_test.cpp b/src/mongo/db/transaction_history_iterator_test.cpp
index 18464573f94..687ced1b8cf 100644
--- a/src/mongo/db/transaction_history_iterator_test.cpp
+++ b/src/mongo/db/transaction_history_iterator_test.cpp
@@ -37,6 +37,7 @@
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/repl/mock_repl_coord_server_fixture.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/repl/optime.h"
@@ -49,62 +50,7 @@
namespace mongo {
-class SessionHistoryIteratorTest : public ServiceContextMongoDTest {
-public:
- void setUp() override {
- ServiceContextMongoDTest::setUp();
-
- _opCtx = cc().makeOperationContext();
-
- // Insert code path assumes existence of repl coordinator!
- repl::ReplSettings replSettings;
- replSettings.setReplSetString(
- ConnectionString::forReplicaSet("sessionTxnStateTest", {HostAndPort("a:1")})
- .toString());
- replSettings.setMaster(true);
-
- auto service = getServiceContext();
- repl::ReplicationCoordinator::set(
- service, stdx::make_unique<repl::ReplicationCoordinatorMock>(service, replSettings));
-
- // Note: internal code does not allow implicit creation of non-capped oplog collection.
- DBDirectClient client(opCtx());
- ASSERT_TRUE(
- client.createCollection(NamespaceString::kRsOplogNamespace.ns(), 1024 * 1024, true));
- }
-
- void tearDown() override {
- // ServiceContextMongoDTest::tearDown() will try to create it's own opCtx, and it's not
- // allowed to have 2 present per client, so destroy this one.
- _opCtx.reset();
-
- ServiceContextMongoDTest::tearDown();
- }
-
- /**
- * Helper method for inserting new entries to the oplog. This completely bypasses
- * fixDocumentForInsert.
- */
- void insertOplogEntry(const repl::OplogEntry newOplog) {
- AutoGetCollection autoColl(opCtx(), NamespaceString::kRsOplogNamespace, MODE_IX);
- auto coll = autoColl.getCollection();
- ASSERT_TRUE(coll != nullptr);
-
- auto status = coll->insertDocument(opCtx(),
- InsertStatement(newOplog.toBSON()),
- &CurOp::get(opCtx())->debug(),
- /* enforceQuota */ false,
- /* fromMigrate */ false);
- ASSERT_OK(status);
- }
-
- OperationContext* opCtx() {
- return _opCtx.get();
- }
-
-private:
- ServiceContext::UniqueOperationContext _opCtx;
-};
+using SessionHistoryIteratorTest = MockReplCoordServerFixture;
TEST_F(SessionHistoryIteratorTest, NormalHistory) {
repl::OplogEntry entry1(repl::OpTime(Timestamp(52, 345), 2),