summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2018-07-18 13:46:53 -0400
committerHenrik Edin <henrik.edin@mongodb.com>2018-07-27 16:20:53 -0400
commitbfe170e49b1dc10b2badde45bc13c057a2f8ab61 (patch)
treef71d35e019c3194d033545c73296d415e18eb496
parent018905518ca552775255f36a52e9fd187f9d61f8 (diff)
downloadmongo-bfe170e49b1dc10b2badde45bc13c057a2f8ab61.tar.gz
SERVER-36258 Construct ServiceContext after mongo initializers complete.
-rw-r--r--jstests/sharding/time_zone_info_mongos.js4
-rw-r--r--src/mongo/client/SConscript1
-rw-r--r--src/mongo/client/mongo_uri_test.cpp65
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/catalog_raii_test.cpp5
-rw-r--r--src/mongo/db/db.cpp18
-rw-r--r--src/mongo/db/query/datetime/init_timezone_data.cpp43
-rw-r--r--src/mongo/db/repl/SConscript6
-rw-r--r--src/mongo/db/repl/base_cloner_test_fixture.h4
-rw-r--r--src/mongo/db/repl/databases_cloner_test.cpp4
-rw-r--r--src/mongo/db/repl/initial_syncer_test.cpp6
-rw-r--r--src/mongo/db/repl/isself_test.cpp5
-rw-r--r--src/mongo/db/repl/multiapplier_test.cpp4
-rw-r--r--src/mongo/db/repl/repl_set_config_checks_test.cpp51
-rw-r--r--src/mongo/db/service_context.cpp17
-rw-r--r--src/mongo/db/service_context_test_fixture.cpp16
-rw-r--r--src/mongo/db/service_context_test_fixture.h22
-rw-r--r--src/mongo/db/sorter/SConscript1
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp5
-rw-r--r--src/mongo/db/storage/kv/SConscript2
-rw-r--r--src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp3
-rw-r--r--src/mongo/db/storage/kv/kv_database_catalog_entry_test.cpp7
-rw-r--r--src/mongo/db/storage/wiredtiger/SConscript1
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_init_test.cpp3
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp3
-rw-r--r--src/mongo/db/update/SConscript1
-rw-r--r--src/mongo/db/update/update_node_test_fixture.h3
-rw-r--r--src/mongo/dbtests/dbtests.cpp1
-rw-r--r--src/mongo/embedded/embedded.cpp1
-rw-r--r--src/mongo/executor/task_executor_test_common.cpp4
-rw-r--r--src/mongo/executor/task_executor_test_fixture.cpp5
-rw-r--r--src/mongo/executor/task_executor_test_fixture.h1
-rw-r--r--src/mongo/s/SConscript1
-rw-r--r--src/mongo/s/client/shard_connection_test.cpp3
-rw-r--r--src/mongo/s/server.cpp11
-rw-r--r--src/mongo/shell/dbshell.cpp2
-rw-r--r--src/mongo/tools/bridge.cpp1
-rw-r--r--src/mongo/unittest/SConscript2
-rw-r--r--src/mongo/unittest/benchmark_main.cpp2
-rw-r--r--src/mongo/unittest/integration_test_main.cpp1
40 files changed, 198 insertions, 138 deletions
diff --git a/jstests/sharding/time_zone_info_mongos.js b/jstests/sharding/time_zone_info_mongos.js
index 5ed4dd9866b..c75ac56628b 100644
--- a/jstests/sharding/time_zone_info_mongos.js
+++ b/jstests/sharding/time_zone_info_mongos.js
@@ -28,7 +28,9 @@
// Test that a non-existent timezone directory causes mongoS startup to fail.
conn = MongoRunner.runMongos({configdb: st.configRS.getURL(), timeZoneInfo: tzNoInfo});
assert.eq(conn, null, "expected launching mongos with bad timezone rules to fail");
- assert.neq(-1, rawMongoProgramOutput().indexOf("Failed global initialization"));
+ // Look for either old or new error message
+ assert(rawMongoProgramOutput().indexOf("Failed to create service context") != -1 ||
+ rawMongoProgramOutput().indexOf("Failed global initialization") != -1);
// Enable sharding on the test DB and ensure its primary is st.shard0.shardName.
assert.commandWorked(mongosDB.adminCommand({enableSharding: mongosDB.getName()}));
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript
index 43af0a24e0e..8bdb16a9c98 100644
--- a/src/mongo/client/SConscript
+++ b/src/mongo/client/SConscript
@@ -37,6 +37,7 @@ env.CppUnitTest(
],
LIBDEPS=[
'$BUILD_DIR/mongo/transport/transport_layer_egress_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'clientdriver_network',
],
)
diff --git a/src/mongo/client/mongo_uri_test.cpp b/src/mongo/client/mongo_uri_test.cpp
index 9584bfd6f9a..d934bcde049 100644
--- a/src/mongo/client/mongo_uri_test.cpp
+++ b/src/mongo/client/mongo_uri_test.cpp
@@ -35,18 +35,18 @@
#include "mongo/bson/bsontypes.h"
#include "mongo/bson/json.h"
#include "mongo/client/mongo_uri.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
#include <boost/filesystem/operations.hpp>
+namespace mongo {
namespace {
-using mongo::MongoURI;
-
struct URITestCase {
std::string URI;
std::string uname;
std::string password;
- mongo::ConnectionString::ConnectionType type;
+ ConnectionString::ConnectionType type;
std::string setname;
size_t numservers;
size_t numOptions;
@@ -57,8 +57,8 @@ struct InvalidURITestCase {
std::string URI;
};
-const mongo::ConnectionString::ConnectionType kMaster = mongo::ConnectionString::MASTER;
-const mongo::ConnectionString::ConnectionType kSet = mongo::ConnectionString::SET;
+const ConnectionString::ConnectionType kMaster = ConnectionString::MASTER;
+const ConnectionString::ConnectionType kSet = ConnectionString::SET;
const URITestCase validCases[] = {
@@ -407,34 +407,34 @@ const InvalidURITestCase invalidCases[] = {
};
// Helper Method to take a filename for a json file and return the array of tests inside of it
-mongo::BSONObj getBsonFromJsonFile(std::string fileName) {
+BSONObj getBsonFromJsonFile(std::string fileName) {
boost::filesystem::path directoryPath = boost::filesystem::current_path();
boost::filesystem::path filePath(directoryPath / "src" / "mongo" / "client" /
"mongo_uri_tests" / fileName);
std::string filename(filePath.string());
std::ifstream infile(filename.c_str());
std::string data((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());
- mongo::BSONObj obj = mongo::fromjson(data);
- ASSERT_TRUE(obj.valid(mongo::BSONVersion::kLatest));
+ BSONObj obj = fromjson(data);
+ ASSERT_TRUE(obj.valid(BSONVersion::kLatest));
ASSERT_TRUE(obj.hasField("tests"));
- mongo::BSONObj arr = obj.getField("tests").embeddedObject().getOwned();
+ BSONObj arr = obj.getField("tests").embeddedObject().getOwned();
ASSERT_TRUE(arr.couldBeArray());
return arr;
}
// Helper method to take a BSONElement and either extract its string or return an empty string
-std::string returnStringFromElementOrNull(mongo::BSONElement element) {
+std::string returnStringFromElementOrNull(BSONElement element) {
ASSERT_TRUE(!element.eoo());
- if (element.type() == mongo::jstNULL) {
+ if (element.type() == jstNULL) {
return std::string();
}
- ASSERT_EQ(element.type(), mongo::String);
+ ASSERT_EQ(element.type(), String);
return element.String();
}
// Helper method to take a valid test case, parse() it, and assure the output is correct
void testValidURIFormat(URITestCase testCase) {
- mongo::unittest::log() << "Testing URI: " << testCase.URI << '\n';
+ unittest::log() << "Testing URI: " << testCase.URI << '\n';
std::string errMsg;
const auto cs_status = MongoURI::parse(testCase.URI);
ASSERT_OK(cs_status);
@@ -462,13 +462,13 @@ TEST(MongoURI, InvalidURIs) {
for (size_t i = 0; i != numCases; ++i) {
const InvalidURITestCase testCase = invalidCases[i];
- mongo::unittest::log() << "Testing URI: " << testCase.URI << '\n';
+ unittest::log() << "Testing URI: " << testCase.URI << '\n';
auto cs_status = MongoURI::parse(testCase.URI);
ASSERT_NOT_OK(cs_status);
}
}
-TEST(MongoURI, ValidButBadURIsFailToConnect) {
+TEST_F(ServiceContextTest, ValidButBadURIsFailToConnect) {
// "invalid" is a TLD that cannot exit on the public internet (see rfc2606). It should always
// parse as a valid URI, but connecting should always fail.
auto sw_uri = MongoURI::parse("mongodb://user:pass@hostname.invalid:12345");
@@ -477,7 +477,7 @@ TEST(MongoURI, ValidButBadURIsFailToConnect) {
ASSERT_TRUE(uri.isValid());
std::string errmsg;
- auto dbclient = uri.connect(mongo::StringData(), errmsg);
+ auto dbclient = uri.connect(StringData(), errmsg);
ASSERT_EQ(dbclient, static_cast<decltype(dbclient)>(nullptr));
}
@@ -494,7 +494,7 @@ TEST(MongoURI, CloneURIForServer) {
auto& uriOptions = uri.getOptions();
ASSERT_EQ(uriOptions.at("ssl"), "true");
- auto clonedURI = uri.cloneURIForServer(mongo::HostAndPort{"localhost:27020"});
+ auto clonedURI = uri.cloneURIForServer(HostAndPort{"localhost:27020"});
ASSERT_EQ(clonedURI.type(), kMaster);
ASSERT_TRUE(clonedURI.getSetName().empty());
@@ -524,7 +524,7 @@ TEST(MongoURI, specTests) {
const auto testBson = getBsonFromJsonFile(file);
for (const auto& testElement : testBson) {
- ASSERT_EQ(testElement.type(), mongo::Object);
+ ASSERT_EQ(testElement.type(), Object);
const auto test = testElement.Obj();
// First extract the valid field and the uri field
@@ -535,13 +535,13 @@ TEST(MongoURI, specTests) {
const auto uriDoc = test.getField("uri");
ASSERT_FALSE(uriDoc.eoo());
- ASSERT_EQ(uriDoc.type(), mongo::String);
+ ASSERT_EQ(uriDoc.type(), String);
const auto uri = uriDoc.String();
if (!valid) {
// This uri string is invalid --> parse the uri and ensure it fails
const InvalidURITestCase testCase = {uri};
- mongo::unittest::log() << "Testing URI: " << testCase.URI << '\n';
+ unittest::log() << "Testing URI: " << testCase.URI << '\n';
auto cs_status = MongoURI::parse(testCase.URI);
ASSERT_NOT_OK(cs_status);
} else {
@@ -552,8 +552,8 @@ TEST(MongoURI, specTests) {
const auto auth = test.getField("auth");
ASSERT_FALSE(auth.eoo());
- if (auth.type() != mongo::jstNULL) {
- ASSERT_EQ(auth.type(), mongo::Object);
+ if (auth.type() != jstNULL) {
+ ASSERT_EQ(auth.type(), Object);
const auto authObj = auth.embeddedObject();
database = returnStringFromElementOrNull(authObj.getField("db"));
username = returnStringFromElementOrNull(authObj.getField("username"));
@@ -563,22 +563,22 @@ TEST(MongoURI, specTests) {
// parse the hosts
const auto hosts = test.getField("hosts");
ASSERT_FALSE(hosts.eoo());
- ASSERT_EQ(hosts.type(), mongo::Array);
+ ASSERT_EQ(hosts.type(), Array);
const auto numHosts = static_cast<size_t>(hosts.Obj().nFields());
// parse the options
- mongo::ConnectionString::ConnectionType connectionType = kMaster;
+ ConnectionString::ConnectionType connectionType = kMaster;
size_t numOptions = 0;
std::string setName;
const auto optionsElement = test.getField("options");
ASSERT_FALSE(optionsElement.eoo());
- if (optionsElement.type() != mongo::jstNULL) {
- ASSERT_EQ(optionsElement.type(), mongo::Object);
+ if (optionsElement.type() != jstNULL) {
+ ASSERT_EQ(optionsElement.type(), Object);
const auto optionsObj = optionsElement.Obj();
numOptions = optionsObj.nFields();
const auto replsetElement = optionsObj.getField("replicaSet");
if (!replsetElement.eoo()) {
- ASSERT_EQ(replsetElement.type(), mongo::String);
+ ASSERT_EQ(replsetElement.type(), String);
setName = replsetElement.String();
connectionType = kSet;
}
@@ -600,7 +600,6 @@ TEST(MongoURI, specTests) {
}
TEST(MongoURI, srvRecordTest) {
- using namespace mongo;
enum Expectation : bool { success = true, failure = false };
const struct {
int lineNumber;
@@ -843,11 +842,10 @@ TEST(MongoURI, srvRecordTest) {
for (std::size_t i = 0; i < std::min(options.size(), expectedOptions.size()); ++i) {
if (options[i] != expectedOptions[i]) {
- mongo::unittest::log() << "Option: \"" << options[i].first << "="
- << options[i].second << "\" doesn't equal: \""
- << expectedOptions[i].first << "="
- << expectedOptions[i].second << "\""
- << " data on line: " << test.lineNumber << std::endl;
+ unittest::log() << "Option: \"" << options[i].first << "=" << options[i].second
+ << "\" doesn't equal: \"" << expectedOptions[i].first << "="
+ << expectedOptions[i].second << "\""
+ << " data on line: " << test.lineNumber << std::endl;
std::cerr << "Failing URI: \"" << test.uri << "\""
<< " data on line: " << test.lineNumber << std::endl;
ASSERT(false);
@@ -874,3 +872,4 @@ TEST(MongoURI, srvRecordTest) {
}
} // namespace
+} // namespace mongo
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index afa17539d9f..b792d074862 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -679,6 +679,7 @@ env.CppUnitTest(
'auth/authmocks',
'catalog/database_holder_mock',
'catalog_raii',
+ 'service_context_test_fixture',
'stats/fill_locker_info',
],
)
diff --git a/src/mongo/db/catalog_raii_test.cpp b/src/mongo/db/catalog_raii_test.cpp
index 05a0bfeb1cb..fc78ed36cfa 100644
--- a/src/mongo/db/catalog_raii_test.cpp
+++ b/src/mongo/db/catalog_raii_test.cpp
@@ -36,6 +36,7 @@
#include "mongo/db/client.h"
#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/concurrency/lock_state.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/log.h"
#include "mongo/util/time_support.h"
@@ -43,13 +44,13 @@
namespace mongo {
namespace {
-class CatalogRAIITestFixture : public unittest::Test {
+class CatalogRAIITestFixture : public ServiceContextTest {
public:
typedef std::pair<ServiceContext::UniqueClient, ServiceContext::UniqueOperationContext>
ClientAndCtx;
ClientAndCtx makeClientWithLocker(const std::string& clientName) {
- auto client = getGlobalServiceContext()->makeClient(clientName);
+ auto client = getServiceContext()->makeClient(clientName);
auto opCtx = client->makeOperationContext();
opCtx->swapLockState(stdx::make_unique<LockerImpl>());
return std::make_pair(std::move(client), std::move(opCtx));
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 36c5bd0b149..19762719102 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -364,7 +364,7 @@ ExitCode _initAndListen(int listenPort) {
}
// Disallow running a storage engine that doesn't support capped collections with --profile
- if (!getGlobalServiceContext()->getStorageEngine()->supportsCappedCollections() &&
+ if (!serviceContext->getStorageEngine()->supportsCappedCollections() &&
serverGlobalParams.defaultProfile != 0) {
log() << "Running " << storageGlobalParams.engine << " with profiling is not supported. "
<< "Make sure you are not using --profile.";
@@ -803,10 +803,7 @@ auto makeReplicationExecutor(ServiceContext* serviceContext) {
executor::makeNetworkInterface("Replication", nullptr, std::move(hookList)));
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(CreateReplicationManager,
- ("SSLManager", "ServiceContext", "default"))
-(InitializerContext* context) {
- auto serviceContext = getGlobalServiceContext();
+void setUpReplication(ServiceContext* serviceContext) {
repl::StorageInterface::set(serviceContext, stdx::make_unique<repl::StorageInterfaceImpl>());
auto storageInterface = repl::StorageInterface::get(serviceContext);
@@ -843,7 +840,6 @@ MONGO_INITIALIZER_WITH_PREREQUISITES(CreateReplicationManager,
static_cast<int64_t>(curTimeMillis64()));
repl::ReplicationCoordinator::set(serviceContext, std::move(replCoord));
repl::setOplogCollectionName(serviceContext);
- return Status::OK();
}
#ifdef MONGO_CONFIG_SSL
@@ -990,7 +986,17 @@ int mongoDbMain(int argc, char* argv[], char** envp) {
severe(LogComponent::kControl) << "Failed global initialization: " << status;
quickExit(EXIT_FAILURE);
}
+
+ try {
+ setGlobalServiceContext(ServiceContext::make());
+ } catch (...) {
+ auto cause = exceptionToStatus();
+ severe(LogComponent::kControl) << "Failed to create service context: " << redact(cause);
+ quickExit(EXIT_FAILURE);
+ }
+
auto service = getGlobalServiceContext();
+ setUpReplication(service);
service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service));
ErrorExtraInfo::invariantHaveAllParsers();
diff --git a/src/mongo/db/query/datetime/init_timezone_data.cpp b/src/mongo/db/query/datetime/init_timezone_data.cpp
index 18a842f231c..d93f9202b32 100644
--- a/src/mongo/db/query/datetime/init_timezone_data.cpp
+++ b/src/mongo/db/query/datetime/init_timezone_data.cpp
@@ -38,28 +38,25 @@
#include "mongo/util/mongoutils/str.h"
namespace mongo {
-
-MONGO_INITIALIZER_WITH_PREREQUISITES(
- LoadTimeZoneDB, ("GlobalLogManager", "EndStartupOptionStorage", "ServiceContext"))
-(InitializerContext* context) {
- auto serviceContext = getGlobalServiceContext();
- if (!serverGlobalParams.timeZoneInfoPath.empty()) {
- std::unique_ptr<timelib_tzdb, TimeZoneDatabase::TimeZoneDBDeleter> timeZoneDatabase(
- timelib_zoneinfo(const_cast<char*>(serverGlobalParams.timeZoneInfoPath.c_str())),
- TimeZoneDatabase::TimeZoneDBDeleter());
- if (!timeZoneDatabase) {
- return {ErrorCodes::FailedToParse,
- str::stream() << "failed to load time zone database from path \""
- << serverGlobalParams.timeZoneInfoPath
- << "\""};
+namespace {
+ServiceContext::ConstructorActionRegisterer loadTimeZoneDB{
+ "LoadTimeZoneDB", [](ServiceContext* service) {
+ if (!serverGlobalParams.timeZoneInfoPath.empty()) {
+ std::unique_ptr<timelib_tzdb, TimeZoneDatabase::TimeZoneDBDeleter> timeZoneDatabase(
+ timelib_zoneinfo(const_cast<char*>(serverGlobalParams.timeZoneInfoPath.c_str())),
+ TimeZoneDatabase::TimeZoneDBDeleter());
+ if (!timeZoneDatabase) {
+ uasserted(ErrorCodes::FailedToParse,
+ str::stream() << "failed to load time zone database from path \""
+ << serverGlobalParams.timeZoneInfoPath
+ << "\"");
+ }
+ TimeZoneDatabase::set(service,
+ stdx::make_unique<TimeZoneDatabase>(std::move(timeZoneDatabase)));
+ } else {
+ // No 'zoneInfo' specified on the command line, fall back to the built-in rules.
+ TimeZoneDatabase::set(service, stdx::make_unique<TimeZoneDatabase>());
}
- TimeZoneDatabase::set(serviceContext,
- stdx::make_unique<TimeZoneDatabase>(std::move(timeZoneDatabase)));
- } else {
- // No 'zoneInfo' specified on the command line, fall back to the built-in rules.
- TimeZoneDatabase::set(serviceContext, stdx::make_unique<TimeZoneDatabase>());
- }
- return Status::OK();
-}
-
+ }};
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index e413e6d8323..06c1d23ee06 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -884,6 +884,7 @@ env.CppUnitTest(
'repl_coordinator_impl',
'replmocks',
'$BUILD_DIR/mongo/db/auth/authmocks',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -1027,6 +1028,7 @@ env.CppUnitTest('isself_test',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/serveronly',
'$BUILD_DIR/mongo/db/service_context_d',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'isself',
],
)
@@ -1218,6 +1220,7 @@ env.Library(
],
LIBDEPS=[
'replmocks',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
'$BUILD_DIR/mongo/util/concurrency/thread_pool',
],
@@ -1299,6 +1302,7 @@ env.CppUnitTest(
'oplog_entry',
'replmocks',
'$BUILD_DIR/mongo/db/auth/authmocks',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
'$BUILD_DIR/mongo/unittest/task_executor_proxy',
],
@@ -1382,6 +1386,7 @@ env.CppUnitTest(
LIBDEPS=[
'multiapplier',
'$BUILD_DIR/mongo/db/auth/authmocks',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
'$BUILD_DIR/mongo/unittest/task_executor_proxy',
],
@@ -1464,6 +1469,7 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/commands/feature_compatibility_parsers',
'$BUILD_DIR/mongo/db/query/command_request_response',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
'$BUILD_DIR/mongo/unittest/concurrency',
'base_cloner_test_fixture',
diff --git a/src/mongo/db/repl/base_cloner_test_fixture.h b/src/mongo/db/repl/base_cloner_test_fixture.h
index 7e6900a2785..bb266948a08 100644
--- a/src/mongo/db/repl/base_cloner_test_fixture.h
+++ b/src/mongo/db/repl/base_cloner_test_fixture.h
@@ -37,6 +37,7 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/repl/collection_cloner.h"
#include "mongo/db/repl/storage_interface_mock.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
#include "mongo/stdx/condition_variable.h"
@@ -53,7 +54,8 @@ namespace repl {
class BaseCloner;
-class BaseClonerTest : public executor::ThreadPoolExecutorTest {
+class BaseClonerTest : public executor::ThreadPoolExecutorTest,
+ public ScopedGlobalServiceContextForTest {
public:
typedef executor::NetworkInterfaceMock::NetworkOperationIterator NetworkOperationIterator;
diff --git a/src/mongo/db/repl/databases_cloner_test.cpp b/src/mongo/db/repl/databases_cloner_test.cpp
index b6e9f97431e..f32c83c756a 100644
--- a/src/mongo/db/repl/databases_cloner_test.cpp
+++ b/src/mongo/db/repl/databases_cloner_test.cpp
@@ -38,6 +38,7 @@
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/repl/storage_interface.h"
#include "mongo/db/repl/storage_interface_mock.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
#include "mongo/stdx/mutex.h"
@@ -77,7 +78,8 @@ struct StorageInterfaceResults {
};
-class DBsClonerTest : public executor::ThreadPoolExecutorTest {
+class DBsClonerTest : public executor::ThreadPoolExecutorTest,
+ public ScopedGlobalServiceContextForTest {
public:
DBsClonerTest() : _storageInterface{}, _dbWorkThreadPool(ThreadPool::Options()) {}
diff --git a/src/mongo/db/repl/initial_syncer_test.cpp b/src/mongo/db/repl/initial_syncer_test.cpp
index 0f0f95e9fa1..2948a08ff01 100644
--- a/src/mongo/db/repl/initial_syncer_test.cpp
+++ b/src/mongo/db/repl/initial_syncer_test.cpp
@@ -56,6 +56,7 @@
#include "mongo/db/repl/sync_source_selector_mock.h"
#include "mongo/db/repl/task_executor_mock.h"
#include "mongo/db/repl/update_position_args.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
#include "mongo/stdx/mutex.h"
@@ -112,7 +113,9 @@ struct CollectionCloneInfo {
Status status{ErrorCodes::NotYetInitialized, ""};
};
-class InitialSyncerTest : public executor::ThreadPoolExecutorTest, public SyncSourceSelector {
+class InitialSyncerTest : public executor::ThreadPoolExecutorTest,
+ public SyncSourceSelector,
+ public ScopedGlobalServiceContextForTest {
public:
InitialSyncerTest() {}
@@ -419,6 +422,7 @@ protected:
_dbWorkThreadPool.reset();
_replicationProcess.reset();
_storageInterface.reset();
+ Client::destroy();
}
/**
diff --git a/src/mongo/db/repl/isself_test.cpp b/src/mongo/db/repl/isself_test.cpp
index 55a13c675d7..2fa60b5ae4c 100644
--- a/src/mongo/db/repl/isself_test.cpp
+++ b/src/mongo/db/repl/isself_test.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/repl/isself.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/net/socket_utils.h"
@@ -43,7 +44,7 @@ namespace {
using std::string;
-TEST(IsSelf, DetectsSameHostIPv4) {
+TEST_F(ServiceContextTest, DetectsSameHostIPv4) {
#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__)
bool wasEnabled = IPv6Enabled();
enableIPv6(false);
@@ -60,7 +61,7 @@ TEST(IsSelf, DetectsSameHostIPv4) {
#endif
}
-TEST(IsSelf, DetectsSameHostIPv6) {
+TEST_F(ServiceContextTest, DetectsSameHostIPv6) {
#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__)
bool wasEnabled = IPv6Enabled();
enableIPv6(true);
diff --git a/src/mongo/db/repl/multiapplier_test.cpp b/src/mongo/db/repl/multiapplier_test.cpp
index 52ba1fd23d2..cde8f7c0c60 100644
--- a/src/mongo/db/repl/multiapplier_test.cpp
+++ b/src/mongo/db/repl/multiapplier_test.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/client.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/repl/multiapplier.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
#include "mongo/unittest/unittest.h"
@@ -40,7 +41,8 @@ namespace {
using namespace mongo;
using namespace mongo::repl;
-class MultiApplierTest : public executor::ThreadPoolExecutorTest {
+class MultiApplierTest : public executor::ThreadPoolExecutorTest,
+ ScopedGlobalServiceContextForTest {
public:
private:
executor::ThreadPoolMock::Options makeThreadPoolMockOptions() const override;
diff --git a/src/mongo/db/repl/repl_set_config_checks_test.cpp b/src/mongo/db/repl/repl_set_config_checks_test.cpp
index 3dce745a2fa..5cbc1909347 100644
--- a/src/mongo/db/repl/repl_set_config_checks_test.cpp
+++ b/src/mongo/db/repl/repl_set_config_checks_test.cpp
@@ -36,13 +36,14 @@
#include "mongo/db/repl/replication_coordinator_external_state_mock.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
namespace repl {
namespace {
-TEST(ValidateConfigForInitiate, VersionMustBe1) {
+TEST_F(ServiceContextTest, ValidateConfigForInitiate_VersionMustBe1) {
ReplicationCoordinatorExternalStateMock rses;
rses.addSelf(HostAndPort("h1"));
@@ -60,7 +61,7 @@ TEST(ValidateConfigForInitiate, VersionMustBe1) {
validateConfigForInitiate(&rses, config, getGlobalServiceContext()).getStatus());
}
-TEST(ValidateConfigForInitiate, MustFindSelf) {
+TEST_F(ServiceContextTest, ValidateConfigForInitiate_MustFindSelf) {
ReplSetConfig config;
ASSERT_OK(config.initializeForInitiate(BSON("_id"
<< "rs0"
@@ -95,7 +96,7 @@ TEST(ValidateConfigForInitiate, MustFindSelf) {
&presentOnceExternalState, config, getGlobalServiceContext())));
}
-TEST(ValidateConfigForInitiate, SelfMustBeElectable) {
+TEST_F(ServiceContextTest, ValidateConfigForInitiate_SelfMustBeElectable) {
ReplSetConfig config;
ASSERT_OK(config.initializeForInitiate(BSON("_id"
<< "rs0"
@@ -121,7 +122,7 @@ TEST(ValidateConfigForInitiate, SelfMustBeElectable) {
.getStatus());
}
-TEST(ValidateConfigForInitiate, WriteConcernMustBeSatisfiable) {
+TEST_F(ServiceContextTest, ValidateConfigForInitiate_WriteConcernMustBeSatisfiable) {
ReplSetConfig config;
ASSERT_OK(
config.initializeForInitiate(BSON("_id"
@@ -144,7 +145,7 @@ TEST(ValidateConfigForInitiate, WriteConcernMustBeSatisfiable) {
.getStatus());
}
-TEST(ValidateConfigForInitiate, ArbiterPriorityMustBeZeroOrOne) {
+TEST_F(ServiceContextTest, ValidateConfigForInitiate_ArbiterPriorityMustBeZeroOrOne) {
ReplSetConfig zeroConfig;
ReplSetConfig oneConfig;
ReplSetConfig twoConfig;
@@ -216,7 +217,7 @@ TEST(ValidateConfigForInitiate, ArbiterPriorityMustBeZeroOrOne) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigVersionNumberMustBeHigherThanOld) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigVersionNumberMustBeHigherThanOld) {
ReplicationCoordinatorExternalStateMock externalState;
externalState.addSelf(HostAndPort("h1"));
@@ -284,7 +285,7 @@ TEST(ValidateConfigForReconfig, NewConfigVersionNumberMustBeHigherThanOld) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigMustNotChangeSetName) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigMustNotChangeSetName) {
ReplicationCoordinatorExternalStateMock externalState;
externalState.addSelf(HostAndPort("h1"));
@@ -333,7 +334,7 @@ TEST(ValidateConfigForReconfig, NewConfigMustNotChangeSetName) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigMustNotChangeSetId) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigMustNotChangeSetId) {
ReplicationCoordinatorExternalStateMock externalState;
externalState.addSelf(HostAndPort("h1"));
@@ -388,7 +389,7 @@ TEST(ValidateConfigForReconfig, NewConfigMustNotChangeSetId) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigMustNotFlipBuildIndexesFlag) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigMustNotFlipBuildIndexesFlag) {
ReplicationCoordinatorExternalStateMock externalState;
externalState.addSelf(HostAndPort("h1"));
@@ -470,7 +471,7 @@ TEST(ValidateConfigForReconfig, NewConfigMustNotFlipBuildIndexesFlag) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigMustNotFlipArbiterFlag) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigMustNotFlipArbiterFlag) {
ReplicationCoordinatorExternalStateMock externalState;
externalState.addSelf(HostAndPort("h1"));
@@ -545,7 +546,7 @@ TEST(ValidateConfigForReconfig, NewConfigMustNotFlipArbiterFlag) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, HostAndIdRemappingRestricted) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_HostAndIdRemappingRestricted) {
// When reconfiguring a replica set, it is allowed to introduce (host, id) pairs
// absent from the old config only when the hosts and ids were both individually
// absent in the old config.
@@ -654,7 +655,7 @@ TEST(ValidateConfigForReconfig, HostAndIdRemappingRestricted) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, MustFindSelf) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_MustFindSelf) {
// Old and new config are same except for version change; this is just testing that we can
// find ourself in the new config.
ReplSetConfig oldConfig;
@@ -725,7 +726,7 @@ TEST(ValidateConfigForReconfig, MustFindSelf) {
&presentOnceExternalState, oldConfig, newConfig, getGlobalServiceContext(), true)));
}
-TEST(ValidateConfigForReconfig, ArbiterPriorityValueMustBeZeroOrOne) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_ArbiterPriorityValueMustBeZeroOrOne) {
ReplicationCoordinatorExternalStateMock externalState;
externalState.addSelf(HostAndPort("h1"));
@@ -823,7 +824,7 @@ TEST(ValidateConfigForReconfig, ArbiterPriorityValueMustBeZeroOrOne) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, SelfMustEndElectable) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_SelfMustEndElectable) {
// Old and new config are same except for version change and the electability of one node;
// this is just testing that we must be electable in the new config.
ReplSetConfig oldConfig;
@@ -871,7 +872,7 @@ TEST(ValidateConfigForReconfig, SelfMustEndElectable) {
.getStatus());
}
-TEST(ValidateConfigForInitiate, NewConfigInvalid) {
+TEST_F(ServiceContextTest, ValidateConfigForInitiate_NewConfigInvalid) {
// The new config is not valid due to a duplicate _id value. This tests that if the new
// config is invalid, validateConfigForInitiate will return a status indicating what is
// wrong with the new config.
@@ -896,7 +897,7 @@ TEST(ValidateConfigForInitiate, NewConfigInvalid) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigInvalid) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigInvalid) {
// The new config is not valid due to a duplicate _id value. This tests that if the new
// config is invalid, validateConfigForReconfig will return a status indicating what is
// wrong with the new config.
@@ -939,7 +940,7 @@ TEST(ValidateConfigForReconfig, NewConfigInvalid) {
.getStatus());
}
-TEST(ValidateConfigForReconfig, NewConfigWriteConcernNotSatisifiable) {
+TEST_F(ServiceContextTest, ValidateConfigForReconfig_NewConfigWriteConcernNotSatisifiable) {
// The new config is not valid due to an unsatisfiable write concern. This tests that if the
// new config is invalid, validateConfigForReconfig will return a status indicating what is
// wrong with the new config.
@@ -982,7 +983,7 @@ TEST(ValidateConfigForReconfig, NewConfigWriteConcernNotSatisifiable) {
.getStatus());
}
-TEST(ValidateConfigForStartUp, NewConfigInvalid) {
+TEST_F(ServiceContextTest, ValidateConfigForStartUp_NewConfigInvalid) {
// The new config is not valid due to a duplicate _id value. This tests that if the new
// config is invalid, validateConfigForStartUp will return a status indicating what is wrong
// with the new config.
@@ -1007,7 +1008,7 @@ TEST(ValidateConfigForStartUp, NewConfigInvalid) {
.getStatus());
}
-TEST(ValidateConfigForStartUp, NewConfigValid) {
+TEST_F(ServiceContextTest, ValidateConfigForStartUp_NewConfigValid) {
// The new config is valid. This tests that validateConfigForStartUp will return a
// Status::OK() indicating the validity of this configuration.
ReplSetConfig newConfig;
@@ -1032,7 +1033,7 @@ TEST(ValidateConfigForStartUp, NewConfigValid) {
.getStatus());
}
-TEST(ValidateConfigForStartUp, NewConfigWriteConcernNotSatisfiable) {
+TEST_F(ServiceContextTest, ValidateConfigForStartUp_NewConfigWriteConcernNotSatisfiable) {
// The new config contains an unsatisfiable write concern. We don't allow these configs to be
// created anymore, but we allow any which exist to pass and the database to start up to
// maintain backwards compatibility.
@@ -1056,7 +1057,7 @@ TEST(ValidateConfigForStartUp, NewConfigWriteConcernNotSatisfiable) {
.getStatus());
}
-TEST(ValidateConfigForHeartbeatReconfig, NewConfigInvalid) {
+TEST_F(ServiceContextTest, ValidateConfigForHeartbeatReconfig_NewConfigInvalid) {
// The new config is not valid due to a duplicate _id value. This tests that if the new
// config is invalid, validateConfigForHeartbeatReconfig will return a status indicating
// what is wrong with the new config.
@@ -1081,7 +1082,7 @@ TEST(ValidateConfigForHeartbeatReconfig, NewConfigInvalid) {
.getStatus());
}
-TEST(ValidateConfigForHeartbeatReconfig, NewConfigValid) {
+TEST_F(ServiceContextTest, ValidateConfigForHeartbeatReconfig_NewConfigValid) {
// The new config is valid. This tests that validateConfigForHeartbeatReconfig will return
// a Status::OK() indicating the validity of this config change.
ReplSetConfig newConfig;
@@ -1104,7 +1105,7 @@ TEST(ValidateConfigForHeartbeatReconfig, NewConfigValid) {
.getStatus());
}
-TEST(ValidateConfigForHeartbeatReconfig, NewConfigWriteConcernNotSatisfiable) {
+TEST_F(ServiceContextTest, ValidateConfigForHeartbeatReconfig_NewConfigWriteConcernNotSatisfiable) {
// The new config contains an unsatisfiable write concern. We don't allow these configs to be
// created anymore, but we allow any which exist to be received in a heartbeat.
ReplSetConfig newConfig;
@@ -1129,7 +1130,7 @@ TEST(ValidateConfigForHeartbeatReconfig, NewConfigWriteConcernNotSatisfiable) {
.getStatus());
}
-TEST(ValidateForReconfig, ForceStillNeedsValidConfig) {
+TEST_F(ServiceContextTest, ValidateForReconfig_ForceStillNeedsValidConfig) {
// The new config is invalid due to two nodes with the same _id value. This tests that
// ValidateForReconfig fails with an invalid config, even if force is true.
ReplSetConfig oldConfig;
@@ -1168,7 +1169,7 @@ TEST(ValidateForReconfig, ForceStillNeedsValidConfig) {
.getStatus());
}
-TEST(ValidateForReconfig, ForceStillNeedsSelfPresent) {
+TEST_F(ServiceContextTest, ValidateForReconfig_ForceStillNeedsSelfPresent) {
// The new config does not contain self. This tests that ValidateForReconfig fails
// if the member receiving it is absent from the config, even if force is true.
ReplSetConfig oldConfig;
diff --git a/src/mongo/db/service_context.cpp b/src/mongo/db/service_context.cpp
index bac2809f798..038cb0a67c4 100644
--- a/src/mongo/db/service_context.cpp
+++ b/src/mongo/db/service_context.cpp
@@ -349,22 +349,6 @@ void ServiceContext::notifyStartupComplete() {
namespace {
-// clang-format off
-GlobalInitializerRegisterer registerCreateServiceContext{
- "ServiceContext",
- {"default"},
- [](InitializerContext* context) {
- setGlobalServiceContext(ServiceContext::make());
- return Status::OK();
- },
- [](DeinitializerContext* context) {
- // For now, deregistration is done manually after all deinitializers run, in case any
- // erroneously access the globalServiceContext without expressing a dependency.
- return Status::OK();
- }
-};
-// clang-format on
-
/**
* Accessor function to get the global list of ServiceContext constructor and destructor
* functions.
@@ -390,7 +374,6 @@ ServiceContext::ConstructorActionRegisterer::ConstructorActionRegisterer(
destructor = [](ServiceContext*) {};
_registerer.emplace(std::move(name),
std::move(prereqs),
- std::vector<std::string>{"ServiceContext"},
[this, constructor, destructor](InitializerContext* context) {
_iter = registeredConstructorActions().emplace(
registeredConstructorActions().end(),
diff --git a/src/mongo/db/service_context_test_fixture.cpp b/src/mongo/db/service_context_test_fixture.cpp
index 486478f56e6..e9aba482801 100644
--- a/src/mongo/db/service_context_test_fixture.cpp
+++ b/src/mongo/db/service_context_test_fixture.cpp
@@ -38,23 +38,29 @@
namespace mongo {
-ServiceContextTest::ServiceContextTest() {
+ScopedGlobalServiceContextForTest::ScopedGlobalServiceContextForTest() {
setGlobalServiceContext(ServiceContext::make());
auto const serviceContext = getGlobalServiceContext();
- Client::initThread(getThreadName());
auto observerRegistry = std::make_unique<OpObserverRegistry>();
serviceContext->setOpObserver(std::move(observerRegistry));
}
-ServiceContextTest::~ServiceContextTest() {
- Client::destroy();
+ScopedGlobalServiceContextForTest::~ScopedGlobalServiceContextForTest() {
setGlobalServiceContext({});
}
-ServiceContext* ServiceContextTest::getServiceContext() {
+ServiceContext* ScopedGlobalServiceContextForTest::getServiceContext() {
return getGlobalServiceContext();
}
+ServiceContextTest::ServiceContextTest() {
+ Client::initThread(getThreadName());
+}
+
+ServiceContextTest::~ServiceContextTest() {
+ Client::destroy();
+}
+
Client* ServiceContextTest::getClient() {
return Client::getCurrent();
}
diff --git a/src/mongo/db/service_context_test_fixture.h b/src/mongo/db/service_context_test_fixture.h
index 1e23c6666d2..8588b1e18e5 100644
--- a/src/mongo/db/service_context_test_fixture.h
+++ b/src/mongo/db/service_context_test_fixture.h
@@ -34,17 +34,25 @@
namespace mongo {
-/**
- * Test fixture for tests that require a properly initialized global service context.
- */
-class ServiceContextTest : public unittest::Test {
+
+class ScopedGlobalServiceContextForTest {
public:
/**
- * Returns a service context, which is only valid for this instance of the test.
- * Must not be called before setUp or after tearDown.
- */
+ * Returns a service context, which is only valid for this instance of the test.
+ * Must not be called before setUp or after tearDown.
+ */
ServiceContext* getServiceContext();
+protected:
+ ScopedGlobalServiceContextForTest();
+ virtual ~ScopedGlobalServiceContextForTest();
+};
+
+/**
+ * Test fixture for tests that require a properly initialized global service context.
+ */
+class ServiceContextTest : public unittest::Test, public ScopedGlobalServiceContextForTest {
+public:
/**
* Returns the default Client for this test.
*/
diff --git a/src/mongo/db/sorter/SConscript b/src/mongo/db/sorter/SConscript
index 0757cd5097d..7b5dd0bdd6e 100644
--- a/src/mongo/db/sorter/SConscript
+++ b/src/mongo/db/sorter/SConscript
@@ -7,6 +7,7 @@ sorterEnv.InjectThirdPartyIncludePaths(libraries=['snappy'])
sorterEnv.CppUnitTest('sorter_test',
'sorter_test.cpp',
LIBDEPS=['$BUILD_DIR/mongo/db/service_context',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/db/storage/encryption_hooks',
'$BUILD_DIR/mongo/db/storage/storage_options',
'$BUILD_DIR/mongo/s/is_mongos',
diff --git a/src/mongo/db/sorter/sorter_test.cpp b/src/mongo/db/sorter/sorter_test.cpp
index 3d9fc03b58f..d55bab970f4 100644
--- a/src/mongo/db/sorter/sorter_test.cpp
+++ b/src/mongo/db/sorter/sorter_test.cpp
@@ -36,6 +36,7 @@
#include "mongo/base/init.h"
#include "mongo/base/static_assert.h"
#include "mongo/config.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/platform/random.h"
#include "mongo/stdx/thread.h"
#include "mongo/unittest/temp_dir.h"
@@ -239,7 +240,7 @@ public:
}
};
-class SortedFileWriterAndFileIteratorTests {
+class SortedFileWriterAndFileIteratorTests : public ScopedGlobalServiceContextForTest {
public:
void run() {
unittest::TempDir tempDir("sortedFileWriterTests");
@@ -325,7 +326,7 @@ public:
};
namespace SorterTests {
-class Basic {
+class Basic : public ScopedGlobalServiceContextForTest {
public:
virtual ~Basic() {}
diff --git a/src/mongo/db/storage/kv/SConscript b/src/mongo/db/storage/kv/SConscript
index 7edb39d2366..384738813c0 100644
--- a/src/mongo/db/storage/kv/SConscript
+++ b/src/mongo/db/storage/kv/SConscript
@@ -114,6 +114,7 @@ env.CppUnitTest(
'kv_engine_mock',
'$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/db/namespace_string',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/db/storage/devnull/storage_devnull_core',
'$BUILD_DIR/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store',
],
@@ -131,6 +132,7 @@ env.CppUnitTest(
'kv_engine_mock',
'$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/db/namespace_string',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/db/storage/devnull/storage_devnull_core',
'$BUILD_DIR/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store',
],
diff --git a/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp b/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp
index d2e4a77f7e9..b27937839b3 100644
--- a/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp
+++ b/src/mongo/db/storage/kv/kv_collection_catalog_entry_test.cpp
@@ -37,6 +37,7 @@
#include "mongo/db/index/multikey_paths.h"
#include "mongo/db/index_names.h"
#include "mongo/db/operation_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/storage/devnull/devnull_kv_engine.h"
#include "mongo/db/storage/kv/kv_database_catalog_entry_mock.h"
#include "mongo/db/storage/kv/kv_engine.h"
@@ -48,7 +49,7 @@
namespace mongo {
namespace {
-class KVCollectionCatalogEntryTest : public unittest::Test {
+class KVCollectionCatalogEntryTest : public ServiceContextTest {
public:
KVCollectionCatalogEntryTest()
: _nss("unittests.kv_collection_catalog_entry"),
diff --git a/src/mongo/db/storage/kv/kv_database_catalog_entry_test.cpp b/src/mongo/db/storage/kv/kv_database_catalog_entry_test.cpp
index 0e122cf5603..353ce9f407f 100644
--- a/src/mongo/db/storage/kv/kv_database_catalog_entry_test.cpp
+++ b/src/mongo/db/storage/kv/kv_database_catalog_entry_test.cpp
@@ -33,6 +33,7 @@
#include "mongo/base/string_data.h"
#include "mongo/db/catalog/collection_options.h"
#include "mongo/db/operation_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/storage/devnull/devnull_kv_engine.h"
#include "mongo/db/storage/kv/kv_prefix.h"
#include "mongo/db/storage/kv/kv_storage_engine.h"
@@ -42,7 +43,7 @@
namespace mongo {
namespace {
-TEST(KVDatabaseCatalogEntryTest, CreateCollectionValidNamespace) {
+TEST_F(ServiceContextTest, CreateCollectionValidNamespace) {
KVStorageEngine storageEngine(
new DevNullKVEngine(), KVStorageEngineOptions{}, kvDatabaseCatalogEntryMockFactory);
storageEngine.finishInit();
@@ -54,7 +55,7 @@ TEST(KVDatabaseCatalogEntryTest, CreateCollectionValidNamespace) {
ASSERT_FALSE(collectionNamespaces.empty());
}
-TEST(KVDatabaseCatalogEntryTest, CreateCollectionEmptyNamespace) {
+TEST_F(ServiceContextTest, CreateCollectionEmptyNamespace) {
KVStorageEngine storageEngine(
new DevNullKVEngine(), KVStorageEngineOptions{}, kvDatabaseCatalogEntryMockFactory);
storageEngine.finishInit();
@@ -84,7 +85,7 @@ public:
};
// After createCollection fails, collection namespaces should remain empty.
-TEST(KVDatabaseCatalogEntryTest, CreateCollectionInvalidRecordStore) {
+TEST_F(ServiceContextTest, CreateCollectionInvalidRecordStore) {
KVStorageEngine storageEngine(new InvalidRecordStoreKVEngine(),
KVStorageEngineOptions{},
kvDatabaseCatalogEntryMockFactory);
diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript
index 9d42061472d..72fb04cbcd3 100644
--- a/src/mongo/db/storage/wiredtiger/SConscript
+++ b/src/mongo/db/storage/wiredtiger/SConscript
@@ -128,6 +128,7 @@ if wiredtiger:
'$BUILD_DIR/mongo/db/serveronly',
'$BUILD_DIR/mongo/db/service_context',
'$BUILD_DIR/mongo/db/service_context_d',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/db/storage/storage_engine_metadata',
'$BUILD_DIR/mongo/db/storage/storage_options',
'$BUILD_DIR/mongo/db/storage/wiredtiger/storage_wiredtiger_core',
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_init_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_init_test.cpp
index 164d52013dd..0815bcf0bc8 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_init_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_init_test.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/json.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/storage/storage_engine_init.h"
#include "mongo/db/storage/storage_engine_metadata.h"
#include "mongo/db/storage/storage_options.h"
@@ -43,7 +44,7 @@ namespace {
using namespace mongo;
-class WiredTigerFactoryTest : public mongo::unittest::Test {
+class WiredTigerFactoryTest : public ServiceContextTest {
private:
virtual void setUp() {
ServiceContext* globalEnv = getGlobalServiceContext();
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
index 2832d72bbf2..77906f1b222 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
@@ -47,6 +47,8 @@ namespace {
class WiredTigerKVHarnessHelper : public KVHarnessHelper {
public:
WiredTigerKVHarnessHelper() : _dbpath("wt-kv-harness") {
+ if (!hasGlobalServiceContext())
+ setGlobalServiceContext(ServiceContext::make());
_engine.reset(new WiredTigerKVEngine(
kWiredTigerEngineName, _dbpath.path(), _cs.get(), "", 1, false, false, false, false));
repl::ReplicationCoordinator::set(
@@ -57,6 +59,7 @@ public:
virtual ~WiredTigerKVHarnessHelper() {
_engine.reset(NULL);
+ // Cannot cleanup the global service context here, the test still have clients remaining.
}
virtual KVEngine* restartEngine() {
diff --git a/src/mongo/db/update/SConscript b/src/mongo/db/update/SConscript
index 405f3a5bb9c..ad97577a94a 100644
--- a/src/mongo/db/update/SConscript
+++ b/src/mongo/db/update/SConscript
@@ -117,6 +117,7 @@ env.CppUnitTest(
],
LIBDEPS=[
'$BUILD_DIR/mongo/bson/mutable/mutable_bson_test_utils',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/db/logical_clock',
'$BUILD_DIR/mongo/db/query/collation/collator_interface_mock',
'$BUILD_DIR/mongo/db/query/query_test_service_context',
diff --git a/src/mongo/db/update/update_node_test_fixture.h b/src/mongo/db/update/update_node_test_fixture.h
index 050c9444e75..6da205a2cb8 100644
--- a/src/mongo/db/update/update_node_test_fixture.h
+++ b/src/mongo/db/update/update_node_test_fixture.h
@@ -30,12 +30,13 @@
#include "mongo/db/logical_clock.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/update/update_node.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
-class UpdateNodeTest : public mongo::unittest::Test {
+class UpdateNodeTest : public ServiceContextTest {
public:
~UpdateNodeTest() override = default;
diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp
index 07a4b4fe915..33aee8da3ab 100644
--- a/src/mongo/dbtests/dbtests.cpp
+++ b/src/mongo/dbtests/dbtests.cpp
@@ -168,6 +168,7 @@ int dbtestsMain(int argc, char** argv, char** envp) {
ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo42);
repl::ReplSettings replSettings;
replSettings.setOplogSizeBytes(10 * 1024 * 1024);
+ setGlobalServiceContext(ServiceContext::make());
ServiceContext* service = getGlobalServiceContext();
service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service));
diff --git a/src/mongo/embedded/embedded.cpp b/src/mongo/embedded/embedded.cpp
index aa4b4133c5e..00b67e1c264 100644
--- a/src/mongo/embedded/embedded.cpp
+++ b/src/mongo/embedded/embedded.cpp
@@ -169,6 +169,7 @@ ServiceContext* initialize(const char* yaml_config) {
Status status = mongo::runGlobalInitializers(yaml_config ? 1 : 0, argv, nullptr);
uassertStatusOKWithContext(status, "Global initilization failed");
+ setGlobalServiceContext(ServiceContext::make());
Client::initThread("initandlisten");
diff --git a/src/mongo/executor/task_executor_test_common.cpp b/src/mongo/executor/task_executor_test_common.cpp
index 1d04675ae03..b2cd5a166cb 100644
--- a/src/mongo/executor/task_executor_test_common.cpp
+++ b/src/mongo/executor/task_executor_test_common.cpp
@@ -342,7 +342,7 @@ COMMON_EXECUTOR_TEST(EventWaitingWithTimeoutTest) {
auto eventThatWillNeverBeTriggered = unittest::assertGet(executor.makeEvent());
- auto serviceContext = getGlobalServiceContext();
+ auto serviceContext = ServiceContext::make();
serviceContext->setFastClockSource(stdx::make_unique<ClockSourceMock>());
auto mockClock = static_cast<ClockSourceMock*>(serviceContext->getFastClockSource());
@@ -364,7 +364,7 @@ COMMON_EXECUTOR_TEST(EventSignalWithTimeoutTest) {
auto eventSignalled = unittest::assertGet(executor.makeEvent());
- auto serviceContext = getGlobalServiceContext();
+ auto serviceContext = ServiceContext::make();
serviceContext->setFastClockSource(stdx::make_unique<ClockSourceMock>());
auto mockClock = static_cast<ClockSourceMock*>(serviceContext->getFastClockSource());
diff --git a/src/mongo/executor/task_executor_test_fixture.cpp b/src/mongo/executor/task_executor_test_fixture.cpp
index f58657bacbb..d534377b643 100644
--- a/src/mongo/executor/task_executor_test_fixture.cpp
+++ b/src/mongo/executor/task_executor_test_fixture.cpp
@@ -65,6 +65,11 @@ void TaskExecutorTest::setUp() {
_executor = makeTaskExecutor(std::move(net));
}
+void TaskExecutorTest::tearDown() {
+ _executor.reset(nullptr);
+ _net = nullptr;
+}
+
void TaskExecutorTest::launchExecutorThread() {
_executor->startup();
postExecutorThreadLaunch();
diff --git a/src/mongo/executor/task_executor_test_fixture.h b/src/mongo/executor/task_executor_test_fixture.h
index ff9904125d4..b99f90cb3af 100644
--- a/src/mongo/executor/task_executor_test_fixture.h
+++ b/src/mongo/executor/task_executor_test_fixture.h
@@ -72,6 +72,7 @@ public:
* Initializes both the NetworkInterfaceMock and TaskExecutor but does not start the executor.
*/
void setUp() override;
+ void tearDown() override;
void launchExecutorThread();
void shutdownExecutorThread();
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index e460e41ad1a..4bb567eaf36 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -466,6 +466,7 @@ env.CppUnitTest(
'client/shard_connection_test.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/dbtests/mocklib',
'$BUILD_DIR/mongo/util/net/network',
'client/sharding_connection_hook',
diff --git a/src/mongo/s/client/shard_connection_test.cpp b/src/mongo/s/client/shard_connection_test.cpp
index 927c4f1aeae..fd3d9dd9a14 100644
--- a/src/mongo/s/client/shard_connection_test.cpp
+++ b/src/mongo/s/client/shard_connection_test.cpp
@@ -30,6 +30,7 @@
#include <vector>
#include "mongo/db/client.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/dbtests/mock/mock_conn_registry.h"
#include "mongo/dbtests/mock/mock_dbclient_connection.h"
#include "mongo/s/client/shard_connection.h"
@@ -47,7 +48,7 @@ namespace {
const std::string TARGET_HOST = "$dummy:27017";
-class ShardConnFixture : public unittest::Test {
+class ShardConnFixture : public ServiceContextTest {
public:
void setUp() {
Client::initThreadIfNotAlready("ShardConnFixture");
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index d5d38e1cc34..0dc64211d36 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -559,7 +559,6 @@ ExitCode mongoSMain(int argc, char* argv[], char** envp) {
if (argc < 1)
return EXIT_BADOPTIONS;
- registerShutdownTask([&]() { cleanupTask(getGlobalServiceContext()); });
setupSignalHandlers();
@@ -569,6 +568,16 @@ ExitCode mongoSMain(int argc, char* argv[], char** envp) {
return EXIT_ABRUPT;
}
+ try {
+ setGlobalServiceContext(ServiceContext::make());
+ } catch (...) {
+ auto cause = exceptionToStatus();
+ severe(LogComponent::kDefault) << "Failed to create service context: " << redact(cause);
+ return EXIT_ABRUPT;
+ }
+
+ registerShutdownTask([&]() { cleanupTask(getGlobalServiceContext()); });
+
ErrorExtraInfo::invariantHaveAllParsers();
startupConfigActions(std::vector<std::string>(argv, argv + argc));
diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp
index c1d37dd0129..bf0a1d3a9db 100644
--- a/src/mongo/shell/dbshell.cpp
+++ b/src/mongo/shell/dbshell.cpp
@@ -743,7 +743,7 @@ int _main(int argc, char* argv[], char** envp) {
mongo::shell_utils::RecordMyLocation(argv[0]);
mongo::runGlobalInitializersOrDie(argc, argv, envp);
-
+ setGlobalServiceContext(ServiceContext::make());
// TODO This should use a TransportLayerManager or TransportLayerFactory
auto serviceContext = getGlobalServiceContext();
transport::TransportLayerASIO::Options opts;
diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp
index 26086ee29d1..01093145986 100644
--- a/src/mongo/tools/bridge.cpp
+++ b/src/mongo/tools/bridge.cpp
@@ -413,6 +413,7 @@ int bridgeMain(int argc, char** argv, char** envp) {
runGlobalInitializersOrDie(argc, argv, envp);
startSignalProcessingThread(LogFileStatus::kNoLogFileToRotate);
+ setGlobalServiceContext(ServiceContext::make());
auto serviceContext = getGlobalServiceContext();
serviceContext->setServiceEntryPoint(std::make_unique<ServiceEntryPointBridge>(serviceContext));
serviceContext->setServiceExecutor(
diff --git a/src/mongo/unittest/SConscript b/src/mongo/unittest/SConscript
index e3593d9ff8b..1193b6d2b07 100644
--- a/src/mongo/unittest/SConscript
+++ b/src/mongo/unittest/SConscript
@@ -46,6 +46,7 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/client/connection_string',
+ '$BUILD_DIR/mongo/db/service_context',
'$BUILD_DIR/mongo/util/options_parser/options_parser_init',
],
)
@@ -59,6 +60,7 @@ bmEnv.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/service_context',
'$BUILD_DIR/third_party/shim_benchmark',
],
)
diff --git a/src/mongo/unittest/benchmark_main.cpp b/src/mongo/unittest/benchmark_main.cpp
index a29168ad5d5..8029a4005fa 100644
--- a/src/mongo/unittest/benchmark_main.cpp
+++ b/src/mongo/unittest/benchmark_main.cpp
@@ -34,6 +34,7 @@
#include "mongo/base/initializer.h"
#include "mongo/config.h"
+#include "mongo/db/service_context.h"
#include "mongo/util/log.h"
#include "mongo/util/signal_handlers_synchronous.h"
@@ -43,6 +44,7 @@ int main(int argc, char** argv, char** envp) {
::mongo::setupSynchronousSignalHandlers();
::mongo::runGlobalInitializersOrDie(argc, argv, envp);
+ ::mongo::setGlobalServiceContext(::mongo::ServiceContext::make());
// Copied from the BENCHMARK_MAIN macro.
::benchmark::Initialize(&argc, argv);
diff --git a/src/mongo/unittest/integration_test_main.cpp b/src/mongo/unittest/integration_test_main.cpp
index b2e3168bccc..20d2d8e0546 100644
--- a/src/mongo/unittest/integration_test_main.cpp
+++ b/src/mongo/unittest/integration_test_main.cpp
@@ -71,6 +71,7 @@ ConnectionString getFixtureConnectionString() {
int main(int argc, char** argv, char** envp) {
setupSynchronousSignalHandlers();
runGlobalInitializersOrDie(argc, argv, envp);
+ setGlobalServiceContext(ServiceContext::make());
quickExit(unittest::Suite::run(std::vector<std::string>(), "", 1));
}