summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2018-06-22 12:00:21 -0400
committerHenrik Edin <henrik.edin@mongodb.com>2018-09-13 12:11:32 -0400
commit58feaec9c55629ba253b1ff013736eb8b8e9c79d (patch)
tree2465d0dee70d9423e59cf263831cd2fe379e6eb8
parent1465239c3b92ba935cc5ebba57dbdf9256c18c57 (diff)
downloadmongo-58feaec9c55629ba253b1ff013736eb8b8e9c79d.tar.gz
SERVER-34798 Remove ServiceContext subclasses and use new ServiceContext in every unit test.
This patch does several loosely related and surprisingly hard to separate things. 1.) Make the ServiceContext class final 2.) Create a mechanism, called ConstructorActions, for running methods on ServiceContexts immediately after they're built and immediately before they're destroyed. 3.) Introduce / improve test fixture base classes for tests, giving them fresh ServiceContext instances for each test case. There is one fixture for tests that need a storage engine and another for those that do not. 4.) Make several remaining global variables SC decorations in support of (3) 5.) Replace many MONGO_INITIALIZERS that access getGlobalServiceContext with the new constructor-actions system, which is needed for (3.) 6.) Fix up tests to use the fixtures from (3) and fix tests that silently used different service contexts in together in a technically illegal fashion that now breaks. 7.) Utilize (2) as necessary to simplify initialization of new ServiceContexts, simplifying the fixtures in (3). (cherry picked from commit d520be0814492c262515cf0a5d62a127ace70dce) SERVER-35985 Destroy clients started in other threads. (cherry picked from commit 9a68eb0cc65a93233b4ff5746330f9eb77de9b90) SERVER-36258 Construct ServiceContext after mongo initializers complete. (cherry picked from commit bfe170e49b1dc10b2badde45bc13c057a2f8ab61) SERVER-36400 Explicitly destroy the client on exiting run() of each BackgroundJob (cherry picked from commit b079e4713d897b5541c2804386025817ec720800) SERVER-36351 Fix so ServiceContextMongoDTest removes the temp directory in its destructor. (cherry picked from commit 4c16f0f336f4db77034e8aa594bbd4a5bac3f40c) SERVER-36347 Fix parse_zone_info.py after ServiceContext refactor. (cherry picked from commit c9d4204b6243e5eee6fe0b5e2c34d02af9ac5edb)
-rw-r--r--jstests/noPassthrough/parse_zone_info.js5
-rw-r--r--jstests/sharding/time_zone_info_mongos.js4
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/bson/SConscript3
-rw-r--r--src/mongo/client/SConscript5
-rw-r--r--src/mongo/client/mongo_uri_test.cpp65
-rw-r--r--src/mongo/db/SConscript39
-rw-r--r--src/mongo/db/auth/SConscript56
-rw-r--r--src/mongo/db/auth/auth_decorations.cpp12
-rw-r--r--src/mongo/db/auth/authorization_manager_global.cpp17
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp82
-rw-r--r--src/mongo/db/auth/authorization_session_test.cpp8
-rw-r--r--src/mongo/db/auth/sasl_authentication_session_test.cpp14
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry.cpp24
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry.h15
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry_test.cpp13
-rw-r--r--src/mongo/db/auth/sasl_options.cpp6
-rw-r--r--src/mongo/db/auth/sasl_plain_server_conversation.cpp11
-rw-r--r--src/mongo/db/auth/sasl_scram_server_conversation.cpp13
-rw-r--r--src/mongo/db/auth/sasl_scram_test.cpp10
-rw-r--r--src/mongo/db/catalog/database_holder_impl.cpp17
-rw-r--r--src/mongo/db/catalog_raii_test.cpp5
-rw-r--r--src/mongo/db/client.h32
-rw-r--r--src/mongo/db/clientcursor.cpp1
-rw-r--r--src/mongo/db/commands/dbcheck.cpp1
-rw-r--r--src/mongo/db/commands/fsync.cpp1
-rw-r--r--src/mongo/db/commands/index_filter_commands_test.cpp51
-rw-r--r--src/mongo/db/commands_test.cpp35
-rw-r--r--src/mongo/db/concurrency/SConscript4
-rw-r--r--src/mongo/db/concurrency/d_concurrency_test.cpp69
-rw-r--r--src/mongo/db/db.cpp24
-rw-r--r--src/mongo/db/exec/SConscript4
-rw-r--r--src/mongo/db/exec/queued_data_stage_test.cpp25
-rw-r--r--src/mongo/db/exec/sort_test.cpp29
-rw-r--r--src/mongo/db/free_mon/free_mon_controller_test.cpp1
-rw-r--r--src/mongo/db/ftdc/SConscript1
-rw-r--r--src/mongo/db/ftdc/compressor_test.cpp18
-rw-r--r--src/mongo/db/ftdc/controller_test.cpp8
-rw-r--r--src/mongo/db/ftdc/file_manager_test.cpp10
-rw-r--r--src/mongo/db/ftdc/file_writer_test.cpp14
-rw-r--r--src/mongo/db/ftdc/ftdc_test.cpp17
-rw-r--r--src/mongo/db/ftdc/ftdc_test.h6
-rw-r--r--src/mongo/db/index_builder.cpp1
-rw-r--r--src/mongo/db/logical_session_cache_test.cpp48
-rw-r--r--src/mongo/db/logical_session_id_test.cpp41
-rw-r--r--src/mongo/db/operation_context_test.cpp25
-rw-r--r--src/mongo/db/ops/SConscript1
-rw-r--r--src/mongo/db/pipeline/SConscript10
-rw-r--r--src/mongo/db/pipeline/aggregation_context_fixture.h16
-rw-r--r--src/mongo/db/pipeline/document_source_graph_lookup_test.cpp22
-rw-r--r--src/mongo/db/pipeline/document_source_group_test.cpp43
-rw-r--r--src/mongo/db/pipeline/document_source_lookup_test.cpp52
-rw-r--r--src/mongo/db/pipeline/document_source_merge_cursors_test.cpp12
-rw-r--r--src/mongo/db/pipeline/document_source_test.cpp11
-rw-r--r--src/mongo/db/pipeline/expression_context.h8
-rw-r--r--src/mongo/db/query/SConscript4
-rw-r--r--src/mongo/db/query/collation/collator_factory_icu_decoration.cpp13
-rw-r--r--src/mongo/db/query/datetime/init_timezone_data.cpp43
-rw-r--r--src/mongo/db/query/query_request_test.cpp17
-rw-r--r--src/mongo/db/query/query_test_service_context.cpp16
-rw-r--r--src/mongo/db/query/query_test_service_context.h12
-rw-r--r--src/mongo/db/repl/SConscript52
-rw-r--r--src/mongo/db/repl/base_cloner_test_fixture.h4
-rw-r--r--src/mongo/db/repl/collection_bulk_loader_impl.cpp34
-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/repl/replication_coordinator_impl_test.cpp13
-rw-r--r--src/mongo/db/repl/replication_coordinator_test_fixture.cpp7
-rw-r--r--src/mongo/db/repl/replication_coordinator_test_fixture.h29
-rw-r--r--src/mongo/db/repl/rollback_impl_test.cpp2
-rw-r--r--src/mongo/db/repl/rollback_test_fixture.cpp23
-rw-r--r--src/mongo/db/repl/rollback_test_fixture.h14
-rw-r--r--src/mongo/db/repl/rs_rollback_test.cpp17
-rw-r--r--src/mongo/db/repl/service_context_repl_mock.cpp47
-rw-r--r--src/mongo/db/repl/service_context_repl_mock.h46
-rw-r--r--src/mongo/db/repl/task_runner_test_fixture.cpp2
-rw-r--r--src/mongo/db/repl/task_runner_test_fixture.h4
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/active_migrations_registry_test.cpp25
-rw-r--r--src/mongo/db/s/active_move_primaries_registry_test.cpp25
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp26
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp2
-rw-r--r--src/mongo/db/s/namespace_metadata_change_notifications_test.cpp29
-rw-r--r--src/mongo/db/s/sharding_state.cpp3
-rw-r--r--src/mongo/db/service_context.cpp190
-rw-r--r--src/mongo/db/service_context.h168
-rw-r--r--src/mongo/db/service_context_d.cpp87
-rw-r--r--src/mongo/db/service_context_d.h48
-rw-r--r--src/mongo/db/service_context_d_test_fixture.cpp100
-rw-r--r--src/mongo/db/service_context_d_test_fixture.h47
-rw-r--r--src/mongo/db/service_context_noop.cpp42
-rw-r--r--src/mongo/db/service_context_noop.h40
-rw-r--r--src/mongo/db/service_context_noop_init.cpp46
-rw-r--r--src/mongo/db/service_context_registrar.cpp70
-rw-r--r--src/mongo/db/service_context_registrar.h46
-rw-r--r--src/mongo/db/service_context_test_fixture.cpp (renamed from src/mongo/db/repl/service_context_repl_mock_init.cpp)47
-rw-r--r--src/mongo/db/service_context_test_fixture.h (renamed from src/mongo/embedded/service_context_embedded.h)38
-rw-r--r--src/mongo/db/service_liaison_mock.h3
-rw-r--r--src/mongo/db/session_catalog_test.cpp3
-rw-r--r--src/mongo/db/sorter/SConscript1
-rw-r--r--src/mongo/db/sorter/sorter_test.cpp16
-rw-r--r--src/mongo/db/storage/SConscript1
-rw-r--r--src/mongo/db/storage/devnull/devnull_init.cpp11
-rw-r--r--src/mongo/db/storage/encryption_hooks.cpp25
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/SConscript1
-rw-r--r--src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp13
-rw-r--r--src/mongo/db/storage/kv/SConscript5
-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/kv/kv_engine_test_timestamps.cpp8
-rw-r--r--src/mongo/db/storage/kv/kv_storage_engine_test.cpp25
-rw-r--r--src/mongo/db/storage/mmap_v1/SConscript1
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp9
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_init_test.cpp11
-rw-r--r--src/mongo/db/storage/mobile/SConscript1
-rw-r--r--src/mongo/db/storage/mobile/mobile_init.cpp15
-rw-r--r--src/mongo/db/storage/record_store_test_harness.h2
-rw-r--r--src/mongo/db/storage/sorted_data_interface_test_harness.h1
-rw-r--r--src/mongo/db/storage/storage_engine_init.cpp62
-rw-r--r--src/mongo/db/storage/storage_engine_init.h6
-rw-r--r--src/mongo/db/storage/test_harness_helper.cpp17
-rw-r--r--src/mongo/db/storage/test_harness_helper.h16
-rw-r--r--src/mongo/db/storage/wiredtiger/SConscript1
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp15
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp21
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_extensions.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp14
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_init_test.cpp3
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp5
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp5
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp1
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp16
-rw-r--r--src/mongo/db/ttl.cpp1
-rw-r--r--src/mongo/db/update/SConscript2
-rw-r--r--src/mongo/db/update/object_replace_node_test.cpp1
-rw-r--r--src/mongo/db/update/update_node_test_fixture.h5
-rw-r--r--src/mongo/db/views/SConscript1
-rw-r--r--src/mongo/db/views/view_catalog_test.cpp2
-rw-r--r--src/mongo/dbtests/dbtests.cpp5
-rw-r--r--src/mongo/dbtests/framework.cpp2
-rw-r--r--src/mongo/dbtests/indexupdatetests.cpp1
-rw-r--r--src/mongo/dbtests/querytests.cpp3
-rw-r--r--src/mongo/dbtests/validate_tests.cpp1
-rw-r--r--src/mongo/embedded/SConscript1
-rw-r--r--src/mongo/embedded/embedded.cpp21
-rw-r--r--src/mongo/embedded/service_context_embedded.cpp87
-rw-r--r--src/mongo/executor/SConscript2
-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/rpc/SConscript1
-rw-r--r--src/mongo/s/SConscript5
-rw-r--r--src/mongo/s/async_requests_sender.cpp2
-rw-r--r--src/mongo/s/catalog_cache_test_fixture.cpp6
-rw-r--r--src/mongo/s/client/shard_connection_test.cpp3
-rw-r--r--src/mongo/s/client/shard_registry.cpp2
-rw-r--r--src/mongo/s/client/sharding_network_connection_hook.cpp3
-rw-r--r--src/mongo/s/cluster_cursor_stats.cpp5
-rw-r--r--src/mongo/s/cluster_identity_loader_test.cpp13
-rw-r--r--src/mongo/s/commands/SConscript3
-rw-r--r--src/mongo/s/commands/cluster_aggregate_test.cpp8
-rw-r--r--src/mongo/s/commands/compute_at_cluster_time_test.cpp8
-rw-r--r--src/mongo/s/grid.cpp6
-rw-r--r--src/mongo/s/grid.h4
-rw-r--r--src/mongo/s/metadata_filtering_test.cpp2
-rw-r--r--src/mongo/s/query/SConscript8
-rw-r--r--src/mongo/s/query/async_results_merger_test.cpp8
-rw-r--r--src/mongo/s/query/cluster_client_cursor_impl_test.cpp26
-rw-r--r--src/mongo/s/query/cluster_cursor_cleanup_job.cpp1
-rw-r--r--src/mongo/s/query/cluster_cursor_manager_test.cpp55
-rw-r--r--src/mongo/s/query/cluster_find_test.cpp4
-rw-r--r--src/mongo/s/server.cpp23
-rw-r--r--src/mongo/s/sharding_mongod_test_fixture.cpp16
-rw-r--r--src/mongo/s/sharding_mongod_test_fixture.h1
-rw-r--r--src/mongo/s/sharding_router_test_fixture.cpp27
-rw-r--r--src/mongo/s/sharding_router_test_fixture.h8
-rw-r--r--src/mongo/shell/dbshell.cpp3
-rw-r--r--src/mongo/tools/bridge.cpp9
-rw-r--r--src/mongo/transport/SConscript2
-rw-r--r--src/mongo/transport/service_executor_adaptive_test.cpp5
-rw-r--r--src/mongo/transport/service_executor_test.cpp6
-rw-r--r--src/mongo/transport/service_state_machine_test.cpp4
-rw-r--r--src/mongo/transport/transport_layer_egress_init.cpp32
-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.cpp2
-rw-r--r--src/mongo/util/SConscript2
-rw-r--r--src/mongo/util/periodic_runner_impl_test.cpp8
-rw-r--r--src/mongo/util/producer_consumer_queue_test.cpp6
193 files changed, 1372 insertions, 2067 deletions
diff --git a/jstests/noPassthrough/parse_zone_info.js b/jstests/noPassthrough/parse_zone_info.js
index e7d2aea7333..e8336f121da 100644
--- a/jstests/noPassthrough/parse_zone_info.js
+++ b/jstests/noPassthrough/parse_zone_info.js
@@ -8,7 +8,10 @@
// Test that a non-existent directory causes startup to fail.
conn = MongoRunner.runMongod({timeZoneInfo: "jstests/libs/config_files/missing_directory"});
assert.eq(conn, null, "expected launching mongod 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);
// Test that startup can succeed with a good file.
conn = MongoRunner.runMongod({timeZoneInfo: "jstests/libs/config_files/good_timezone_info"});
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/SConscript b/src/mongo/SConscript
index 6d2f750dd99..d5bd367bb13 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -522,7 +522,6 @@ if not has_option('noshell') and usemozjs:
"$BUILD_DIR/third_party/shim_pcrecpp",
"shell_core",
"db/server_options_core",
- "db/service_context_noop_init",
"client/clientdriver_network",
"$BUILD_DIR/mongo/util/password",
],
diff --git a/src/mongo/bson/SConscript b/src/mongo/bson/SConscript
index dc87d2978d0..fbe9ef1dae0 100644
--- a/src/mongo/bson/SConscript
+++ b/src/mongo/bson/SConscript
@@ -95,6 +95,7 @@ asioEnv.CppIntegrationTest(
],
LIBDEPS=[
'$BUILD_DIR/mongo/executor/network_interface_fixture',
- '$BUILD_DIR/mongo/rpc/protocol'
+ '$BUILD_DIR/mongo/rpc/protocol',
+ '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
],
)
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript
index ac4acab29fe..c5a54ee2b5c 100644
--- a/src/mongo/client/SConscript
+++ b/src/mongo/client/SConscript
@@ -36,8 +36,9 @@ env.CppUnitTest(
'mongo_uri_test.cpp',
],
LIBDEPS=[
- 'clientdriver_network',
'$BUILD_DIR/mongo/transport/transport_layer_egress_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
+ 'clientdriver_network',
],
)
@@ -211,6 +212,7 @@ env.CppIntegrationTest(
],
LIBDEPS=[
'clientdriver_network',
+ '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
'$BUILD_DIR/mongo/util/version_impl',
],
)
@@ -326,7 +328,6 @@ env.CppUnitTest(
LIBDEPS=[
'fetcher',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
],
)
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 24d8dd46eef..1cb106b01e4 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -244,7 +244,6 @@ env.CppUnitTest(
'logical_session_id_helpers',
'service_context',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/unittest/concurrency',
'$BUILD_DIR/mongo/util/clock_source_mock',
],
@@ -508,8 +507,6 @@ env.Library(
'operation_context.cpp',
'operation_context_group.cpp',
'service_context.cpp',
- 'service_context_noop.cpp',
- 'service_context_registrar.cpp',
'server_recovery.cpp',
'unclean_shutdown.cpp',
],
@@ -526,16 +523,6 @@ env.Library(
)
env.Library(
- target='service_context_noop_init',
- source=[
- 'service_context_noop_init.cpp'
- ],
- LIBDEPS=[
- 'service_context',
- ],
-)
-
-env.Library(
target='lasterror',
source=[
"lasterror.cpp",
@@ -607,9 +594,9 @@ env.CppUnitTest(
LIBDEPS=[
'$BUILD_DIR/mongo/idl/idl_parser',
"commands",
- "service_context_noop_init",
"auth/authmocks",
"repl/replmocks",
+ "service_context_test_fixture",
],
)
@@ -677,7 +664,7 @@ env.CppUnitTest(
'auth/authmocks',
'catalog/database_holder_mock',
'catalog_raii',
- 'service_context_noop_init',
+ 'service_context_test_fixture',
'stats/fill_locker_info',
],
)
@@ -726,7 +713,6 @@ env.Library(
env.Library(
target="service_context_d",
source=[
- "service_context_d.cpp",
"service_entry_point_mongod.cpp",
],
LIBDEPS=[
@@ -1196,13 +1182,12 @@ envWithAsio.CppUnitTest(
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/auth/authorization_session_for_test',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/transport/transport_layer_mock',
'logical_session_cache',
'logical_session_cache_impl',
'logical_session_id',
'logical_session_id_helpers',
+ 'service_context_test_fixture',
'service_liaison_mock',
'sessions_collection_mock',
],
@@ -1398,7 +1383,6 @@ envWithAsio.CppUnitTest(
'logical_session_cache_test.cpp',
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/executor/async_timer_mock',
'auth/authmocks',
'keys_collection_manager',
@@ -1409,6 +1393,7 @@ envWithAsio.CppUnitTest(
'logical_session_cache',
'logical_session_cache_impl',
'service_liaison_mock',
+ 'service_context_test_fixture',
'sessions_collection_mock',
],
)
@@ -1708,6 +1693,20 @@ env.CppUnitTest(
)
env.Library(
+ target='service_context_test_fixture',
+ source=[
+ 'service_context_test_fixture.cpp',
+ ],
+ LIBDEPS=[
+ 'service_context',
+ '$BUILD_DIR/mongo/unittest/unittest',
+ ],
+ LIBDEPS_PRIVATE=[
+ 'op_observer',
+ ],
+)
+
+env.Library(
target= 'service_context_d_test_fixture',
source= [
'service_context_d_test_fixture.cpp',
@@ -1718,6 +1717,7 @@ env.Library(
'$BUILD_DIR/mongo/db/storage/storage_options',
'$BUILD_DIR/mongo/unittest/unittest',
'service_context_d',
+ 'service_context_test_fixture',
],
)
@@ -1787,6 +1787,7 @@ asioEnv.CppIntegrationTest(
],
LIBDEPS=[
'$BUILD_DIR/mongo/executor/network_interface_fixture',
+ '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
],
)
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index a086c1e7d6f..35c418f448d 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -282,6 +282,7 @@ env.Library(
LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/server_parameters',
+ '$BUILD_DIR/mongo/util/net/network',
'$BUILD_DIR/mongo/util/options_parser/options_parser',
],
)
@@ -309,17 +310,15 @@ env.Library(
],
)
-env.CppUnitTest(
- target='sasl_mechanism_registry_test',
- source=[
- 'sasl_mechanism_registry_test.cpp',
- ],
- LIBDEPS=[
- 'authmocks',
- 'saslauth',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
- ],
-)
+env.CppUnitTest(target='sasl_mechanism_registry_test',
+ source=[
+ 'sasl_mechanism_registry_test.cpp',
+ ],
+ LIBDEPS=[
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
+ 'authmocks',
+ 'saslauth',
+ ])
env.Library(
target='authmongod',
@@ -343,8 +342,7 @@ env.Library(
source=[
'authz_manager_external_state_s.cpp',
'authz_session_external_state_s.cpp',
- 'user_cache_invalidator_job.cpp'
- ],
+ 'user_cache_invalidator_job.cpp'],
LIBDEPS=[
'authservercommon',
'$BUILD_DIR/mongo/s/catalog/dist_lock_manager',
@@ -376,7 +374,7 @@ env.CppUnitTest(
LIBDEPS=[
'auth',
'authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -388,7 +386,7 @@ env.CppUnitTest(
LIBDEPS=[
'auth',
'authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -400,7 +398,7 @@ env.CppUnitTest(
LIBDEPS=[
'auth',
'authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -412,7 +410,7 @@ env.CppUnitTest(
LIBDEPS=[
'auth',
'authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -424,7 +422,7 @@ env.CppUnitTest(
LIBDEPS=[
'auth',
'authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -436,35 +434,25 @@ env.CppUnitTest(
LIBDEPS=[
'auth',
'authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/transport/transport_layer_common',
'$BUILD_DIR/mongo/transport/transport_layer_mock',
],
)
-env.Library(
- target='authorization_session_for_test',
- source=[
- 'authorization_session_for_test.cpp',
- ],
- LIBDEPS=[
- 'auth',
- 'auth_impl_internal',
- ],
-)
-
env.CppUnitTest(
target='authorization_session_test',
source=[
'authorization_session_test.cpp',
+ 'authorization_session_for_test.cpp',
],
LIBDEPS=[
'auth',
'authmocks',
+ 'auth_impl_internal',
'saslauth',
- 'authorization_session_for_test',
'$BUILD_DIR/mongo/db/pipeline/pipeline',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/transport/transport_layer_mock',
],
)
@@ -491,7 +479,7 @@ env.CppUnitTest(
LIBDEPS=[
'address_restriction',
'$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/util/net/network',
],
)
@@ -506,7 +494,7 @@ env.CppUnitTest(
'authmocks',
'saslauth',
'$BUILD_DIR/mongo/client/sasl_client',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
diff --git a/src/mongo/db/auth/auth_decorations.cpp b/src/mongo/db/auth/auth_decorations.cpp
index c78117b91e6..13b4edbc6b5 100644
--- a/src/mongo/db/auth/auth_decorations.cpp
+++ b/src/mongo/db/auth/auth_decorations.cpp
@@ -53,9 +53,9 @@ const auto getAuthorizationSession =
class AuthzClientObserver final : public ServiceContext::ClientObserver {
public:
void onCreateClient(Client* client) override {
- auto service = client->getServiceContext();
- AuthorizationSession::set(client,
- AuthorizationManager::get(service)->makeAuthorizationSession());
+ if (auto authzManager = AuthorizationManager::get(client->getServiceContext())) {
+ AuthorizationSession::set(client, authzManager->makeAuthorizationSession());
+ }
}
void onDestroyClient(Client* client) override {}
@@ -64,6 +64,11 @@ public:
void onDestroyOperationContext(OperationContext* opCtx) override {}
};
+ServiceContext::ConstructorActionRegisterer authzClientObserverRegisterer{
+ "AuthzClientObserver", [](ServiceContext* service) {
+ service->registerClientObserver(std::make_unique<AuthzClientObserver>());
+ }};
+
} // namespace
void AuthenticationSession::set(Client* client, std::unique_ptr<AuthenticationSession> newSession) {
@@ -86,7 +91,6 @@ AuthorizationManager* AuthorizationManager::get(ServiceContext& service) {
void AuthorizationManager::set(ServiceContext* service,
std::unique_ptr<AuthorizationManager> authzManager) {
getAuthorizationManager(service) = std::move(authzManager);
- service->registerClientObserver(std::make_unique<AuthzClientObserver>());
}
AuthorizationSession* AuthorizationSession::get(Client* client) {
diff --git a/src/mongo/db/auth/authorization_manager_global.cpp b/src/mongo/db/auth/authorization_manager_global.cpp
index 3f8a8808d04..0088ac451d5 100644
--- a/src/mongo/db/auth/authorization_manager_global.cpp
+++ b/src/mongo/db/auth/authorization_manager_global.cpp
@@ -91,23 +91,16 @@ AuthorizationManager* getGlobalAuthorizationManager() {
MONGO_EXPORT_STARTUP_SERVER_PARAMETER(startupAuthSchemaValidation, bool, true);
-GlobalInitializerRegisterer authorizationManagerInitializer(
+ServiceContext::ConstructorActionRegisterer createAuthorizationManager(
"CreateAuthorizationManager",
- {MONGO_SHIM_DEPENDENCY(AuthorizationManager::create),
- "OIDGeneration",
+ {"OIDGeneration",
"EndStartupOptionStorage",
- "ServiceContext"},
- [](InitializerContext* context) {
+ MONGO_SHIM_DEPENDENCY(AuthorizationManager::create)},
+ [](ServiceContext* service) {
auto authzManager = AuthorizationManager::create();
authzManager->setAuthEnabled(serverGlobalParams.authState ==
ServerGlobalParams::AuthState::kEnabled);
authzManager->setShouldValidateAuthSchemaOnStartup(startupAuthSchemaValidation);
- AuthorizationManager::set(getGlobalServiceContext(), std::move(authzManager));
- return Status::OK();
- },
- [](DeinitializerContext* context) {
- AuthorizationManager::set(getGlobalServiceContext(), nullptr);
- return Status::OK();
+ AuthorizationManager::set(service, std::move(authzManager));
});
-
} // namespace mongo
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index cfb62e5ff50..e0ba470d4f5 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -46,8 +46,9 @@
#include "mongo/db/auth/sasl_options.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/namespace_string.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context_test_fixture.h"
+#include "mongo/db/storage/recovery_unit_noop.h"
#include "mongo/stdx/memory.h"
#include "mongo/transport/session.h"
#include "mongo/transport/transport_layer_mock.h"
@@ -73,21 +74,29 @@ void setX509PeerInfo(const transport::SessionHandle& session, SSLPeerInfo info)
using std::vector;
-class AuthorizationManagerTest : public ::mongo::unittest::Test {
+class AuthorizationManagerTest : public ServiceContextTest {
public:
virtual ~AuthorizationManagerTest() {
if (authzManager)
authzManager->invalidateUserCache();
}
- void setUp() override {
+ AuthorizationManagerTest() {
auto localExternalState = std::make_unique<AuthzManagerExternalStateMock>();
externalState = localExternalState.get();
- authzManager = std::make_unique<AuthorizationManagerImpl>(
+ auto localAuthzManager = std::make_unique<AuthorizationManagerImpl>(
std::move(localExternalState),
AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{});
- externalState->setAuthorizationManager(authzManager.get());
+ authzManager = localAuthzManager.get();
+ externalState->setAuthorizationManager(authzManager);
authzManager->setAuthEnabled(true);
+ AuthorizationManager::set(getServiceContext(), std::move(localAuthzManager));
+
+ // Re-initialize the client after setting the AuthorizationManager to get an
+ // AuthorizationSession.
+ Client::releaseCurrent();
+ Client::initThread(getThreadName(), session);
+ opCtx = makeOperationContext();
credentials = BSON("SCRAM-SHA-1"
<< scram::Secrets<SHA1Block>::generateCredentials(
@@ -97,15 +106,18 @@ public:
"password", saslGlobalParams.scramSHA256IterationCount.load()));
}
- std::unique_ptr<AuthorizationManager> authzManager;
+ transport::TransportLayerMock transportLayer;
+ transport::SessionHandle session = transportLayer.createSession();
+ AuthorizationManager* authzManager;
AuthzManagerExternalStateMock* externalState;
BSONObj credentials;
+ ServiceContext::UniqueOperationContext opCtx;
};
TEST_F(AuthorizationManagerTest, testAcquireV2User) {
- OperationContextNoop opCtx;
- ASSERT_OK(externalState->insertPrivilegeDocument(&opCtx,
+
+ ASSERT_OK(externalState->insertPrivilegeDocument(opCtx.get(),
BSON("_id"
<< "admin.v2read"
<< "user"
@@ -120,7 +132,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
<< "db"
<< "test"))),
BSONObj()));
- ASSERT_OK(externalState->insertPrivilegeDocument(&opCtx,
+ ASSERT_OK(externalState->insertPrivilegeDocument(opCtx.get(),
BSON("_id"
<< "admin.v2cluster"
<< "user"
@@ -137,7 +149,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
BSONObj()));
User* v2read;
- ASSERT_OK(authzManager->acquireUser(&opCtx, UserName("v2read", "test"), &v2read));
+ ASSERT_OK(authzManager->acquireUser(opCtx.get(), UserName("v2read", "test"), &v2read));
ASSERT_EQUALS(UserName("v2read", "test"), v2read->getName());
ASSERT(v2read->isValid());
ASSERT_EQUALS(1U, v2read->getRefCount());
@@ -151,7 +163,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
authzManager->releaseUser(v2read);
User* v2cluster;
- ASSERT_OK(authzManager->acquireUser(&opCtx, UserName("v2cluster", "admin"), &v2cluster));
+ ASSERT_OK(authzManager->acquireUser(opCtx.get(), UserName("v2cluster", "admin"), &v2cluster));
ASSERT_EQUALS(UserName("v2cluster", "admin"), v2cluster->getName());
ASSERT(v2cluster->isValid());
ASSERT_EQUALS(1U, v2cluster->getRefCount());
@@ -167,14 +179,9 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
#ifdef MONGO_CONFIG_SSL
TEST_F(AuthorizationManagerTest, testLocalX509Authorization) {
- ServiceContextNoop serviceContext;
- transport::TransportLayerMock transportLayer{};
- transport::SessionHandle session = transportLayer.createSession();
setX509PeerInfo(
session,
SSLPeerInfo(buildX509Name(), {RoleName("read", "test"), RoleName("readWrite", "test")}));
- ServiceContext::UniqueClient client = serviceContext.makeClient("testClient", session);
- ServiceContext::UniqueOperationContext opCtx = client->makeOperationContext();
User* x509User;
ASSERT_OK(
@@ -202,14 +209,9 @@ TEST_F(AuthorizationManagerTest, testLocalX509Authorization) {
#endif
TEST_F(AuthorizationManagerTest, testLocalX509AuthorizationInvalidUser) {
- ServiceContextNoop serviceContext;
- transport::TransportLayerMock transportLayer{};
- transport::SessionHandle session = transportLayer.createSession();
setX509PeerInfo(
session,
SSLPeerInfo(buildX509Name(), {RoleName("read", "test"), RoleName("write", "test")}));
- ServiceContext::UniqueClient client = serviceContext.makeClient("testClient", session);
- ServiceContext::UniqueOperationContext opCtx = client->makeOperationContext();
User* x509User;
ASSERT_NOT_OK(
@@ -217,12 +219,7 @@ TEST_F(AuthorizationManagerTest, testLocalX509AuthorizationInvalidUser) {
}
TEST_F(AuthorizationManagerTest, testLocalX509AuthenticationNoAuthorization) {
- ServiceContextNoop serviceContext;
- transport::TransportLayerMock transportLayer{};
- transport::SessionHandle session = transportLayer.createSession();
setX509PeerInfo(session, {});
- ServiceContext::UniqueClient client = serviceContext.makeClient("testClient", session);
- ServiceContext::UniqueOperationContext opCtx = client->makeOperationContext();
User* x509User;
ASSERT_NOT_OK(
@@ -295,10 +292,10 @@ public:
// Tests SERVER-21535, unrecognized actions should be ignored rather than causing errors.
TEST_F(AuthorizationManagerTest, testAcquireV2UserWithUnrecognizedActions) {
- OperationContextNoop opCtx;
+
ASSERT_OK(externalState->insertPrivilegeDocument(
- &opCtx,
+ opCtx.get(),
BSON("_id"
<< "admin.myUser"
<< "user"
@@ -324,7 +321,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2UserWithUnrecognizedActions) {
BSONObj()));
User* myUser;
- ASSERT_OK(authzManager->acquireUser(&opCtx, UserName("myUser", "test"), &myUser));
+ ASSERT_OK(authzManager->acquireUser(opCtx.get(), UserName("myUser", "test"), &myUser));
ASSERT_EQUALS(UserName("myUser", "test"), myUser->getName());
ASSERT(myUser->isValid());
ASSERT_EQUALS(1U, myUser->getRefCount());
@@ -365,17 +362,16 @@ public:
};
virtual void setUp() override {
- opCtx.setRecoveryUnit(recoveryUnit, WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork);
+ opCtx->setRecoveryUnit(recoveryUnit, WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork);
AuthorizationManagerTest::setUp();
}
- OperationContextNoop opCtx;
size_t registeredChanges = 0;
MockRecoveryUnit* recoveryUnit = new MockRecoveryUnit(&registeredChanges);
};
TEST_F(AuthorizationManagerLogOpTest, testDropDatabaseAddsRecoveryUnits) {
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("dropDatabase"
@@ -385,7 +381,7 @@ TEST_F(AuthorizationManagerLogOpTest, testDropDatabaseAddsRecoveryUnits) {
}
TEST_F(AuthorizationManagerLogOpTest, testDropAuthCollectionAddsRecoveryUnits) {
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("drop"
@@ -393,7 +389,7 @@ TEST_F(AuthorizationManagerLogOpTest, testDropAuthCollectionAddsRecoveryUnits) {
nullptr);
ASSERT_EQ(size_t(1), registeredChanges);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("drop"
@@ -401,7 +397,7 @@ TEST_F(AuthorizationManagerLogOpTest, testDropAuthCollectionAddsRecoveryUnits) {
nullptr);
ASSERT_EQ(size_t(2), registeredChanges);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("drop"
@@ -409,7 +405,7 @@ TEST_F(AuthorizationManagerLogOpTest, testDropAuthCollectionAddsRecoveryUnits) {
nullptr);
ASSERT_EQ(size_t(3), registeredChanges);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("drop"
@@ -419,21 +415,21 @@ TEST_F(AuthorizationManagerLogOpTest, testDropAuthCollectionAddsRecoveryUnits) {
}
TEST_F(AuthorizationManagerLogOpTest, testCreateAnyCollectionAddsNoRecoveryUnits) {
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("create"
<< "system.users"),
nullptr);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("create"
<< "system.profile"),
nullptr);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"c",
{"admin", "$cmd"},
BSON("create"
@@ -444,7 +440,7 @@ TEST_F(AuthorizationManagerLogOpTest, testCreateAnyCollectionAddsNoRecoveryUnits
}
TEST_F(AuthorizationManagerLogOpTest, testRawInsertToRolesCollectionAddsRecoveryUnits) {
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"i",
{"admin", "system.profile"},
BSON("_id"
@@ -452,7 +448,7 @@ TEST_F(AuthorizationManagerLogOpTest, testRawInsertToRolesCollectionAddsRecovery
nullptr);
ASSERT_EQ(size_t(0), registeredChanges);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"i",
{"admin", "system.users"},
BSON("_id"
@@ -460,7 +456,7 @@ TEST_F(AuthorizationManagerLogOpTest, testRawInsertToRolesCollectionAddsRecovery
nullptr);
ASSERT_EQ(size_t(0), registeredChanges);
- authzManager->logOp(&opCtx,
+ authzManager->logOp(opCtx.get(),
"i",
{"admin", "system.roles"},
BSON("_id"
diff --git a/src/mongo/db/auth/authorization_session_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp
index 19e29fcb6f3..e629f50cac5 100644
--- a/src/mongo/db/auth/authorization_session_test.cpp
+++ b/src/mongo/db/auth/authorization_session_test.cpp
@@ -47,7 +47,7 @@
#include "mongo/db/json.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/stdx/memory.h"
#include "mongo/transport/session.h"
#include "mongo/transport/transport_layer_mock.h"
@@ -89,7 +89,7 @@ public:
FailureCapableAuthzManagerExternalStateMock* managerState;
transport::TransportLayerMock transportLayer;
transport::SessionHandle session;
- ServiceContextNoop serviceContext;
+ ServiceContext::UniqueServiceContext serviceContext = ServiceContext::make();
ServiceContext::UniqueClient client;
ServiceContext::UniqueOperationContext _opCtx;
AuthzSessionExternalStateMock* sessionState;
@@ -99,7 +99,7 @@ public:
void setUp() {
session = transportLayer.createSession();
- client = serviceContext.makeClient("testClient", session);
+ client = serviceContext->makeClient("testClient", session);
RestrictionEnvironment::set(
session, stdx::make_unique<RestrictionEnvironment>(SockAddr(), SockAddr()));
_opCtx = client->makeOperationContext();
@@ -110,7 +110,7 @@ public:
std::move(localManagerState),
AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{});
authzManager = uniqueAuthzManager.get();
- AuthorizationManager::set(&serviceContext, std::move(uniqueAuthzManager));
+ AuthorizationManager::set(serviceContext.get(), std::move(uniqueAuthzManager));
auto localSessionState = std::make_unique<AuthzSessionExternalStateMock>(authzManager);
sessionState = localSessionState.get();
authzSession = std::make_unique<AuthorizationSessionForTest>(
diff --git a/src/mongo/db/auth/sasl_authentication_session_test.cpp b/src/mongo/db/auth/sasl_authentication_session_test.cpp
index 8497edcac37..70e07043966 100644
--- a/src/mongo/db/auth/sasl_authentication_session_test.cpp
+++ b/src/mongo/db/auth/sasl_authentication_session_test.cpp
@@ -22,8 +22,8 @@
#include "mongo/db/auth/sasl_plain_server_conversation.h"
#include "mongo/db/auth/sasl_scram_server_conversation.h"
#include "mongo/db/jsobj.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/log.h"
#include "mongo/util/password_digest.h"
@@ -32,7 +32,7 @@ namespace mongo {
namespace {
-class SaslConversation : public unittest::Test {
+class SaslConversation : public ServiceContextTest {
public:
explicit SaslConversation(std::string mech);
@@ -42,8 +42,6 @@ public:
void testWrongClientMechanism();
void testWrongServerMechanism();
- ServiceContextNoop serviceContext;
- ServiceContext::UniqueClient opClient;
ServiceContext::UniqueOperationContext opCtx;
AuthzManagerExternalStateMock* authManagerExternalState;
AuthorizationManager* authManager;
@@ -66,8 +64,7 @@ const std::string mockServiceName = "mocksvc";
const std::string mockHostName = "host.mockery.com";
SaslConversation::SaslConversation(std::string mech)
- : opClient(serviceContext.makeClient("saslTest")),
- opCtx(serviceContext.makeOperationContext(opClient.get())),
+ : opCtx(makeOperationContext()),
authManagerExternalState(new AuthzManagerExternalStateMock),
authManager(new AuthorizationManagerImpl(
std::unique_ptr<AuthzManagerExternalState>(authManagerExternalState),
@@ -75,7 +72,8 @@ SaslConversation::SaslConversation(std::string mech)
authSession(authManager->makeAuthorizationSession()),
mechanism(mech) {
- AuthorizationManager::set(&serviceContext, std::unique_ptr<AuthorizationManager>(authManager));
+ AuthorizationManager::set(getServiceContext(),
+ std::unique_ptr<AuthorizationManager>(authManager));
client.reset(SaslClientSession::create(mechanism));
diff --git a/src/mongo/db/auth/sasl_mechanism_registry.cpp b/src/mongo/db/auth/sasl_mechanism_registry.cpp
index 3426ca97b80..cb588b9b829 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry.cpp
+++ b/src/mongo/db/auth/sasl_mechanism_registry.cpp
@@ -124,23 +124,13 @@ bool SASLServerMechanismRegistry::_mechanismSupportedByConfig(StringData mechNam
return sequenceContains(saslGlobalParams.authenticationMechanisms, mechName);
}
-GlobalInitializerRegisterer SASLServerMechanismRegistryInitializer(
+namespace {
+ServiceContext::ConstructorActionRegisterer SASLServerMechanismRegistryInitializer{
"CreateSASLServerMechanismRegistry",
- {"ServiceContext"},
- [](InitializerContext* context) {
- if (saslGlobalParams.hostName.empty())
- saslGlobalParams.hostName = getHostNameCached();
- if (saslGlobalParams.serviceName.empty())
- saslGlobalParams.serviceName = "mongodb";
-
- auto registry = stdx::make_unique<SASLServerMechanismRegistry>();
- SASLServerMechanismRegistry::set(getGlobalServiceContext(), std::move(registry));
- return Status::OK();
- },
- [](DeinitializerContext* context) {
- SASLServerMechanismRegistry::set(getGlobalServiceContext(), nullptr);
-
- return Status::OK();
- });
+ {"EndStartupOptionStorage"},
+ [](ServiceContext* service) {
+ SASLServerMechanismRegistry::set(service, std::make_unique<SASLServerMechanismRegistry>());
+ }};
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/auth/sasl_mechanism_registry.h b/src/mongo/db/auth/sasl_mechanism_registry.h
index 6d8fba8efd0..78c790b7223 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry.h
+++ b/src/mongo/db/auth/sasl_mechanism_registry.h
@@ -28,6 +28,7 @@
#pragma once
+#include <boost/optional.hpp>
#include <memory>
#include <unordered_map>
@@ -333,4 +334,18 @@ private:
stdx::unordered_map<std::string, std::unique_ptr<ServerFactoryBase>> _externalMap;
};
+template <typename Factory>
+class GlobalSASLMechanismRegisterer {
+private:
+ boost::optional<ServiceContext::ConstructorActionRegisterer> registerer;
+
+public:
+ GlobalSASLMechanismRegisterer() {
+ registerer.emplace(std::string(typeid(Factory).name()),
+ std::vector<std::string>{"CreateSASLServerMechanismRegistry"},
+ [](ServiceContext* service) {
+ SASLServerMechanismRegistry::get(service).registerFactory<Factory>();
+ });
+ }
+};
} // namespace mongo
diff --git a/src/mongo/db/auth/sasl_mechanism_registry_test.cpp b/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
index 6122498e20a..d7f4527f6e7 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
+++ b/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
@@ -31,8 +31,8 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_impl.h"
#include "mongo/db/auth/authz_manager_external_state_mock.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
@@ -128,16 +128,15 @@ public:
};
-class MechanismRegistryTest : public mongo::unittest::Test {
+class MechanismRegistryTest : public ServiceContextTest {
public:
MechanismRegistryTest()
- : opClient(serviceContext.makeClient("mechanismRegistryTest")),
- opCtx(serviceContext.makeOperationContext(opClient.get())),
+ : opCtx(makeOperationContext()),
authManagerExternalState(new AuthzManagerExternalStateMock()),
authManager(new AuthorizationManagerImpl(
std::unique_ptr<AuthzManagerExternalStateMock>(authManagerExternalState),
AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{})) {
- AuthorizationManager::set(&serviceContext,
+ AuthorizationManager::set(getServiceContext(),
std::unique_ptr<AuthorizationManager>(authManager));
ASSERT_OK(authManagerExternalState->updateOne(
@@ -181,8 +180,6 @@ public:
BSONObj()));
}
- ServiceContextNoop serviceContext;
- ServiceContext::UniqueClient opClient;
ServiceContext::UniqueOperationContext opCtx;
AuthzManagerExternalStateMock* authManagerExternalState;
AuthorizationManager* authManager;
diff --git a/src/mongo/db/auth/sasl_options.cpp b/src/mongo/db/auth/sasl_options.cpp
index f35825c6d14..d3eb191a8b4 100644
--- a/src/mongo/db/auth/sasl_options.cpp
+++ b/src/mongo/db/auth/sasl_options.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/server_parameters.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
+#include "mongo/util/net/socket_utils.h"
#include "mongo/util/options_parser/startup_option_init.h"
#include "mongo/util/options_parser/startup_options.h"
@@ -172,6 +173,11 @@ Status storeSASLOptions(const moe::Environment& params) {
}
}
+ if (saslGlobalParams.hostName.empty())
+ saslGlobalParams.hostName = getHostNameCached();
+ if (saslGlobalParams.serviceName.empty())
+ saslGlobalParams.serviceName = "mongodb";
+
return Status::OK();
}
diff --git a/src/mongo/db/auth/sasl_plain_server_conversation.cpp b/src/mongo/db/auth/sasl_plain_server_conversation.cpp
index 3c32c9b7f58..7d89c2eaeb8 100644
--- a/src/mongo/db/auth/sasl_plain_server_conversation.cpp
+++ b/src/mongo/db/auth/sasl_plain_server_conversation.cpp
@@ -157,12 +157,7 @@ StatusWith<std::tuple<bool, std::string>> SASLPlainServerMechanism::stepImpl(
return std::make_tuple(true, std::string());
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(SASLPLAINServerMechanism,
- ("CreateSASLServerMechanismRegistry"))
-(::mongo::InitializerContext* context) {
- auto& registry = SASLServerMechanismRegistry::get(getGlobalServiceContext());
- registry.registerFactory<PLAINServerFactory>();
- return Status::OK();
-}
-
+namespace {
+GlobalSASLMechanismRegisterer<PLAINServerFactory> plainRegisterer;
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/auth/sasl_scram_server_conversation.cpp b/src/mongo/db/auth/sasl_scram_server_conversation.cpp
index 28cbe4537fd..d3ded3c88f8 100644
--- a/src/mongo/db/auth/sasl_scram_server_conversation.cpp
+++ b/src/mongo/db/auth/sasl_scram_server_conversation.cpp
@@ -342,13 +342,8 @@ StatusWith<std::tuple<bool, std::string>> SaslSCRAMServerMechanism<Policy>::_sec
template class SaslSCRAMServerMechanism<SCRAMSHA1Policy>;
template class SaslSCRAMServerMechanism<SCRAMSHA256Policy>;
-MONGO_INITIALIZER_WITH_PREREQUISITES(SASLSCRAMServerMechanism,
- ("CreateSASLServerMechanismRegistry"))
-(::mongo::InitializerContext* context) {
- auto& registry = SASLServerMechanismRegistry::get(getGlobalServiceContext());
- registry.registerFactory<SCRAMSHA1ServerFactory>();
- registry.registerFactory<SCRAMSHA256ServerFactory>();
- return Status::OK();
-}
-
+namespace {
+GlobalSASLMechanismRegisterer<SCRAMSHA1ServerFactory> scramsha1Registerer;
+GlobalSASLMechanismRegisterer<SCRAMSHA256ServerFactory> scramsha256Registerer;
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/auth/sasl_scram_test.cpp b/src/mongo/db/auth/sasl_scram_test.cpp
index 2a347b6d464..4520586f0a4 100644
--- a/src/mongo/db/auth/sasl_scram_test.cpp
+++ b/src/mongo/db/auth/sasl_scram_test.cpp
@@ -43,7 +43,7 @@
#include "mongo/db/auth/authz_session_external_state_mock.h"
#include "mongo/db/auth/sasl_mechanism_registry.h"
#include "mongo/db/auth/sasl_scram_server_conversation.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/base64.h"
@@ -174,9 +174,9 @@ protected:
const SCRAMStepsResult goalState =
SCRAMStepsResult(SaslTestState(SaslTestState::kClient, 4), Status::OK());
- std::unique_ptr<ServiceContextNoop> serviceContext;
- ServiceContextNoop::UniqueClient client;
- ServiceContextNoop::UniqueOperationContext opCtx;
+ ServiceContext::UniqueServiceContext serviceContext;
+ ServiceContext::UniqueClient client;
+ ServiceContext::UniqueOperationContext opCtx;
AuthzManagerExternalStateMock* authzManagerExternalState;
AuthorizationManager* authzManager;
@@ -186,7 +186,7 @@ protected:
std::unique_ptr<NativeSaslClientSession> saslClientSession;
void setUp() final {
- serviceContext = stdx::make_unique<ServiceContextNoop>();
+ serviceContext = ServiceContext::make();
client = serviceContext->makeClient("test");
opCtx = serviceContext->makeOperationContext(client.get());
diff --git a/src/mongo/db/catalog/database_holder_impl.cpp b/src/mongo/db/catalog/database_holder_impl.cpp
index fcfde5272ab..17058837479 100644
--- a/src/mongo/db/catalog/database_holder_impl.cpp
+++ b/src/mongo/db/catalog/database_holder_impl.cpp
@@ -50,23 +50,14 @@
namespace mongo {
namespace {
-std::unique_ptr<DatabaseHolder> dbHolderStorage;
-
-GlobalInitializerRegisterer dbHolderImplInitializer("InitializeDbHolderimpl",
- [](InitializerContext* const) {
- dbHolderStorage =
- std::make_unique<DatabaseHolder>();
- return Status::OK();
- },
- [](DeinitializerContext* const) {
- dbHolderStorage = nullptr;
- return Status::OK();
- });
+
+const auto dbHolderStorage = ServiceContext::declareDecoration<DatabaseHolder>();
+
} // namespace
MONGO_REGISTER_SHIM(DatabaseHolder::getDatabaseHolder)
()->DatabaseHolder& {
- return *dbHolderStorage;
+ return dbHolderStorage(getGlobalServiceContext());
}
MONGO_REGISTER_SHIM(DatabaseHolder::makeImpl)
diff --git a/src/mongo/db/catalog_raii_test.cpp b/src/mongo/db/catalog_raii_test.cpp
index b824b445148..4d178e9d724 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<DefaultLockerImpl>());
return std::make_pair(std::move(client), std::move(opCtx));
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index 99b172505e3..74130191b99 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -47,6 +47,7 @@
#include "mongo/transport/session.h"
#include "mongo/util/concurrency/spin_lock.h"
#include "mongo/util/decorable.h"
+#include "mongo/util/invariant.h"
#include "mongo/util/net/hostandport.h"
namespace mongo {
@@ -242,6 +243,37 @@ private:
PseudoRandom _prng;
};
+/**
+ * Utility class to temporarily swap which client is bound to the running thread.
+ *
+ * Use this class to bind a client to the current thread for the duration of the
+ * AlternativeClientRegion's lifetime, restoring the prior client, if any, at the
+ * end of the block.
+ */
+class AlternativeClientRegion {
+public:
+ explicit AlternativeClientRegion(ServiceContext::UniqueClient& clientToUse)
+ : _alternateClient(&clientToUse) {
+ invariant(clientToUse);
+ if (Client::getCurrent()) {
+ _originalClient = Client::releaseCurrent();
+ }
+ Client::setCurrent(std::move(*_alternateClient));
+ }
+
+ ~AlternativeClientRegion() {
+ *_alternateClient = Client::releaseCurrent();
+ if (_originalClient) {
+ Client::setCurrent(std::move(_originalClient));
+ }
+ }
+
+private:
+ ServiceContext::UniqueClient _originalClient;
+ ServiceContext::UniqueClient* const _alternateClient;
+};
+
+
/** get the Client object for this thread. */
Client& cc();
diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp
index 200a128b664..fca4761b28c 100644
--- a/src/mongo/db/clientcursor.cpp
+++ b/src/mongo/db/clientcursor.cpp
@@ -262,6 +262,7 @@ public:
void run() {
Client::initThread("clientcursormon");
+ ON_BLOCK_EXIT([] { Client::destroy(); });
while (!globalInShutdownDeprecated()) {
{
const ServiceContext::UniqueOperationContext opCtx = cc().makeOperationContext();
diff --git a/src/mongo/db/commands/dbcheck.cpp b/src/mongo/db/commands/dbcheck.cpp
index b29bb881a05..5db2476f8b2 100644
--- a/src/mongo/db/commands/dbcheck.cpp
+++ b/src/mongo/db/commands/dbcheck.cpp
@@ -192,6 +192,7 @@ protected:
virtual void run() override {
// Every dbCheck runs in its own client.
Client::initThread(name());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
for (const auto& coll : *_run) {
try {
diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp
index 1af900475e7..81807c7e526 100644
--- a/src/mongo/db/commands/fsync.cpp
+++ b/src/mongo/db/commands/fsync.cpp
@@ -335,6 +335,7 @@ SimpleMutex filesLockedFsync;
void FSyncLockThread::run() {
Client::initThread("fsyncLockWorker");
+ ON_BLOCK_EXIT([] { Client::destroy(); });
stdx::lock_guard<SimpleMutex> lkf(filesLockedFsync);
stdx::unique_lock<stdx::mutex> lk(fsyncCmd.lockStateMutex);
diff --git a/src/mongo/db/commands/index_filter_commands_test.cpp b/src/mongo/db/commands/index_filter_commands_test.cpp
index da0b0b919d0..7ee3a62e25d 100644
--- a/src/mongo/db/commands/index_filter_commands_test.cpp
+++ b/src/mongo/db/commands/index_filter_commands_test.cpp
@@ -149,13 +149,12 @@ void addQueryShapeToPlanCache(OperationContext* opCtx,
/**
* Checks if plan cache contains query shape.
*/
-bool planCacheContains(const PlanCache& planCache,
+bool planCacheContains(OperationContext* opCtx,
+ const PlanCache& planCache,
const char* queryStr,
const char* sortStr,
const char* projectionStr,
const char* collationStr) {
- QueryTestServiceContext serviceContext;
- auto opCtx = serviceContext.makeOperationContext();
// Create canonical query.
auto qr = stdx::make_unique<QueryRequest>(nss);
@@ -163,7 +162,7 @@ bool planCacheContains(const PlanCache& planCache,
qr->setSort(fromjson(sortStr));
qr->setProj(fromjson(projectionStr));
qr->setCollation(fromjson(collationStr));
- auto statusWithInputQuery = CanonicalQuery::canonicalize(opCtx.get(), std::move(qr));
+ auto statusWithInputQuery = CanonicalQuery::canonicalize(opCtx, std::move(qr));
ASSERT_OK(statusWithInputQuery.getStatus());
unique_ptr<CanonicalQuery> inputQuery = std::move(statusWithInputQuery.getValue());
@@ -183,7 +182,7 @@ bool planCacheContains(const PlanCache& planCache,
qr->setSort(entry->sort);
qr->setProj(entry->projection);
qr->setCollation(entry->collation);
- auto statusWithCurrentQuery = CanonicalQuery::canonicalize(opCtx.get(), std::move(qr));
+ auto statusWithCurrentQuery = CanonicalQuery::canonicalize(opCtx, std::move(qr));
ASSERT_OK(statusWithCurrentQuery.getStatus());
unique_ptr<CanonicalQuery> currentQuery = std::move(statusWithCurrentQuery.getValue());
@@ -333,8 +332,12 @@ TEST(IndexFilterCommandsTest, SetAndClearFilters) {
"{a: -1}",
"{_id: 0, a: 1}",
"{locale: 'mock_reverse_string'}");
- ASSERT_TRUE(planCacheContains(
- planCache, "{a: 1, b: 1}", "{a: -1}", "{_id: 0, a: 1}", "{locale: 'mock_reverse_string'}"));
+ ASSERT_TRUE(planCacheContains(opCtx.get(),
+ planCache,
+ "{a: 1, b: 1}",
+ "{a: -1}",
+ "{_id: 0, a: 1}",
+ "{locale: 'mock_reverse_string'}"));
ASSERT_OK(SetFilter::set(opCtx.get(),
&querySettings,
@@ -347,8 +350,12 @@ TEST(IndexFilterCommandsTest, SetAndClearFilters) {
ASSERT_EQUALS(filters.size(), 1U);
// Query shape should not exist in plan cache after hint is updated.
- ASSERT_FALSE(planCacheContains(
- planCache, "{a: 1, b: 1}", "{a: -1}", "{_id: 0, a: 1}", "{locale: 'mock_reverse_string'}"));
+ ASSERT_FALSE(planCacheContains(opCtx.get(),
+ planCache,
+ "{a: 1, b: 1}",
+ "{a: -1}",
+ "{_id: 0, a: 1}",
+ "{locale: 'mock_reverse_string'}"));
// Fields in filter should match criteria in most recent query settings update.
ASSERT_BSONOBJ_EQ(filters[0].getObjectField("query"), fromjson("{a: 1, b: 1}"));
@@ -403,8 +410,8 @@ TEST(IndexFilterCommandsTest, SetAndClearFilters) {
ASSERT_EQUALS(filters.size(), 2U);
// Query shape should not exist in plan cache after cleaing 1 hint.
- ASSERT_FALSE(planCacheContains(planCache, "{a: 1}", "{}", "{}", "{}"));
- ASSERT_TRUE(planCacheContains(planCache, "{b: 1}", "{}", "{}", "{}"));
+ ASSERT_FALSE(planCacheContains(opCtx.get(), planCache, "{a: 1}", "{}", "{}", "{}"));
+ ASSERT_TRUE(planCacheContains(opCtx.get(), planCache, "{b: 1}", "{}", "{}", "{}"));
// Clear all filters
ASSERT_OK(
@@ -413,7 +420,7 @@ TEST(IndexFilterCommandsTest, SetAndClearFilters) {
ASSERT_TRUE(filters.empty());
// {b: 1} should be gone from plan cache after flushing query settings.
- ASSERT_FALSE(planCacheContains(planCache, "{b: 1}", "{}", "{}", "{}"));
+ ASSERT_FALSE(planCacheContains(opCtx.get(), planCache, "{b: 1}", "{}", "{}", "{}"));
}
TEST(IndexFilterCommandsTest, SetAndClearFiltersCollation) {
@@ -430,9 +437,9 @@ TEST(IndexFilterCommandsTest, SetAndClearFiltersCollation) {
addQueryShapeToPlanCache(
opCtx.get(), &planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}");
addQueryShapeToPlanCache(opCtx.get(), &planCache, "{a: 'foo'}", "{}", "{}", "{}");
- ASSERT_TRUE(
- planCacheContains(planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}"));
- ASSERT_TRUE(planCacheContains(planCache, "{a: 'foo'}", "{}", "{}", "{}"));
+ ASSERT_TRUE(planCacheContains(
+ opCtx.get(), planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}"));
+ ASSERT_TRUE(planCacheContains(opCtx.get(), planCache, "{a: 'foo'}", "{}", "{}", "{}"));
ASSERT_OK(SetFilter::set(opCtx.get(),
&querySettings,
@@ -450,9 +457,9 @@ TEST(IndexFilterCommandsTest, SetAndClearFiltersCollation) {
"mock_reverse_string");
// Plan cache should only contain entry for query without collation.
- ASSERT_FALSE(
- planCacheContains(planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}"));
- ASSERT_TRUE(planCacheContains(planCache, "{a: 'foo'}", "{}", "{}", "{}"));
+ ASSERT_FALSE(planCacheContains(
+ opCtx.get(), planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}"));
+ ASSERT_TRUE(planCacheContains(opCtx.get(), planCache, "{a: 'foo'}", "{}", "{}", "{}"));
// Add filter for query shape without collation.
ASSERT_OK(SetFilter::set(opCtx.get(),
@@ -483,9 +490,9 @@ TEST(IndexFilterCommandsTest, SetAndClearFiltersCollation) {
ASSERT_BSONOBJ_EQ(filters[0].getObjectField("collation"), fromjson("{}"));
// Plan cache should only contain entry for query without collation.
- ASSERT_FALSE(
- planCacheContains(planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}"));
- ASSERT_TRUE(planCacheContains(planCache, "{a: 'foo'}", "{}", "{}", "{}"));
+ ASSERT_FALSE(planCacheContains(
+ opCtx.get(), planCache, "{a: 'foo'}", "{}", "{}", "{locale: 'mock_reverse_string'}"));
+ ASSERT_TRUE(planCacheContains(opCtx.get(), planCache, "{a: 'foo'}", "{}", "{}", "{}"));
}
@@ -504,7 +511,7 @@ TEST(IndexFilterCommandsTest, SetFilterAcceptsIndexNames) {
collatedIndex});
addQueryShapeToPlanCache(opCtx.get(), &planCache, "{a: 2}", "{}", "{}", "{}");
- ASSERT_TRUE(planCacheContains(planCache, "{a: 2}", "{}", "{}", "{}"));
+ ASSERT_TRUE(planCacheContains(opCtx.get(), planCache, "{a: 2}", "{}", "{}", "{}"));
ASSERT_OK(SetFilter::set(opCtx.get(),
&querySettings,
diff --git a/src/mongo/db/commands_test.cpp b/src/mongo/db/commands_test.cpp
index 0bec7ad4b51..2cdc620d0d9 100644
--- a/src/mongo/db/commands_test.cpp
+++ b/src/mongo/db/commands_test.cpp
@@ -32,7 +32,7 @@
#include "mongo/db/commands.h"
#include "mongo/db/commands_test_example_gen.h"
#include "mongo/db/dbmessage.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
@@ -96,14 +96,9 @@ TEST(Commands, appendCommandStatusErrorExtraInfo) {
ASSERT_BSONOBJ_EQ(actualResult.obj(), expectedResult.obj());
}
-class ParseNsOrUUID : public unittest::Test {
+class ParseNsOrUUID : public ServiceContextTest {
public:
- ParseNsOrUUID()
- : client(service.makeClient("test")),
- opCtxPtr(client->makeOperationContext()),
- opCtx(opCtxPtr.get()) {}
- ServiceContextNoop service;
- ServiceContext::UniqueClient client;
+ ParseNsOrUUID() : opCtxPtr(makeOperationContext()), opCtx(opCtxPtr.get()) {}
ServiceContext::UniqueOperationContext opCtxPtr;
OperationContext* opCtx;
};
@@ -333,18 +328,18 @@ ExampleMinimalCommand exampleMinimalCommand;
ExampleVoidCommand exampleVoidCommand;
CmdT<decltype(throwFn)> throwStatusCommand("throwsStatus", throwFn);
-struct IncrementTestCommon {
+class TypedCommand : public ServiceContextTest {
+protected:
template <typename T>
- void run(T& command, std::function<void(int, const BSONObj&)> postAssert) {
+ void runIncr(T& command, std::function<void(int, const BSONObj&)> postAssert) {
const NamespaceString ns("testdb.coll");
- auto client = getGlobalServiceContext()->makeClient("commands_test");
for (std::int32_t i : {123, 12345, 0, -456}) {
const OpMsgRequest request = [&] {
typename T::Request incr(ns);
incr.setI(i);
return incr.serialize(BSON("$db" << ns.db()));
}();
- auto opCtx = client->makeOperationContext();
+ auto opCtx = makeOperationContext();
auto invocation = command.parse(opCtx.get(), request);
ASSERT_EQ(invocation->ns(), ns);
@@ -368,29 +363,29 @@ struct IncrementTestCommon {
}
};
-TEST(TypedCommand, runTyped) {
- IncrementTestCommon{}.run(exampleIncrementCommand, [](int i, const BSONObj& reply) {
+TEST_F(TypedCommand, runTyped) {
+ runIncr(exampleIncrementCommand, [](int i, const BSONObj& reply) {
ASSERT_EQ(reply["ok"].Double(), 1.0);
ASSERT_EQ(reply["iPlusOne"].Int(), i + 1);
});
}
-TEST(TypedCommand, runMinimal) {
- IncrementTestCommon{}.run(exampleMinimalCommand, [](int i, const BSONObj& reply) {
+TEST_F(TypedCommand, runMinimal) {
+ runIncr(exampleMinimalCommand, [](int i, const BSONObj& reply) {
ASSERT_EQ(reply["ok"].Double(), 1.0);
ASSERT_EQ(reply["iPlusOne"].Int(), i + 1);
});
}
-TEST(TypedCommand, runVoid) {
- IncrementTestCommon{}.run(exampleVoidCommand, [](int i, const BSONObj& reply) {
+TEST_F(TypedCommand, runVoid) {
+ runIncr(exampleVoidCommand, [](int i, const BSONObj& reply) {
ASSERT_EQ(reply["ok"].Double(), 1.0);
ASSERT_EQ(exampleVoidCommand.iCapture, i + 1);
});
}
-TEST(TypedCommand, runThrowStatus) {
- IncrementTestCommon{}.run(throwStatusCommand, [](int i, const BSONObj& reply) {
+TEST_F(TypedCommand, runThrowStatus) {
+ runIncr(throwStatusCommand, [](int i, const BSONObj& reply) {
Status status = Status::OK();
try {
(void)throwFn();
diff --git a/src/mongo/db/concurrency/SConscript b/src/mongo/db/concurrency/SConscript
index 947096a1eab..0ca5123d60b 100644
--- a/src/mongo/db/concurrency/SConscript
+++ b/src/mongo/db/concurrency/SConscript
@@ -56,7 +56,6 @@ env.Benchmark(
'd_concurrency_bm.cpp',
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'lock_manager',
])
@@ -70,9 +69,10 @@ env.CppUnitTest(
'lock_stats_test.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/curop',
+ '$BUILD_DIR/mongo/db/service_context_d_test_fixture',
'$BUILD_DIR/mongo/util/progress_meter',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'lock_manager',
'write_conflict_exception',
]
diff --git a/src/mongo/db/concurrency/d_concurrency_test.cpp b/src/mongo/db/concurrency/d_concurrency_test.cpp
index 2436190e851..d54f2896c62 100644
--- a/src/mongo/db/concurrency/d_concurrency_test.cpp
+++ b/src/mongo/db/concurrency/d_concurrency_test.cpp
@@ -38,6 +38,7 @@
#include "mongo/db/concurrency/global_lock_acquisition_tracker.h"
#include "mongo/db/concurrency/lock_manager_test_help.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/db/storage/recovery_unit_noop.h"
#include "mongo/stdx/functional.h"
#include "mongo/stdx/future.h"
@@ -78,19 +79,8 @@ private:
};
-class DConcurrencyTestFixture : public unittest::Test {
+class DConcurrencyTestFixture : public ServiceContextMongoDTest {
public:
- DConcurrencyTestFixture() : _client(getGlobalServiceContext()->makeClient("testClient")) {}
- ~DConcurrencyTestFixture() {}
-
- /**
- * Constructs and returns a new OperationContext.
- */
- ServiceContext::UniqueOperationContext makeOpCtx() const {
- auto opCtx = _client->makeOperationContext();
- return opCtx;
- }
-
/**
* Returns a vector of Clients of length 'k', each of which has an OperationContext with its
* lockState set to a DefaultLockerImpl.
@@ -102,8 +92,8 @@ public:
clients;
clients.reserve(k);
for (int i = 0; i < k; ++i) {
- auto client = getGlobalServiceContext()->makeClient(
- str::stream() << "test client for thread " << i);
+ auto client =
+ getServiceContext()->makeClient(str::stream() << "test client for thread " << i);
auto opCtx = client->makeOperationContext();
opCtx->swapLockState(stdx::make_unique<LockerType>());
clients.emplace_back(std::move(client), std::move(opCtx));
@@ -130,20 +120,17 @@ public:
return result;
}
-
-private:
- ServiceContext::UniqueClient _client;
};
TEST_F(DConcurrencyTestFixture, WriteConflictRetryInstantiatesOK) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
writeConflictRetry(opCtx.get(), "", "", [] {});
}
TEST_F(DConcurrencyTestFixture, WriteConflictRetryRetriesFunctionOnWriteConflictException) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto&& opDebug = CurOp::get(opCtx.get())->debug();
ASSERT_EQUALS(boost::none, opDebug.additiveMetrics.writeConflicts);
@@ -157,7 +144,7 @@ TEST_F(DConcurrencyTestFixture, WriteConflictRetryRetriesFunctionOnWriteConflict
}
TEST_F(DConcurrencyTestFixture, WriteConflictRetryPropagatesNonWriteConflictException) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
ASSERT_THROWS_CODE(writeConflictRetry(opCtx.get(),
"",
@@ -172,7 +159,7 @@ TEST_F(DConcurrencyTestFixture, WriteConflictRetryPropagatesNonWriteConflictExce
TEST_F(DConcurrencyTestFixture,
WriteConflictRetryPropagatesWriteConflictExceptionIfAlreadyInAWriteUnitOfWork) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::GlobalWrite globalWrite(opCtx.get());
WriteUnitOfWork wuow(opCtx.get());
@@ -263,21 +250,21 @@ TEST_F(DConcurrencyTestFixture, ResourceMutex) {
}
TEST_F(DConcurrencyTestFixture, GlobalRead) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::GlobalRead globalRead(opCtx.get());
ASSERT(opCtx->lockState()->isR());
}
TEST_F(DConcurrencyTestFixture, GlobalWrite) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::GlobalWrite globalWrite(opCtx.get());
ASSERT(opCtx->lockState()->isW());
}
TEST_F(DConcurrencyTestFixture, GlobalWriteAndGlobalRead) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
@@ -294,7 +281,7 @@ TEST_F(DConcurrencyTestFixture, GlobalWriteAndGlobalRead) {
TEST_F(DConcurrencyTestFixture,
GlobalWriteRequiresExplicitDowngradeToIntentWriteModeIfDestroyedWhileHoldingDatabaseLock) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
@@ -342,7 +329,7 @@ TEST_F(DConcurrencyTestFixture,
TEST_F(DConcurrencyTestFixture,
GlobalWriteRequiresSupportsDowngradeToIntentWriteModeWhileHoldingDatabaseLock) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
@@ -389,7 +376,7 @@ TEST_F(DConcurrencyTestFixture,
TEST_F(DConcurrencyTestFixture,
NestedGlobalWriteSupportsDowngradeToIntentWriteModeWhileHoldingDatabaseLock) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
@@ -596,7 +583,7 @@ TEST_F(DConcurrencyTestFixture, GlobalLockX_TimeoutDueToGlobalLockX) {
}
TEST_F(DConcurrencyTestFixture, TempReleaseGlobalWrite) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
Lock::GlobalWrite globalWrite(opCtx.get());
@@ -610,7 +597,7 @@ TEST_F(DConcurrencyTestFixture, TempReleaseGlobalWrite) {
}
TEST_F(DConcurrencyTestFixture, TempReleaseRecursive) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
Lock::GlobalWrite globalWrite(opCtx.get());
@@ -826,7 +813,7 @@ TEST_F(DConcurrencyTestFixture, DBLockWaitIsNotInterruptibleWithLockGuard) {
TEST_F(DConcurrencyTestFixture, DBLockTakesS) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock dbRead(opCtx.get(), "db", MODE_S);
@@ -835,7 +822,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesS) {
}
TEST_F(DConcurrencyTestFixture, DBLockTakesX) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock dbWrite(opCtx.get(), "db", MODE_X);
@@ -844,7 +831,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesX) {
}
TEST_F(DConcurrencyTestFixture, DBLockTakesISForAdminIS) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock dbRead(opCtx.get(), "admin", MODE_IS);
@@ -852,7 +839,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesISForAdminIS) {
}
TEST_F(DConcurrencyTestFixture, DBLockTakesSForAdminS) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock dbRead(opCtx.get(), "admin", MODE_S);
@@ -860,7 +847,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesSForAdminS) {
}
TEST_F(DConcurrencyTestFixture, DBLockTakesXForAdminIX) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock dbWrite(opCtx.get(), "admin", MODE_IX);
@@ -868,7 +855,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesXForAdminIX) {
}
TEST_F(DConcurrencyTestFixture, DBLockTakesXForAdminX) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock dbWrite(opCtx.get(), "admin", MODE_X);
@@ -876,7 +863,7 @@ TEST_F(DConcurrencyTestFixture, DBLockTakesXForAdminX) {
}
TEST_F(DConcurrencyTestFixture, MultipleWriteDBLocksOnSameThread) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
Lock::DBLock r1(opCtx.get(), "db1", MODE_X);
Lock::DBLock r2(opCtx.get(), "db1", MODE_X);
@@ -885,7 +872,7 @@ TEST_F(DConcurrencyTestFixture, MultipleWriteDBLocksOnSameThread) {
}
TEST_F(DConcurrencyTestFixture, MultipleConflictingDBLocksOnSameThread) {
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
Lock::DBLock r1(opCtx.get(), "db1", MODE_X);
@@ -898,7 +885,7 @@ TEST_F(DConcurrencyTestFixture, MultipleConflictingDBLocksOnSameThread) {
TEST_F(DConcurrencyTestFixture, IsDbLockedForSMode) {
const std::string dbName("db");
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
Lock::DBLock dbLock(opCtx.get(), dbName, MODE_S);
@@ -912,7 +899,7 @@ TEST_F(DConcurrencyTestFixture, IsDbLockedForSMode) {
TEST_F(DConcurrencyTestFixture, IsDbLockedForXMode) {
const std::string dbName("db");
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
Lock::DBLock dbLock(opCtx.get(), dbName, MODE_X);
@@ -926,7 +913,7 @@ TEST_F(DConcurrencyTestFixture, IsDbLockedForXMode) {
TEST_F(DConcurrencyTestFixture, IsCollectionLocked_DB_Locked_IS) {
const std::string ns("db1.coll");
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
@@ -957,7 +944,7 @@ TEST_F(DConcurrencyTestFixture, IsCollectionLocked_DB_Locked_IS) {
TEST_F(DConcurrencyTestFixture, IsCollectionLocked_DB_Locked_IX) {
const std::string ns("db1.coll");
- auto opCtx = makeOpCtx();
+ auto opCtx = makeOperationContext();
opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
auto lockState = opCtx->lockState();
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 69b61379772..9aa5c806427 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -119,8 +119,6 @@
#include "mongo/db/server_options.h"
#include "mongo/db/server_parameters.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/db/service_entry_point_mongod.h"
#include "mongo/db/session_catalog.h"
#include "mongo/db/session_killer.h"
@@ -322,8 +320,6 @@ ExitCode _initAndListen(int listenPort) {
logProcessDetails();
- createLockFile(serviceContext);
-
serviceContext->setServiceEntryPoint(
stdx::make_unique<ServiceEntryPointMongod>(serviceContext));
@@ -367,7 +363,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.";
@@ -809,10 +805,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);
@@ -849,7 +842,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
@@ -997,6 +989,18 @@ int mongoDbMain(int argc, char* argv[], char** envp) {
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();
startupConfigActions(std::vector<std::string>(argv, argv + argc));
diff --git a/src/mongo/db/exec/SConscript b/src/mongo/db/exec/SConscript
index a5ffcde4cbb..bb9b13becfd 100644
--- a/src/mongo/db/exec/SConscript
+++ b/src/mongo/db/exec/SConscript
@@ -60,7 +60,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/db/auth/authmocks",
"$BUILD_DIR/mongo/db/query_exec",
"$BUILD_DIR/mongo/db/serveronly",
- "$BUILD_DIR/mongo/db/service_context_d",
+ "$BUILD_DIR/mongo/db/service_context_d_test_fixture",
"$BUILD_DIR/mongo/dbtests/mocklib",
"$BUILD_DIR/mongo/util/clock_source_mock",
],
@@ -75,7 +75,7 @@ env.CppUnitTest(
"$BUILD_DIR/mongo/db/auth/authmocks",
"$BUILD_DIR/mongo/db/query_exec",
"$BUILD_DIR/mongo/db/serveronly",
- "$BUILD_DIR/mongo/db/service_context_d",
+ "$BUILD_DIR/mongo/db/service_context_d_test_fixture",
"$BUILD_DIR/mongo/dbtests/mocklib",
"$BUILD_DIR/mongo/db/query/collation/collator_factory_mock",
"$BUILD_DIR/mongo/db/query/collation/collator_interface_mock",
diff --git a/src/mongo/db/exec/queued_data_stage_test.cpp b/src/mongo/db/exec/queued_data_stage_test.cpp
index 960d832777a..de09994b2a0 100644
--- a/src/mongo/db/exec/queued_data_stage_test.cpp
+++ b/src/mongo/db/exec/queued_data_stage_test.cpp
@@ -35,9 +35,8 @@
#include <boost/optional.hpp>
#include "mongo/db/exec/working_set.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/clock_source_mock.h"
@@ -49,30 +48,20 @@ namespace {
using std::unique_ptr;
using stdx::make_unique;
-class QueuedDataStageTest : public unittest::Test {
+class QueuedDataStageTest : public ServiceContextMongoDTest {
public:
QueuedDataStageTest() {
- _service = stdx::make_unique<ServiceContextNoop>();
- _service->setFastClockSource(stdx::make_unique<ClockSourceMock>());
- _client = _service->makeClient("test");
- _opCtxNoop = _client->makeOperationContext();
- _opCtx = _opCtxNoop.get();
+ getServiceContext()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
+ _opCtx = makeOperationContext();
}
protected:
OperationContext* getOpCtx() {
- return _opCtx;
+ return _opCtx.get();
}
private:
- OperationContext* _opCtx;
-
- // Members of a class are destroyed in reverse order of declaration.
- // The UniqueClient must be destroyed before the ServiceContextNoop is destroyed.
- // The OperationContextNoop must be destroyed before the UniqueClient is destroyed.
- std::unique_ptr<ServiceContextNoop> _service;
- ServiceContext::UniqueClient _client;
- ServiceContext::UniqueOperationContext _opCtxNoop;
+ ServiceContext::UniqueOperationContext _opCtx;
};
//
diff --git a/src/mongo/db/exec/sort_test.cpp b/src/mongo/db/exec/sort_test.cpp
index 08f3f15580e..b45626b0999 100644
--- a/src/mongo/db/exec/sort_test.cpp
+++ b/src/mongo/db/exec/sort_test.cpp
@@ -36,11 +36,10 @@
#include "mongo/db/exec/queued_data_stage.h"
#include "mongo/db/json.h"
-#include "mongo/db/operation_context_noop.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/query/collation/collator_factory_mock.h"
#include "mongo/db/query/collation/collator_interface_mock.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/clock_source_mock.h"
@@ -49,19 +48,17 @@ using namespace mongo;
namespace {
-class SortStageTest : public unittest::Test {
+class SortStageTest : public ServiceContextMongoDTest {
public:
SortStageTest() {
- _service = stdx::make_unique<ServiceContextNoop>();
- _service->setFastClockSource(stdx::make_unique<ClockSourceMock>());
- _client = _service->makeClient("test");
- _opCtxNoop = _client->makeOperationContext();
- _opCtx = _opCtxNoop.get();
- CollatorFactoryInterface::set(_service.get(), stdx::make_unique<CollatorFactoryMock>());
+ getServiceContext()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
+ _opCtx = makeOperationContext();
+ CollatorFactoryInterface::set(getServiceContext(),
+ stdx::make_unique<CollatorFactoryMock>());
}
OperationContext* getOpCtx() {
- return _opCtx;
+ return _opCtx.get();
}
/**
@@ -155,15 +152,7 @@ public:
}
private:
- OperationContext* _opCtx;
-
- std::unique_ptr<ServiceContextNoop> _service;
-
- // Members of a class are destroyed in reverse order of declaration.
- // The UniqueClient must be destroyed before the ServiceContextNoop is destroyed.
- // The OperationContextNoop must be destroyed before the UniqueClient is destroyed.
- ServiceContext::UniqueClient _client;
- ServiceContext::UniqueOperationContext _opCtxNoop;
+ ServiceContext::UniqueOperationContext _opCtx;
};
TEST_F(SortStageTest, SortEmptyWorkingSet) {
diff --git a/src/mongo/db/free_mon/free_mon_controller_test.cpp b/src/mongo/db/free_mon/free_mon_controller_test.cpp
index 17f22101a1f..43481e870e4 100644
--- a/src/mongo/db/free_mon/free_mon_controller_test.cpp
+++ b/src/mongo/db/free_mon/free_mon_controller_test.cpp
@@ -59,7 +59,6 @@
#include "mongo/db/repl/storage_interface_impl.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_d_test_fixture.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
#include "mongo/rpc/object_check.h"
diff --git a/src/mongo/db/ftdc/SConscript b/src/mongo/db/ftdc/SConscript
index 4822907a540..6415ae347dd 100644
--- a/src/mongo/db/ftdc/SConscript
+++ b/src/mongo/db/ftdc/SConscript
@@ -96,6 +96,7 @@ env.CppUnitTest(
'varint_test.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/util/clock_source_mock',
'ftdc',
],
diff --git a/src/mongo/db/ftdc/compressor_test.cpp b/src/mongo/db/ftdc/compressor_test.cpp
index 0c01bd58040..38ae3958a7b 100644
--- a/src/mongo/db/ftdc/compressor_test.cpp
+++ b/src/mongo/db/ftdc/compressor_test.cpp
@@ -60,8 +60,10 @@ namespace mongo {
FTDCCompressor::CompressorState::kCompressorFull); \
ASSERT_TRUE(st.getValue().is_initialized());
+class FTDCCompressorTest : public FTDCTest {};
+
// Sanity check
-TEST(FTDCCompressor, TestBasic) {
+TEST_F(FTDCCompressorTest, TestBasic) {
FTDCConfig config;
FTDCCompressor c(&config);
@@ -91,7 +93,7 @@ TEST(FTDCCompressor, TestBasic) {
}
// Test strings only
-TEST(FTDCCompressor, TestStrings) {
+TEST_F(FTDCCompressorTest, TestStrings) {
FTDCConfig config;
FTDCCompressor c(&config);
@@ -180,7 +182,7 @@ private:
};
// Test various schema changes
-TEST(FTDCCompressor, TestSchemaChanges) {
+TEST_F(FTDCCompressorTest, TestSchemaChanges) {
TestTie c;
auto st = c.addSample(BSON("name"
@@ -341,7 +343,7 @@ TEST(FTDCCompressor, TestSchemaChanges) {
}
// Ensure changing between the various number formats is considered compatible
-TEST(FTDCCompressor, TestNumbersCompat) {
+TEST_F(FTDCCompressorTest, TestNumbersCompat) {
TestTie c;
auto st = c.addSample(BSON("name"
@@ -368,7 +370,7 @@ TEST(FTDCCompressor, TestNumbersCompat) {
}
// Test various date time types
-TEST(FTDCCompressor, TestDateTimeTypes) {
+TEST_F(FTDCCompressorTest, TestDateTimeTypes) {
TestTie c;
for (int i = 0; i < 10; i++) {
BSONObjBuilder builder1;
@@ -382,7 +384,7 @@ TEST(FTDCCompressor, TestDateTimeTypes) {
}
// Test all types
-TEST(FTDCCompressor, Types) {
+TEST_F(FTDCCompressorTest, Types) {
TestTie c;
auto st = c.addSample(BSON("name"
@@ -455,7 +457,7 @@ TEST(FTDCCompressor, Types) {
}
// Test a full buffer
-TEST(FTDCCompressor, TestFull) {
+TEST_F(FTDCCompressorTest, TestFull) {
// Test a large numbers of zeros, and incremental numbers in a full buffer
for (int j = 0; j < 2; j++) {
TestTie c;
@@ -509,7 +511,7 @@ BSONObj generateSample(std::random_device& rd, T generator, size_t count) {
}
// Test many metrics
-TEST(ZFTDCCompressor, TestManyMetrics) {
+TEST_F(FTDCCompressorTest, TestManyMetrics) {
std::random_device rd;
std::mt19937 gen(rd());
diff --git a/src/mongo/db/ftdc/controller_test.cpp b/src/mongo/db/ftdc/controller_test.cpp
index c307d02cca8..de88054aec9 100644
--- a/src/mongo/db/ftdc/controller_test.cpp
+++ b/src/mongo/db/ftdc/controller_test.cpp
@@ -50,6 +50,8 @@
namespace mongo {
+class FTDCControllerTest : public FTDCTest {};
+
class FTDCMetricsCollectorMockTee : public FTDCCollectorInterface {
public:
~FTDCMetricsCollectorMockTee() {
@@ -154,7 +156,7 @@ public:
};
// Test a run of the controller and the data it logs to log file
-TEST(FTDCControllerTest, TestFull) {
+TEST_F(FTDCControllerTest, TestFull) {
unittest::TempDir tempdir("metrics_testpath");
boost::filesystem::path dir(tempdir.path());
@@ -207,7 +209,7 @@ TEST(FTDCControllerTest, TestFull) {
// Test we can start and stop the controller in quick succession, make sure it succeeds without
// assert or fault
-TEST(FTDCControllerTest, TestStartStop) {
+TEST_F(FTDCControllerTest, TestStartStop) {
unittest::TempDir tempdir("metrics_testpath");
boost::filesystem::path dir(tempdir.path());
@@ -228,7 +230,7 @@ TEST(FTDCControllerTest, TestStartStop) {
// Test we can start the controller as disabled, the directory is empty, and then we can succesfully
// enable it
-TEST(FTDCControllerTest, TestStartAsDisabled) {
+TEST_F(FTDCControllerTest, TestStartAsDisabled) {
unittest::TempDir tempdir("metrics_testpath");
boost::filesystem::path dir(tempdir.path());
diff --git a/src/mongo/db/ftdc/file_manager_test.cpp b/src/mongo/db/ftdc/file_manager_test.cpp
index 027ae88af62..0a0b0367221 100644
--- a/src/mongo/db/ftdc/file_manager_test.cpp
+++ b/src/mongo/db/ftdc/file_manager_test.cpp
@@ -50,8 +50,10 @@
namespace mongo {
+class FTDCFileManagerTest : public ServiceContextTest {};
+
// Test a full buffer
-TEST(FTDCFileManagerTest, TestFull) {
+TEST_F(FTDCFileManagerTest, TestFull) {
Client* client = &cc();
FTDCConfig c;
c.maxFileSizeBytes = 300;
@@ -149,7 +151,7 @@ void ValidateInterimFileHasData(const boost::filesystem::path& dir, bool hasData
}
// Test a normal restart
-TEST(FTDCFileManagerTest, TestNormalRestart) {
+TEST_F(FTDCFileManagerTest, TestNormalRestart) {
Client* client = &cc();
FTDCConfig c;
c.maxFileSizeBytes = 1000;
@@ -219,7 +221,7 @@ TEST(FTDCFileManagerTest, TestNormalRestart) {
}
// Test a restart after a crash with a corrupt archive file
-TEST(FTDCFileManagerTest, TestCorruptCrashRestart) {
+TEST_F(FTDCFileManagerTest, TestCorruptCrashRestart) {
Client* client = &cc();
FTDCConfig c;
c.maxFileSizeBytes = 1000;
@@ -296,7 +298,7 @@ TEST(FTDCFileManagerTest, TestCorruptCrashRestart) {
}
// Test a restart with a good interim file, and validate we have all the data
-TEST(FTDCFileManagerTest, TestNormalCrashInterim) {
+TEST_F(FTDCFileManagerTest, TestNormalCrashInterim) {
Client* client = &cc();
FTDCConfig c;
c.maxSamplesPerInterimMetricChunk = 3;
diff --git a/src/mongo/db/ftdc/file_writer_test.cpp b/src/mongo/db/ftdc/file_writer_test.cpp
index f7977e2b8b3..81e3a741d24 100644
--- a/src/mongo/db/ftdc/file_writer_test.cpp
+++ b/src/mongo/db/ftdc/file_writer_test.cpp
@@ -47,8 +47,10 @@ namespace mongo {
const char* kTestFile = "metrics.test";
const char* kTestFileCopy = "metrics.test.copy";
+class FTDCFileTest : public ServiceContextTest {};
+
// File Sanity check
-TEST(FTDCFileTest, TestFileBasicMetadata) {
+TEST_F(FTDCFileTest, TestFileBasicMetadata) {
unittest::TempDir tempdir("metrics_testpath");
boost::filesystem::path p(tempdir.path());
p /= kTestFile;
@@ -99,7 +101,7 @@ TEST(FTDCFileTest, TestFileBasicMetadata) {
}
// File Sanity check
-TEST(FTDCFileTest, TestFileBasicCompress) {
+TEST_F(FTDCFileTest, TestFileBasicCompress) {
unittest::TempDir tempdir("metrics_testpath");
boost::filesystem::path p(tempdir.path());
p /= kTestFile;
@@ -208,7 +210,7 @@ private:
};
// Test various schema changes
-TEST(FTDCFileTest, TestSchemaChanges) {
+TEST_F(FTDCFileTest, TestSchemaChanges) {
FileTestTie c;
c.addSample(BSON("name"
@@ -279,7 +281,7 @@ TEST(FTDCFileTest, TestSchemaChanges) {
}
// Test a full buffer
-TEST(FTDCFileTest, TestFull) {
+TEST_F(FTDCFileTest, TestFull) {
// Test a large numbers of zeros, and incremental numbers in a full buffer
for (int j = 0; j < 2; j++) {
FileTestTie c;
@@ -318,7 +320,7 @@ TEST(FTDCFileTest, TestFull) {
}
// Test a large documents so that we cause multiple 4kb buffers to flush on Windows.
-TEST(FTDCFileTest, TestLargeDocuments) {
+TEST_F(FTDCFileTest, TestLargeDocuments) {
FileTestTie c;
for (int j = 0; j < 5; j++) {
@@ -337,7 +339,7 @@ TEST(FTDCFileTest, TestLargeDocuments) {
}
// Test a bad file
-TEST(FTDCFileTest, TestBadFile) {
+TEST_F(FTDCFileTest, TestBadFile) {
unittest::TempDir tempdir("metrics_testpath");
boost::filesystem::path p(tempdir.path());
p /= kTestFile;
diff --git a/src/mongo/db/ftdc/ftdc_test.cpp b/src/mongo/db/ftdc/ftdc_test.cpp
index 7e4020b3979..11674ea2cad 100644
--- a/src/mongo/db/ftdc/ftdc_test.cpp
+++ b/src/mongo/db/ftdc/ftdc_test.cpp
@@ -39,7 +39,6 @@
#include "mongo/db/ftdc/file_reader.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/clock_source.h"
@@ -111,17 +110,11 @@ void createDirectoryClean(const boost::filesystem::path& dir) {
boost::filesystem::create_directory(dir);
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(FTDCTestInit, ("ThreadNameInitializer"))
-(InitializerContext* context) {
- setGlobalServiceContext(stdx::make_unique<ServiceContextNoop>());
-
- getGlobalServiceContext()->setFastClockSource(stdx::make_unique<ClockSourceMock>());
- getGlobalServiceContext()->setPreciseClockSource(stdx::make_unique<ClockSourceMock>());
- getGlobalServiceContext()->setTickSource(stdx::make_unique<TickSourceMock>());
-
- Client::initThreadIfNotAlready("UnitTest");
-
- return Status::OK();
+FTDCTest::FTDCTest() {
+ auto service = getServiceContext();
+ service->setFastClockSource(stdx::make_unique<ClockSourceMock>());
+ service->setPreciseClockSource(stdx::make_unique<ClockSourceMock>());
+ service->setTickSource(stdx::make_unique<TickSourceMock>());
}
} // namespace mongo
diff --git a/src/mongo/db/ftdc/ftdc_test.h b/src/mongo/db/ftdc/ftdc_test.h
index afbca103b4f..fb9ada44f2f 100644
--- a/src/mongo/db/ftdc/ftdc_test.h
+++ b/src/mongo/db/ftdc/ftdc_test.h
@@ -30,9 +30,15 @@
#include <vector>
#include "mongo/db/jsobj.h"
+#include "mongo/db/service_context_test_fixture.h"
namespace mongo {
+class FTDCTest : public ServiceContextTest {
+public:
+ FTDCTest();
+};
+
/**
* Validate the documents in a file match the specified vector.
*
diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp
index d45f66189f1..e70494335ff 100644
--- a/src/mongo/db/index_builder.cpp
+++ b/src/mongo/db/index_builder.cpp
@@ -119,6 +119,7 @@ std::string IndexBuilder::name() const {
void IndexBuilder::run() {
Client::initThread(name().c_str());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
LOG(2) << "IndexBuilder building index " << _index;
auto opCtx = cc().makeOperationContext();
diff --git a/src/mongo/db/logical_session_cache_test.cpp b/src/mongo/db/logical_session_cache_test.cpp
index d69b0befd8c..b8ec36827fe 100644
--- a/src/mongo/db/logical_session_cache_test.cpp
+++ b/src/mongo/db/logical_session_cache_test.cpp
@@ -39,8 +39,9 @@
#include "mongo/db/logical_session_cache.h"
#include "mongo/db/logical_session_id.h"
#include "mongo/db/logical_session_id_helpers.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/service_liaison_mock.h"
#include "mongo/db/sessions_collection_mock.h"
#include "mongo/stdx/future.h"
@@ -62,35 +63,25 @@ using unittest::EnsureFCV;
* Test fixture that sets up a session cache attached to a mock service liaison
* and mock sessions collection implementation.
*/
-class LogicalSessionCacheTest : public unittest::Test {
+class LogicalSessionCacheTest : public ServiceContextTest {
public:
LogicalSessionCacheTest()
: _service(std::make_shared<MockServiceLiaisonImpl>()),
- _sessions(std::make_shared<MockSessionsCollectionImpl>()) {}
+ _sessions(std::make_shared<MockSessionsCollectionImpl>()) {
- void setUp() override {
- AuthorizationManager::set(&serviceContext, AuthorizationManager::create());
-
- auto client = serviceContext.makeClient("testClient");
- _opCtx = client->makeOperationContext();
- _client = client.get();
- Client::setCurrent(std::move(client));
+ AuthorizationManager::set(getServiceContext(), AuthorizationManager::create());
+ // Re-initialize the client after setting the AuthorizationManager to get an
+ // AuthorizationSession.
+ Client::releaseCurrent();
+ Client::initThread(getThreadName());
+ _opCtx = makeOperationContext();
auto mockService = stdx::make_unique<MockServiceLiaison>(_service);
auto mockSessions = stdx::make_unique<MockSessionsCollection>(_sessions);
_cache = stdx::make_unique<LogicalSessionCacheImpl>(
std::move(mockService), std::move(mockSessions), nullptr);
}
- void tearDown() override {
- if (_opCtx) {
- _opCtx.reset();
- }
-
- _service->join();
- auto client = Client::releaseCurrent();
- }
-
void waitUntilRefreshScheduled() {
while (service()->jobs() < 2) {
sleepmillis(10);
@@ -110,7 +101,7 @@ public:
}
void setOpCtx() {
- _opCtx = client()->makeOperationContext();
+ _opCtx = getClient()->makeOperationContext();
}
void clearOpCtx() {
@@ -121,20 +112,13 @@ public:
return _opCtx.get();
}
- Client* client() {
- return _client;
- }
-
private:
- ServiceContextNoop serviceContext;
ServiceContext::UniqueOperationContext _opCtx;
std::shared_ptr<MockServiceLiaisonImpl> _service;
std::shared_ptr<MockSessionsCollectionImpl> _sessions;
std::unique_ptr<LogicalSessionCache> _cache;
-
- Client* _client;
};
// Test that the getFromCache method does not make calls to the sessions collection
@@ -205,7 +189,7 @@ TEST_F(LogicalSessionCacheTest, StartSession) {
// Do refresh, cached records should get flushed to collection.
clearOpCtx();
- ASSERT(cache()->refreshNow(client()).isOK());
+ ASSERT(cache()->refreshNow(getClient()).isOK());
ASSERT(sessions()->has(lsid));
// Try to start the same session again, should succeed.
@@ -237,7 +221,7 @@ TEST_F(LogicalSessionCacheTest, BasicSessionExpiration) {
service()->fastForward(Milliseconds(kSessionTimeout.count() + 5));
// Check that it is no longer in the cache
- ASSERT(cache()->refreshNow(client()).isOK());
+ ASSERT(cache()->refreshNow(getClient()).isOK());
res = cache()->promote(record.getId());
// TODO SERVER-29709
// ASSERT(!res.isOK());
@@ -260,7 +244,7 @@ TEST_F(LogicalSessionCacheTest, ManySignedLsidsInCacheRefresh) {
// Force a refresh
clearOpCtx();
service()->fastForward(kForceRefresh);
- ASSERT(cache()->refreshNow(client()).isOK());
+ ASSERT(cache()->refreshNow(getClient()).isOK());
}
//
@@ -378,7 +362,7 @@ TEST_F(LogicalSessionCacheTest, RefreshMatrixSessionState) {
// Force a refresh
clearOpCtx();
service()->fastForward(kForceRefresh);
- ASSERT(cache()->refreshNow(client()).isOK());
+ ASSERT(cache()->refreshNow(getClient()).isOK());
for (int i = 0; i < 32; i++) {
std::stringstream failText;
diff --git a/src/mongo/db/logical_session_id_test.cpp b/src/mongo/db/logical_session_id_test.cpp
index 6d84ccfdbab..128a793b12b 100644
--- a/src/mongo/db/logical_session_id_test.cpp
+++ b/src/mongo/db/logical_session_id_test.cpp
@@ -40,7 +40,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_impl.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/auth/authorization_session_for_test.h"
#include "mongo/db/auth/authz_manager_external_state_mock.h"
#include "mongo/db/auth/authz_session_external_state_mock.h"
#include "mongo/db/auth/sasl_options.h"
@@ -50,8 +49,9 @@
#include "mongo/db/logical_session_cache.h"
#include "mongo/db/logical_session_cache_impl.h"
#include "mongo/db/logical_session_id_helpers.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/service_liaison_mock.h"
#include "mongo/db/sessions_collection_mock.h"
#include "mongo/transport/session.h"
@@ -61,42 +61,29 @@
namespace mongo {
namespace {
-class LogicalSessionIdTest : public ::mongo::unittest::Test {
+class LogicalSessionIdTest : public ServiceContextTest {
public:
AuthzManagerExternalStateMock* managerState;
transport::TransportLayerMock transportLayer;
- transport::SessionHandle session;
- ServiceContextNoop serviceContext;
- ServiceContext::UniqueClient client;
+ transport::SessionHandle session = transportLayer.createSession();
ServiceContext::UniqueOperationContext _opCtx;
- AuthzSessionExternalStateMock* sessionState;
- AuthorizationManager* authzManager;
- AuthorizationSessionForTest* authzSession;
+ AuthorizationSession* authzSession;
- void setUp() {
- session = transportLayer.createSession();
- client = serviceContext.makeClient("testClient", session);
+ LogicalSessionIdTest() {
RestrictionEnvironment::set(
session, std::make_unique<RestrictionEnvironment>(SockAddr(), SockAddr()));
- _opCtx = client->makeOperationContext();
auto localManagerState = std::make_unique<AuthzManagerExternalStateMock>();
managerState = localManagerState.get();
managerState->setAuthzVersion(AuthorizationManager::schemaVersion26Final);
- auto uniqueAuthzManager = std::make_unique<AuthorizationManagerImpl>(
+ auto authzManager = std::make_unique<AuthorizationManagerImpl>(
std::move(localManagerState),
AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{});
- authzManager = uniqueAuthzManager.get();
- AuthorizationManager::set(&serviceContext, std::move(uniqueAuthzManager));
- auto localSessionState = std::make_unique<AuthzSessionExternalStateMock>(authzManager);
- sessionState = localSessionState.get();
-
- auto localauthzSession = std::make_unique<AuthorizationSessionForTest>(
- std::move(localSessionState),
- AuthorizationSessionImpl::InstallMockForTestingOrAuthImpl{});
- authzSession = localauthzSession.get();
-
- AuthorizationSession::set(client.get(), std::move(localauthzSession));
authzManager->setAuthEnabled(true);
+ AuthorizationManager::set(getServiceContext(), std::move(authzManager));
+ Client::releaseCurrent();
+ Client::initThread(getThreadName(), session);
+ authzSession = AuthorizationSession::get(getClient());
+ _opCtx = makeOperationContext();
auto localServiceLiaison =
std::make_unique<MockServiceLiaison>(std::make_shared<MockServiceLiaisonImpl>());
@@ -106,7 +93,7 @@ public:
auto localLogicalSessionCache = std::make_unique<LogicalSessionCacheImpl>(
std::move(localServiceLiaison), std::move(localSessionsCollection), nullptr);
- LogicalSessionCache::set(&serviceContext, std::move(localLogicalSessionCache));
+ LogicalSessionCache::set(getServiceContext(), std::move(localLogicalSessionCache));
}
User* addSimpleUser(UserName un) {
diff --git a/src/mongo/db/operation_context_test.cpp b/src/mongo/db/operation_context_test.cpp
index f3e25164201..b779102b702 100644
--- a/src/mongo/db/operation_context_test.cpp
+++ b/src/mongo/db/operation_context_test.cpp
@@ -36,7 +36,6 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/operation_context_group.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/stdx/future.h"
#include "mongo/stdx/memory.h"
#include "mongo/stdx/thread.h"
@@ -77,7 +76,7 @@ std::ostream& operator<<(std::ostream& os, stdx::future_status futureStatus) {
}
TEST(OperationContextTest, NoSessionIdNoTransactionNumber) {
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest");
auto opCtx = client->makeOperationContext();
@@ -86,7 +85,7 @@ TEST(OperationContextTest, NoSessionIdNoTransactionNumber) {
}
TEST(OperationContextTest, SessionIdNoTransactionNumber) {
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest");
auto opCtx = client->makeOperationContext();
@@ -100,7 +99,7 @@ TEST(OperationContextTest, SessionIdNoTransactionNumber) {
}
TEST(OperationContextTest, SessionIdAndTransactionNumber) {
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest");
auto opCtx = client->makeOperationContext();
@@ -113,7 +112,7 @@ TEST(OperationContextTest, SessionIdAndTransactionNumber) {
}
DEATH_TEST(OperationContextTest, SettingSessionIdMoreThanOnceShouldCrash, "invariant") {
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest");
auto opCtx = client->makeOperationContext();
@@ -122,7 +121,7 @@ DEATH_TEST(OperationContextTest, SettingSessionIdMoreThanOnceShouldCrash, "invar
}
DEATH_TEST(OperationContextTest, SettingTransactionNumberMoreThanOnceShouldCrash, "invariant") {
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest");
auto opCtx = client->makeOperationContext();
@@ -133,7 +132,7 @@ DEATH_TEST(OperationContextTest, SettingTransactionNumberMoreThanOnceShouldCrash
}
DEATH_TEST(OperationContextTest, SettingTransactionNumberWithoutSessionIdShouldCrash, "invariant") {
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest");
auto opCtx = client->makeOperationContext();
@@ -144,12 +143,12 @@ TEST(OperationContextTest, OpCtxGroup) {
OperationContextGroup group1;
ASSERT_TRUE(group1.isEmpty());
{
- auto serviceCtx1 = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx1 = ServiceContext::make();
auto client1 = serviceCtx1->makeClient("OperationContextTest1");
auto opCtx1 = group1.makeOperationContext(*client1);
ASSERT_FALSE(group1.isEmpty());
- auto serviceCtx2 = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx2 = ServiceContext::make();
auto client2 = serviceCtx2->makeClient("OperationContextTest2");
{
auto opCtx2 = group1.makeOperationContext(*client2);
@@ -170,7 +169,7 @@ TEST(OperationContextTest, OpCtxGroup) {
OperationContextGroup group2;
{
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client = serviceCtx->makeClient("OperationContextTest1");
auto opCtx2 = group2.adopt(client->makeOperationContext());
ASSERT_FALSE(group2.isEmpty());
@@ -185,7 +184,7 @@ TEST(OperationContextTest, OpCtxGroup) {
OperationContextGroup group3;
OperationContextGroup group4;
{
- auto serviceCtx = stdx::make_unique<ServiceContextNoop>();
+ auto serviceCtx = ServiceContext::make();
auto client3 = serviceCtx->makeClient("OperationContextTest3");
auto opCtx3 = group3.makeOperationContext(*client3);
auto p3 = opCtx3.opCtx();
@@ -204,7 +203,7 @@ TEST(OperationContextTest, OpCtxGroup) {
class OperationDeadlineTests : public unittest::Test {
public:
void setUp() {
- service = stdx::make_unique<ServiceContextNoop>();
+ service = ServiceContext::make();
service->setFastClockSource(stdx::make_unique<SharedClockSourceAdapter>(mockClock));
service->setPreciseClockSource(stdx::make_unique<SharedClockSourceAdapter>(mockClock));
service->setTickSource(stdx::make_unique<TickSourceMock>());
@@ -212,7 +211,7 @@ public:
}
const std::shared_ptr<ClockSourceMock> mockClock = std::make_shared<ClockSourceMock>();
- std::unique_ptr<ServiceContext> service;
+ ServiceContext::UniqueServiceContext service;
ServiceContext::UniqueClient client;
};
diff --git a/src/mongo/db/ops/SConscript b/src/mongo/db/ops/SConscript
index 5de783b5bac..b7428b32608 100644
--- a/src/mongo/db/ops/SConscript
+++ b/src/mongo/db/ops/SConscript
@@ -60,6 +60,7 @@ env.CppIntegrationTest(
source='write_ops_document_stream_integration_test.cpp',
LIBDEPS=[
'$BUILD_DIR/mongo/client/clientdriver_network',
+ '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
'$BUILD_DIR/mongo/util/version_impl',
],
)
diff --git a/src/mongo/db/pipeline/SConscript b/src/mongo/db/pipeline/SConscript
index 2508af7eda6..fbdc846e838 100644
--- a/src/mongo/db/pipeline/SConscript
+++ b/src/mongo/db/pipeline/SConscript
@@ -73,7 +73,6 @@ env.CppUnitTest(
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/query/collation/collator_interface_mock',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'document_value',
'document_value_test_util',
],
@@ -242,7 +241,7 @@ env.CppUnitTest(
source='document_source_facet_test.cpp',
LIBDEPS=[
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/s/is_mongos',
'pipeline',
'document_source_mock',
@@ -354,7 +353,6 @@ env.CppUnitTest(
source='tee_buffer_test.cpp',
LIBDEPS=[
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/s/is_mongos',
'document_source_mock',
'document_value_test_util',
@@ -370,6 +368,7 @@ env.CppUnitTest(
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/query/query_test_service_context',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'accumulator',
'document_value_test_util',
'expression',
@@ -397,8 +396,7 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/query/collation/collator_interface_mock',
'$BUILD_DIR/mongo/db/repl/replmocks',
- '$BUILD_DIR/mongo/db/service_context',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/s/is_mongos',
'document_value_test_util',
'document_source_mock',
@@ -414,7 +412,6 @@ env.CppUnitTest(
LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/query/collation/collator_interface_mock',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'document_value',
]
)
@@ -504,7 +501,6 @@ env.CppUnitTest(
target='resume_token_test',
source='resume_token_test.cpp',
LIBDEPS=[
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/auth/authmocks',
'document_sources_idl',
],
diff --git a/src/mongo/db/pipeline/aggregation_context_fixture.h b/src/mongo/db/pipeline/aggregation_context_fixture.h
index b2833c5a70b..2fe53f43822 100644
--- a/src/mongo/db/pipeline/aggregation_context_fixture.h
+++ b/src/mongo/db/pipeline/aggregation_context_fixture.h
@@ -32,6 +32,7 @@
#include <memory>
#include "mongo/db/pipeline/expression_context_for_test.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
@@ -40,18 +41,25 @@ namespace mongo {
/**
* Test fixture which provides an ExpressionContext for use in testing.
*/
-class AggregationContextFixture : public unittest::Test {
+class AggregationContextFixture : public ServiceContextTest {
public:
AggregationContextFixture()
: AggregationContextFixture(NamespaceString("unittests.pipeline_test")) {}
- AggregationContextFixture(NamespaceString nss) : _expCtx(new ExpressionContextForTest(nss)) {}
+ AggregationContextFixture(NamespaceString nss) {
+ TimeZoneDatabase::set(getServiceContext(), std::make_unique<TimeZoneDatabase>());
+ // Must instantiate ExpressionContext _after_ setting the TZ database on the service
+ // context.
+ _expCtx = new ExpressionContext(_opCtx.get(), nullptr);
+ _expCtx->ns = std::move(nss);
+ }
- boost::intrusive_ptr<ExpressionContextForTest> getExpCtx() {
+ boost::intrusive_ptr<ExpressionContext> getExpCtx() {
return _expCtx.get();
}
private:
- boost::intrusive_ptr<ExpressionContextForTest> _expCtx;
+ ServiceContext::UniqueOperationContext _opCtx = makeOperationContext();
+ boost::intrusive_ptr<ExpressionContext> _expCtx;
};
} // namespace mongo
diff --git a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
index 05a62606bb6..b3079f0573f 100644
--- a/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
+++ b/src/mongo/db/pipeline/document_source_graph_lookup_test.cpp
@@ -100,7 +100,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
std::deque<DocumentSource::GetNextResult> fromContents{Document{{"to", 0}}};
NamespaceString fromNs("test", "graph_lookup");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto graphLookupStage =
DocumentSourceGraphLookUp::create(expCtx,
@@ -128,7 +128,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
Document{{"_id", "a"_sd}, {"to", 0}, {"from", 1}}, Document{{"to", 1}}};
NamespaceString fromNs("test", "graph_lookup");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto graphLookupStage =
DocumentSourceGraphLookUp::create(expCtx,
@@ -156,7 +156,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
std::deque<DocumentSource::GetNextResult> fromContents{Document{{"to", 0}}};
NamespaceString fromNs("test", "graph_lookup");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto unwindStage = DocumentSourceUnwind::create(expCtx, "results", false, boost::none);
auto graphLookupStage =
@@ -199,7 +199,7 @@ TEST_F(DocumentSourceGraphLookUpTest,
Document(to1), Document(to2), Document(to0from1), Document(to0from2)};
NamespaceString fromNs("test", "graph_lookup");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto graphLookupStage =
DocumentSourceGraphLookUp::create(expCtx,
@@ -263,7 +263,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldPropagatePauses) {
Document{{"_id", "a"_sd}, {"to", 0}, {"from", 1}}, Document{{"_id", "b"_sd}, {"to", 1}}};
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto graphLookupStage =
DocumentSourceGraphLookUp::create(expCtx,
@@ -329,7 +329,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldPropagatePausesWhileUnwinding) {
Document{{"_id", "a"_sd}, {"to", 0}, {"from", 1}}, Document{{"_id", "b"_sd}, {"to", 1}}};
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
const bool preserveNullAndEmptyArrays = false;
@@ -392,7 +392,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldPropagatePausesWhileUnwinding) {
TEST_F(DocumentSourceGraphLookUpTest, GraphLookupShouldReportAsFieldIsModified) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface =
std::make_shared<MockMongoInterface>(std::deque<DocumentSource::GetNextResult>{});
auto graphLookupStage =
@@ -416,7 +416,7 @@ TEST_F(DocumentSourceGraphLookUpTest, GraphLookupShouldReportAsFieldIsModified)
TEST_F(DocumentSourceGraphLookUpTest, GraphLookupShouldReportFieldsModifiedByAbsorbedUnwind) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface =
std::make_shared<MockMongoInterface>(std::deque<DocumentSource::GetNextResult>{});
auto unwindStage =
@@ -446,7 +446,7 @@ TEST_F(DocumentSourceGraphLookUpTest, GraphLookupWithComparisonExpressionForStar
auto inputMock = DocumentSourceMock::create(Document({{"_id", 0}, {"a", 1}, {"b", 2}}));
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
std::deque<DocumentSource::GetNextResult> fromContents{Document{{"_id", 0}, {"to", true}},
Document{{"_id", 1}, {"to", false}}};
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
@@ -511,7 +511,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldExpandArraysAtEndOfConnectFromField)
Document(sinkDoc)};
NamespaceString fromNs("test", "graph_lookup");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto graphLookupStage =
DocumentSourceGraphLookUp::create(expCtx,
@@ -583,7 +583,7 @@ TEST_F(DocumentSourceGraphLookUpTest, ShouldNotExpandArraysWithinArraysAtEndOfCo
Document(startDoc), Document(target1), Document(target2), Document(soloDoc)};
NamespaceString fromNs("test", "graph_lookup");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->mongoProcessInterface = std::make_shared<MockMongoInterface>(std::move(fromContents));
auto graphLookupStage =
DocumentSourceGraphLookUp::create(expCtx,
diff --git a/src/mongo/db/pipeline/document_source_group_test.cpp b/src/mongo/db/pipeline/document_source_group_test.cpp
index de99452f3d7..44210e4a579 100644
--- a/src/mongo/db/pipeline/document_source_group_test.cpp
+++ b/src/mongo/db/pipeline/document_source_group_test.cpp
@@ -196,11 +196,10 @@ BSONObj toBson(const intrusive_ptr<DocumentSource>& source) {
return arr[0].getDocument().toBson();
}
-class Base {
+class Base : public ServiceContextTest {
public:
Base()
- : _queryServiceContext(stdx::make_unique<QueryTestServiceContext>()),
- _opCtx(_queryServiceContext->makeOperationContext()),
+ : _opCtx(makeOperationContext()),
_ctx(new ExpressionContextForTest(_opCtx.get(),
AggregationRequest(NamespaceString(ns), {}))),
_tempDir("DocumentSourceGroupTest") {}
@@ -257,7 +256,7 @@ private:
class ParseErrorBase : public Base {
public:
virtual ~ParseErrorBase() {}
- void run() {
+ void _doTest() final {
ASSERT_THROWS(createGroup(spec()), AssertionException);
}
@@ -268,7 +267,7 @@ protected:
class ExpressionBase : public Base {
public:
virtual ~ExpressionBase() {}
- void run() {
+ void _doTest() final {
createGroup(spec());
auto source = DocumentSourceMock::create(Document(doc()));
group()->setSource(source.get());
@@ -298,7 +297,7 @@ class IdConstantBase : public ExpressionBase {
/** $group spec is not an object. */
class NonObject : public Base {
public:
- void run() {
+ void _doTest() final {
BSONObj spec = BSON("$group"
<< "foo");
BSONElement specElement = spec.firstElement();
@@ -500,7 +499,7 @@ typedef map<Value, Document, ValueCmp> IdMap;
class CheckResultsBase : public Base {
public:
virtual ~CheckResultsBase() {}
- void run() {
+ void _doTest() {
runSharded(false);
runSharded(true);
}
@@ -726,7 +725,7 @@ class UndefinedAccumulatorValue : public CheckResultsBase {
/** Simulate merging sharded results in the router. */
class RouterMerger : public CheckResultsBase {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{_id:0,list:[1,2]}",
"{_id:1,list:[3,4]}",
"{_id:0,list:[10,20]}",
@@ -755,7 +754,7 @@ private:
/** Dependant field paths. */
class Dependencies : public Base {
public:
- void run() {
+ void _doTest() final {
createGroup(fromjson("{_id:'$x',a:{$sum:'$y.z'},b:{$avg:{$add:['$u','$v']}}}"));
DepsTracker dependencies;
ASSERT_EQUALS(DocumentSource::EXHAUSTIVE_ALL, group()->getDependencies(&dependencies));
@@ -773,7 +772,7 @@ public:
class StreamingOptimization : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 0}", "{a: 0}", "{a: 1}", "{a: 1}"});
source->sorts = {BSON("a" << 1)};
@@ -808,7 +807,7 @@ public:
class StreamingWithMultipleIdFields : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create(
{"{a: 1, b: 2}", "{a: 1, b: 2}", "{a: 1, b: 1}", "{a: 2, b: 1}", "{a: 2, b: 1}"});
source->sorts = {BSON("a" << 1 << "b" << -1)};
@@ -848,7 +847,7 @@ public:
class StreamingWithMultipleLevels : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create(
{"{a: {b: {c: 3}}, d: 1}", "{a: {b: {c: 1}}, d: 2}", "{a: {b: {c: 1}}, d: 0}"});
source->sorts = {BSON("a.b.c" << -1 << "a.b.d" << 1 << "d" << 1)};
@@ -884,7 +883,7 @@ public:
class StreamingWithFieldRepeated : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create(
{"{a: 1, b: 1}", "{a: 1, b: 1}", "{a: 2, b: 1}", "{a: 2, b: 3}"});
source->sorts = {BSON("a" << 1 << "b" << 1)};
@@ -919,7 +918,7 @@ public:
class StreamingWithConstantAndFieldPath : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create(
{"{a: 5, b: 1}", "{a: 5, b: 2}", "{a: 3, b: 1}", "{a: 1, b: 1}", "{a: 1, b: 1}"});
source->sorts = {BSON("a" << -1 << "b" << 1)};
@@ -953,7 +952,7 @@ public:
class StreamingWithRootSubfield : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 1}", "{a: 2}", "{a: 3}"});
source->sorts = {BSON("a" << 1)};
@@ -973,7 +972,7 @@ public:
class StreamingWithConstant : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 1}", "{a: 2}", "{a: 3}"});
source->sorts = {BSON("$a" << 1)};
@@ -990,7 +989,7 @@ public:
class StreamingWithEmptyId : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 1}", "{a: 2}", "{a: 3}"});
source->sorts = {BSON("$a" << 1)};
@@ -1007,7 +1006,7 @@ public:
class NoOptimizationIfMissingDoubleSort : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 1}", "{a: 2}", "{a: 3}"});
source->sorts = {BSON("a" << 1)};
@@ -1034,7 +1033,7 @@ public:
class NoOptimizationWithRawRoot : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 1}", "{a: 2}", "{a: 3}"});
source->sorts = {BSON("a" << 1)};
@@ -1061,7 +1060,7 @@ public:
class NoOptimizationIfUsingExpressions : public Base {
public:
- void run() {
+ void _doTest() final {
auto source = DocumentSourceMock::create({"{a: 1, b: 1}", "{a: 2, b: 2}", "{a: 3, b: 1}"});
source->sorts = {BSON("a" << 1 << "b" << 1)};
@@ -1100,11 +1099,11 @@ class StringConstantIdAndAccumulatorExpressions : public CheckResultsBase {
/** An array constant passed to an accumulator. */
class ArrayConstantAccumulatorExpression : public CheckResultsBase {
public:
- void run() {
+ void _doTest() final {
// A parse exception is thrown when a raw array is provided to an accumulator.
ASSERT_THROWS(createGroup(fromjson("{_id:1,a:{$push:[4,5,6]}}")), AssertionException);
// Run standard base tests.
- CheckResultsBase::run();
+ CheckResultsBase::_doTest();
}
deque<DocumentSource::GetNextResult> inputData() {
return {Document()};
diff --git a/src/mongo/db/pipeline/document_source_lookup_test.cpp b/src/mongo/db/pipeline/document_source_lookup_test.cpp
index 3c27f9a90ab..00c0baeecdb 100644
--- a/src/mongo/db/pipeline/document_source_lookup_test.cpp
+++ b/src/mongo/db/pipeline/document_source_lookup_test.cpp
@@ -85,7 +85,7 @@ public:
TEST_F(DocumentSourceLookUpTest, PreservesParentPipelineLetVariables) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto varId = expCtx->variablesParseState.defineVariable("foo");
expCtx->variables.setValue(varId, Value(123));
@@ -109,7 +109,7 @@ TEST_F(DocumentSourceLookUpTest, PreservesParentPipelineLetVariables) {
TEST_F(DocumentSourceLookUpTest, ShouldTruncateOutputSortOnAsField) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "a");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
intrusive_ptr<DocumentSourceMock> source = DocumentSourceMock::create();
source->sorts = {BSON("a" << 1 << "d.e" << 1 << "c" << 1)};
@@ -132,7 +132,7 @@ TEST_F(DocumentSourceLookUpTest, ShouldTruncateOutputSortOnAsField) {
TEST_F(DocumentSourceLookUpTest, ShouldTruncateOutputSortOnSuffixOfAsField) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "a");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
intrusive_ptr<DocumentSourceMock> source = DocumentSourceMock::create();
source->sorts = {BSON("a" << 1 << "d.e" << 1 << "c" << 1)};
@@ -155,7 +155,7 @@ TEST_F(DocumentSourceLookUpTest, ShouldTruncateOutputSortOnSuffixOfAsField) {
TEST_F(DocumentSourceLookUpTest, AcceptsPipelineSyntax) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto docSource = DocumentSourceLookUp::createFromBson(
BSON("$lookup" << BSON("from"
@@ -173,7 +173,7 @@ TEST_F(DocumentSourceLookUpTest, AcceptsPipelineSyntax) {
TEST_F(DocumentSourceLookUpTest, AcceptsPipelineWithLetSyntax) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto docSource = DocumentSourceLookUp::createFromBson(
BSON("$lookup" << BSON("from"
@@ -225,7 +225,7 @@ TEST_F(DocumentSourceLookUpTest, LiteParsedDocumentSourceLookupContainsExpectedN
TEST_F(DocumentSourceLookUpTest, RejectLookupWhenDepthLimitIsExceeded) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
expCtx->subPipelineDepth = DocumentSourceLookUp::kMaxSubPipelineDepth;
@@ -245,7 +245,7 @@ TEST_F(DocumentSourceLookUpTest, RejectLookupWhenDepthLimitIsExceeded) {
TEST_F(ReplDocumentSourceLookUpTest, RejectsPipelineWithChangeStreamStage) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Verify that attempting to create a $lookup pipeline containing a $changeStream stage fails.
ASSERT_THROWS_CODE(
@@ -260,7 +260,7 @@ TEST_F(ReplDocumentSourceLookUpTest, RejectsPipelineWithChangeStreamStage) {
TEST_F(ReplDocumentSourceLookUpTest, RejectsSubPipelineWithChangeStreamStage) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Verify that attempting to create a sub-$lookup pipeline containing a $changeStream stage
// fails at parse time, even if the outer pipeline does not have a $changeStream stage.
@@ -277,7 +277,7 @@ TEST_F(ReplDocumentSourceLookUpTest, RejectsSubPipelineWithChangeStreamStage) {
TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenPipelineIsSpecified) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
try {
auto lookupStage = DocumentSourceLookUp::createFromBson(
@@ -306,7 +306,7 @@ TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenPipelineIsSpec
TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenLetIsSpecified) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
ASSERT_THROWS_CODE(DocumentSourceLookUp::createFromBson(BSON("$lookup" << BSON("from"
<< "coll"
@@ -328,7 +328,7 @@ TEST_F(DocumentSourceLookUpTest, RejectsLocalFieldForeignFieldWhenLetIsSpecified
TEST_F(DocumentSourceLookUpTest, RejectsInvalidLetVariableName) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
ASSERT_THROWS_CODE(DocumentSourceLookUp::createFromBson(
BSON("$lookup" << BSON("from"
@@ -379,7 +379,7 @@ TEST_F(DocumentSourceLookUpTest, RejectsInvalidLetVariableName) {
TEST_F(DocumentSourceLookUpTest, ShouldBeAbleToReParseSerializedStage) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto lookupStage = DocumentSourceLookUp::createFromBson(
BSON("$lookup" << BSON("from"
@@ -540,7 +540,7 @@ private:
TEST_F(DocumentSourceLookUpTest, ShouldPropagatePauses) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Set up the $lookup stage.
auto lookupSpec = Document{{"$lookup",
@@ -591,7 +591,7 @@ TEST_F(DocumentSourceLookUpTest, ShouldPropagatePauses) {
TEST_F(DocumentSourceLookUpTest, ShouldPropagatePausesWhileUnwinding) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Set up the $lookup stage.
auto lookupSpec = Document{{"$lookup",
@@ -644,7 +644,7 @@ TEST_F(DocumentSourceLookUpTest, ShouldPropagatePausesWhileUnwinding) {
TEST_F(DocumentSourceLookUpTest, LookupReportsAsFieldIsModified) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Set up the $lookup stage.
auto lookupSpec = Document{{"$lookup",
@@ -666,7 +666,7 @@ TEST_F(DocumentSourceLookUpTest, LookupReportsAsFieldIsModified) {
TEST_F(DocumentSourceLookUpTest, LookupReportsFieldsModifiedByAbsorbedUnwind) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "foreign");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Set up the $lookup stage.
auto lookupSpec = Document{{"$lookup",
@@ -699,7 +699,7 @@ BSONObj sequentialCacheStageObj(const StringData status = "kBuilding"_sd,
TEST_F(DocumentSourceLookUpTest, ShouldCacheNonCorrelatedSubPipelinePrefix) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto docSource = DocumentSourceLookUp::createFromBson(
fromjson("{$lookup: {let: {var1: '$_id'}, pipeline: [{$match: {x:1}}, {$sort: {x: 1}}, "
@@ -728,7 +728,7 @@ TEST_F(DocumentSourceLookUpTest,
ShouldDiscoverVariablesReferencedInFacetPipelineAfterAnExhaustiveAllStage) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// In the $facet stage here, the correlated $match stage comes after a $group stage which
// returns EXHAUSTIVE_ALL for its dependencies. Verify that we continue enumerating the $facet
@@ -763,7 +763,7 @@ TEST_F(DocumentSourceLookUpTest,
TEST_F(DocumentSourceLookUpTest, ExprEmbeddedInMatchExpressionShouldBeOptimized) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// This pipeline includes a $match stage that itself includes a $expr expression.
auto docSource = DocumentSourceLookUp::createFromBson(
@@ -802,7 +802,7 @@ TEST_F(DocumentSourceLookUpTest,
ShouldIgnoreLocalVariablesShadowingLetVariablesWhenFindingNonCorrelatedPrefix) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// The $project stage defines a local variable with the same name as the $lookup 'let' variable.
// Verify that the $project is identified as non-correlated and the cache is placed after it.
@@ -836,7 +836,7 @@ TEST_F(DocumentSourceLookUpTest,
TEST_F(DocumentSourceLookUpTest, ShouldInsertCacheBeforeCorrelatedNestedLookup) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Create a $lookup stage whose pipeline contains nested $lookups. The third-level $lookup
// refers to a 'let' variable defined in the top-level $lookup. Verify that the second-level
@@ -873,7 +873,7 @@ TEST_F(DocumentSourceLookUpTest,
ShouldIgnoreNestedLookupLetVariablesShadowingOuterLookupLetVariablesWhenFindingPrefix) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// The nested $lookup stage defines a 'let' variable with the same name as the top-level 'let'.
// Verify the nested $lookup is identified as non-correlated and the cache is placed after it.
@@ -907,7 +907,7 @@ TEST_F(DocumentSourceLookUpTest,
TEST_F(DocumentSourceLookUpTest, ShouldCacheEntirePipelineIfNonCorrelated) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto docSource = DocumentSourceLookUp::createFromBson(
fromjson("{$lookup: {let: {}, pipeline: [{$match: {x:1}}, {$sort: {x: 1}}, {$lookup: "
@@ -940,7 +940,7 @@ TEST_F(DocumentSourceLookUpTest,
ShouldReplaceNonCorrelatedPrefixWithCacheAfterFirstSubPipelineIteration) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto docSource = DocumentSourceLookUp::createFromBson(
fromjson(
@@ -1014,7 +1014,7 @@ TEST_F(DocumentSourceLookUpTest,
ShouldAbandonCacheIfMaxSizeIsExceededAfterFirstSubPipelineIteration) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
// Ensure the cache is abandoned after the first iteration by setting its max size to 0.
size_t maxCacheSizeBytes = 0;
@@ -1079,7 +1079,7 @@ TEST_F(DocumentSourceLookUpTest,
TEST_F(DocumentSourceLookUpTest, ShouldNotCacheIfCorrelatedStageIsAbsorbedIntoPlanExecutor) {
auto expCtx = getExpCtx();
NamespaceString fromNs("test", "coll");
- expCtx->setResolvedNamespace(fromNs, {fromNs, std::vector<BSONObj>{}});
+ expCtx->setResolvedNamespace_forTest(fromNs, {fromNs, std::vector<BSONObj>{}});
auto docSource = DocumentSourceLookUp::createFromBson(
fromjson("{$lookup: {let: {var1: '$_id'}, pipeline: [{$match: {$expr: { $gte: ['$x', "
diff --git a/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp b/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp
index 3614324d27d..902063bd233 100644
--- a/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp
+++ b/src/mongo/db/pipeline/document_source_merge_cursors_test.cpp
@@ -37,7 +37,7 @@
#include "mongo/db/pipeline/document_source_limit.h"
#include "mongo/db/pipeline/document_source_sort.h"
#include "mongo/db/pipeline/document_value_test_util.h"
-#include "mongo/db/pipeline/expression_context_for_test.h"
+#include "mongo/db/pipeline/expression_context.h"
#include "mongo/db/query/cursor_response.h"
#include "mongo/db/query/getmore_request.h"
#include "mongo/db/query/query_request.h"
@@ -74,7 +74,11 @@ const CursorId kExhaustedCursorID = 0;
class DocumentSourceMergeCursorsTest : public ShardingTestFixture {
public:
- DocumentSourceMergeCursorsTest() : _expCtx(new ExpressionContextForTest(kTestNss)) {}
+ DocumentSourceMergeCursorsTest() {
+ TimeZoneDatabase::set(getServiceContext(), std::make_unique<TimeZoneDatabase>());
+ _expCtx = new ExpressionContext(operationContext(), nullptr);
+ _expCtx->ns = kTestNss;
+ }
void setUp() override {
ShardingTestFixture::setUp();
@@ -102,12 +106,12 @@ public:
setupShards(shards);
}
- boost::intrusive_ptr<ExpressionContextForTest> getExpCtx() {
+ boost::intrusive_ptr<ExpressionContext> getExpCtx() {
return _expCtx.get();
}
private:
- boost::intrusive_ptr<ExpressionContextForTest> _expCtx;
+ boost::intrusive_ptr<ExpressionContext> _expCtx;
};
TEST_F(DocumentSourceMergeCursorsTest, ShouldRejectNonArray) {
diff --git a/src/mongo/db/pipeline/document_source_test.cpp b/src/mongo/db/pipeline/document_source_test.cpp
index 934f9bf024a..2979179c255 100644
--- a/src/mongo/db/pipeline/document_source_test.cpp
+++ b/src/mongo/db/pipeline/document_source_test.cpp
@@ -32,13 +32,16 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/pipeline/document_source.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
namespace {
-TEST(TruncateSort, SortTruncatesNormalField) {
+class DocumentSourceTruncateSort : public ServiceContextTest {};
+
+TEST_F(DocumentSourceTruncateSort, SortTruncatesNormalField) {
SimpleBSONObjComparator bsonComparator{};
BSONObj sortKey = BSON("a" << 1 << "b" << 1 << "c" << 1);
auto truncated =
@@ -47,7 +50,7 @@ TEST(TruncateSort, SortTruncatesNormalField) {
ASSERT_EQUALS(truncated.count(BSON("a" << 1)), 1U);
}
-TEST(DocumentSourceTruncateSort, SortTruncatesOnSubfield) {
+TEST_F(DocumentSourceTruncateSort, SortTruncatesOnSubfield) {
SimpleBSONObjComparator bsonComparator{};
BSONObj sortKey = BSON("a" << 1 << "b.c" << 1 << "d" << 1);
auto truncated =
@@ -56,7 +59,7 @@ TEST(DocumentSourceTruncateSort, SortTruncatesOnSubfield) {
ASSERT_EQUALS(truncated.count(BSON("a" << 1)), 1U);
}
-TEST(DocumentSourceTruncateSort, SortDoesNotTruncateOnParent) {
+TEST_F(DocumentSourceTruncateSort, SortDoesNotTruncateOnParent) {
SimpleBSONObjComparator bsonComparator{};
BSONObj sortKey = BSON("a" << 1 << "b" << 1 << "d" << 1);
auto truncated =
@@ -65,7 +68,7 @@ TEST(DocumentSourceTruncateSort, SortDoesNotTruncateOnParent) {
ASSERT_EQUALS(truncated.count(BSON("a" << 1 << "b" << 1 << "d" << 1)), 1U);
}
-TEST(DocumentSourceTruncateSort, TruncateSortDedupsSortCorrectly) {
+TEST_F(DocumentSourceTruncateSort, TruncateSortDedupsSortCorrectly) {
SimpleBSONObjComparator bsonComparator{};
BSONObj sortKeyOne = BSON("a" << 1 << "b" << 1);
BSONObj sortKeyTwo = BSON("a" << 1);
diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h
index ed5dd84b251..495797b7575 100644
--- a/src/mongo/db/pipeline/expression_context.h
+++ b/src/mongo/db/pipeline/expression_context.h
@@ -186,6 +186,14 @@ public:
return tailableMode == TailableModeEnum::kTailableAndAwaitData;
}
+ /**
+ * Sets the resolved definition for an involved namespace.
+ */
+ void setResolvedNamespace_forTest(const NamespaceString& nss,
+ ResolvedNamespace resolvedNamespace) {
+ _resolvedNamespaces[nss.coll()] = std::move(resolvedNamespace);
+ }
+
// The explain verbosity requested by the user, or boost::none if no explain was requested.
boost::optional<ExplainOptions::Verbosity> explain;
diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript
index 37f68acfc2d..bb8eb142176 100644
--- a/src/mongo/db/query/SConscript
+++ b/src/mongo/db/query/SConscript
@@ -103,7 +103,6 @@ env.CppUnitTest(
],
LIBDEPS=[
"$BUILD_DIR/mongo/db/pipeline/aggregation_request",
- '$BUILD_DIR/mongo/db/service_context_noop_init',
"query_test_service_context",
"query_common",
],
@@ -218,6 +217,8 @@ env.Library(
"$BUILD_DIR/mongo/db/logical_session_id",
"$BUILD_DIR/mongo/db/service_context",
],
+ LIBDEPS_PRIVATE=[
+ ],
)
env.Library(
@@ -295,6 +296,7 @@ env.CppUnitTest(
LIBDEPS=[
"$BUILD_DIR/mongo/db/pipeline/aggregation_request",
"$BUILD_DIR/mongo/db/concurrency/lock_manager",
+ "$BUILD_DIR/mongo/db/service_context_test_fixture",
"query_request",
],
)
diff --git a/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp b/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp
index c2a4922071f..abe71a471d6 100644
--- a/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp
+++ b/src/mongo/db/query/collation/collator_factory_icu_decoration.cpp
@@ -37,13 +37,12 @@ namespace mongo {
namespace {
-MONGO_INITIALIZER_WITH_PREREQUISITES(CreateCollatorFactory, ("ServiceContext", "LoadICUData"))
-(InitializerContext* context) {
- CollatorFactoryInterface::set(getGlobalServiceContext(),
- stdx::make_unique<CollatorFactoryICU>());
- return Status::OK();
-}
-
+ServiceContext::ConstructorActionRegisterer registerIcuCollator{
+ "CreateCollatorFactory",
+ {"LoadICUData"},
+ [](ServiceContext* service) {
+ CollatorFactoryInterface::set(service, stdx::make_unique<CollatorFactoryICU>());
+ }};
} // namespace
} // namespace mongo
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/query/query_request_test.cpp b/src/mongo/db/query/query_request_test.cpp
index 9992fdb155e..c9354dfe1fa 100644
--- a/src/mongo/db/query/query_request_test.cpp
+++ b/src/mongo/db/query/query_request_test.cpp
@@ -39,7 +39,7 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/pipeline/aggregation_request.h"
#include "mongo/db/query/query_request.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
@@ -1363,20 +1363,19 @@ TEST(QueryRequestTest, ParseFromLegacyQueryTooNegativeNToReturn) {
.getStatus());
}
-TEST(QueryRequestTest, ParseFromUUID) {
- ServiceContextNoop service;
- auto client = service.makeClient("test");
- auto opCtxNoop = client->makeOperationContext();
- auto opCtx = opCtxNoop.get();
+class QueryRequestTest : public ServiceContextTest {};
+
+TEST_F(QueryRequestTest, ParseFromUUID) {
+ auto opCtx = makeOperationContext();
// Register a UUID/Collection pair in the UUIDCatalog.
const CollectionUUID uuid = UUID::gen();
const NamespaceString nss("test.testns");
Collection coll(stdx::make_unique<CollectionMock>(nss));
- UUIDCatalog& catalog = UUIDCatalog::get(opCtx);
- catalog.onCreateCollection(opCtx, &coll, uuid);
+ UUIDCatalog& catalog = UUIDCatalog::get(opCtx.get());
+ catalog.onCreateCollection(opCtx.get(), &coll, uuid);
QueryRequest qr(uuid);
// Ensure a call to refreshNSS succeeds.
- qr.refreshNSS(opCtx);
+ qr.refreshNSS(opCtx.get());
ASSERT_EQ(nss, qr.nss());
}
diff --git a/src/mongo/db/query/query_test_service_context.cpp b/src/mongo/db/query/query_test_service_context.cpp
index d752db15664..490e3aff679 100644
--- a/src/mongo/db/query/query_test_service_context.cpp
+++ b/src/mongo/db/query/query_test_service_context.cpp
@@ -36,13 +36,15 @@
namespace mongo {
-QueryTestServiceContext::QueryTestServiceContext() {
- CollatorFactoryInterface::set(&_serviceContext, stdx::make_unique<CollatorFactoryMock>());
- _uniqueClient = _serviceContext.makeClient("QueryTest");
+QueryTestServiceContext::QueryTestServiceContext()
+ : _service(ServiceContext::make()), _client(_service->makeClient("query_test")) {
+ CollatorFactoryInterface::set(getServiceContext(), stdx::make_unique<CollatorFactoryMock>());
}
+QueryTestServiceContext::~QueryTestServiceContext() = default;
+
ServiceContext::UniqueOperationContext QueryTestServiceContext::makeOperationContext() {
- return _uniqueClient->makeOperationContext();
+ return getClient()->makeOperationContext();
}
ServiceContext::UniqueOperationContext QueryTestServiceContext::makeOperationContext(
@@ -53,7 +55,11 @@ ServiceContext::UniqueOperationContext QueryTestServiceContext::makeOperationCon
}
Client* QueryTestServiceContext::getClient() const {
- return _uniqueClient.get();
+ return _client.get();
+}
+
+ServiceContext* QueryTestServiceContext::getServiceContext() {
+ return _service.get();
}
} // namespace mongo
diff --git a/src/mongo/db/query/query_test_service_context.h b/src/mongo/db/query/query_test_service_context.h
index c52944cf2f5..05a21afef3f 100644
--- a/src/mongo/db/query/query_test_service_context.h
+++ b/src/mongo/db/query/query_test_service_context.h
@@ -30,7 +30,7 @@
#include "mongo/db/client.h"
#include "mongo/db/logical_session_id.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
namespace mongo {
@@ -42,20 +42,18 @@ namespace mongo {
class QueryTestServiceContext {
public:
QueryTestServiceContext();
+ ~QueryTestServiceContext();
ServiceContext::UniqueOperationContext makeOperationContext();
ServiceContext::UniqueOperationContext makeOperationContext(LogicalSessionId lsid);
Client* getClient() const;
-
- ServiceContext* getServiceContext() {
- return &_serviceContext;
- }
+ ServiceContext* getServiceContext();
private:
- ServiceContextNoop _serviceContext;
- ServiceContext::UniqueClient _uniqueClient;
+ ServiceContext::UniqueServiceContext _service;
+ ServiceContext::UniqueClient _client;
};
} // namespace mongo
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index 6e45c708fd9..756ea3f6332 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -780,7 +780,6 @@ env.CppUnitTest(
'topology_coordinator',
'replica_set_messages',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/executor/network_interface_factory',
'$BUILD_DIR/mongo/executor/network_interface_mock',
'$BUILD_DIR/mongo/executor/network_interface_thread_pool',
@@ -836,10 +835,10 @@ env.Library(
LIBDEPS=[
'repl_coordinator_impl',
'replmocks',
- 'service_context_repl_mock_init',
'topology_coordinator',
'$BUILD_DIR/mongo/db/auth/authorization_manager_global',
'$BUILD_DIR/mongo/db/auth/authmocks',
+ '$BUILD_DIR/mongo/db/service_context_d_test_fixture',
'$BUILD_DIR/mongo/executor/network_interface_mock',
'$BUILD_DIR/mongo/executor/network_interface_factory',
'$BUILD_DIR/mongo/executor/network_interface_thread_pool',
@@ -847,6 +846,10 @@ env.Library(
'$BUILD_DIR/mongo/unittest/unittest',
],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/storage/ephemeral_for_test/storage_ephemeral_for_test',
+ '$BUILD_DIR/mongo/db/storage/storage_engine_common',
+ ],
)
env.CppUnitTest(
@@ -869,7 +872,7 @@ env.CppUnitTest(
'repl_coordinator_impl',
'replmocks',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
@@ -892,7 +895,6 @@ env.CppUnitTest(
LIBDEPS=[
'repl_coordinator_impl',
'replmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
],
@@ -907,7 +909,6 @@ env.CppUnitTest(
'repl_coordinator_impl',
'replica_set_messages',
'replmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
],
@@ -923,7 +924,6 @@ env.CppUnitTest(
'replica_set_messages',
'replmocks',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
],
)
@@ -937,7 +937,6 @@ env.CppUnitTest(
'repl_coordinator_impl',
'replica_set_messages',
'replmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
],
@@ -976,7 +975,6 @@ env.Library(
'replication_consistency_markers_mock.cpp',
'replication_coordinator_external_state_mock.cpp',
'replication_coordinator_mock.cpp',
- 'service_context_repl_mock.cpp',
'storage_interface_mock.cpp',
],
LIBDEPS=[
@@ -991,17 +989,6 @@ env.Library(
],
)
-env.Library(
- target='service_context_repl_mock_init',
- source=[
- 'service_context_repl_mock_init.cpp',
- ],
- LIBDEPS=[
- 'replmocks',
- '$BUILD_DIR/mongo/util/clock_source_mock',
- ],
-)
-
env.Library('read_concern_args',
[
'read_concern_args.cpp'
@@ -1059,6 +1046,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',
],
)
@@ -1197,7 +1185,6 @@ env.CppUnitTest(
'reporter',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/unittest/task_executor_proxy',
],
)
@@ -1250,6 +1237,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',
],
@@ -1282,7 +1270,6 @@ env.CppUnitTest(
'base_cloner_test_fixture',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/auth/authorization_manager_global',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/unittest/task_executor_proxy',
],
)
@@ -1309,7 +1296,6 @@ env.CppUnitTest(
'base_cloner_test_fixture',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/commands/list_collections_filter',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/unittest/task_executor_proxy',
],
)
@@ -1333,7 +1319,7 @@ env.CppUnitTest(
'oplog_entry',
'replmocks',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$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',
],
@@ -1350,32 +1336,24 @@ env.Library(
],
)
-env.Library(
- target='task_runner_test_fixture',
+env.CppUnitTest(
+ target='task_runner_test',
source=[
+ 'task_runner_test.cpp',
'task_runner_test_fixture.cpp',
],
LIBDEPS=[
'replmocks',
- 'service_context_repl_mock_init',
'task_runner',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/auth/authorization_manager_global',
- '$BUILD_DIR/mongo/db/service_context',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/unittest/concurrency',
'$BUILD_DIR/mongo/unittest/unittest',
],
)
env.CppUnitTest(
- target='task_runner_test',
- source='task_runner_test.cpp',
- LIBDEPS=[
- 'task_runner_test_fixture',
- ],
-)
-
-env.CppUnitTest(
target='read_concern_args_test',
source=[
'read_concern_args_test.cpp',
@@ -1424,8 +1402,8 @@ env.CppUnitTest(
source='multiapplier_test.cpp',
LIBDEPS=[
'multiapplier',
- 'service_context_repl_mock_init',
'$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',
],
@@ -1506,6 +1484,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',
@@ -1513,7 +1492,6 @@ env.CppUnitTest(
'initial_syncer',
'replication_process',
'replmocks',
- 'service_context_repl_mock_init',
'sync_source_selector_mock',
'task_executor_mock',
],
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/collection_bulk_loader_impl.cpp b/src/mongo/db/repl/collection_bulk_loader_impl.cpp
index a8b432e7a7f..b0ccc6dfcc9 100644
--- a/src/mongo/db/repl/collection_bulk_loader_impl.cpp
+++ b/src/mongo/db/repl/collection_bulk_loader_impl.cpp
@@ -51,40 +51,6 @@
namespace mongo {
namespace repl {
-namespace {
-
-/**
- * Utility class to temporarily swap which client is bound to the running thread.
- *
- * Use this class to bind a client to the current thread for the duration of the
- * AlternativeClientRegion's lifetime, restoring the prior client, if any, at the
- * end of the block.
- */
-class AlternativeClientRegion {
-public:
- explicit AlternativeClientRegion(ServiceContext::UniqueClient& clientToUse)
- : _alternateClient(&clientToUse) {
- invariant(clientToUse);
- if (Client::getCurrent()) {
- _originalClient = Client::releaseCurrent();
- }
- Client::setCurrent(std::move(*_alternateClient));
- }
-
- ~AlternativeClientRegion() {
- *_alternateClient = Client::releaseCurrent();
- if (_originalClient) {
- Client::setCurrent(std::move(_originalClient));
- }
- }
-
-private:
- ServiceContext::UniqueClient _originalClient;
- ServiceContext::UniqueClient* const _alternateClient;
-};
-
-} // namespace
-
CollectionBulkLoaderImpl::CollectionBulkLoaderImpl(ServiceContext::UniqueClient&& client,
ServiceContext::UniqueOperationContext&& opCtx,
std::unique_ptr<AutoGetCollection>&& autoColl,
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 14ffb0c5455..2db70d6b4e2 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 adac65ef262..8ae698e310b 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/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
index 015fed756b0..95a16e5572e 100644
--- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp
@@ -57,7 +57,7 @@
#include "mongo/db/repl/topology_coordinator.h"
#include "mongo/db/repl/update_position_args.h"
#include "mongo/db/server_options.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/db/write_concern_options.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/rpc/metadata/oplog_query_metadata.h"
@@ -829,10 +829,6 @@ TEST_F(ReplCoordTest, NodeReturnsWriteConcernFailedUntilASufficientNumberOfNodes
TEST_F(ReplCoordTest,
NodeReturnsUnknownReplWriteConcernWhenAwaitReplicationReceivesAnInvalidWriteConcernMode) {
- auto service = stdx::make_unique<ServiceContextNoop>();
- auto client = service->makeClient("test");
- auto opCtx = client->makeOperationContext();
-
assertStartSuccess(BSON("_id"
<< "mySet"
<< "version"
@@ -862,6 +858,7 @@ TEST_F(ReplCoordTest,
invalidWriteConcern.wTimeout = WriteConcernOptions::kNoWaiting;
invalidWriteConcern.wMode = "fakemode";
+ auto opCtx = makeOperationContext();
ReplicationCoordinator::StatusAndDuration statusAndDur =
getReplCoord()->awaitReplication(opCtx.get(), time1, invalidWriteConcern);
ASSERT_EQUALS(ErrorCodes::UnknownReplWriteConcern, statusAndDur.status);
@@ -870,10 +867,6 @@ TEST_F(ReplCoordTest,
TEST_F(
ReplCoordTest,
NodeReturnsWriteConcernFailedUntilASufficientSetOfNodesHaveTheWriteAndTheWriteIsInACommittedSnapshot) {
- auto service = stdx::make_unique<ServiceContextNoop>();
- auto client = service->makeClient("test");
- auto opCtx = client->makeOperationContext();
-
assertStartSuccess(
BSON("_id"
<< "mySet"
@@ -941,7 +934,7 @@ TEST_F(
multiRackWriteConcern.wTimeout = WriteConcernOptions::kNoWaiting;
multiRackWriteConcern.wMode = "multiDCAndRack";
-
+ auto opCtx = makeOperationContext();
// Nothing satisfied
getReplCoord()->setMyLastAppliedOpTime(time1);
getReplCoord()->setMyLastDurableOpTime(time1);
diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
index db81b8e46d8..7b2defbe0ad 100644
--- a/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
+++ b/src/mongo/db/repl/replication_coordinator_test_fixture.cpp
@@ -45,6 +45,8 @@
#include "mongo/db/repl/replication_recovery_mock.h"
#include "mongo/db/repl/storage_interface_mock.h"
#include "mongo/db/repl/topology_coordinator.h"
+#include "mongo/db/storage/storage_engine_init.h"
+#include "mongo/db/storage/storage_options.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_mock.h"
#include "mongo/executor/thread_pool_task_executor.h"
@@ -79,12 +81,11 @@ BSONObj ReplCoordTest::addProtocolVersion(const BSONObj& configDoc, int protocol
return builder.obj();
}
-
-void ReplCoordTest::setUp() {
+ReplCoordTest::ReplCoordTest() {
_settings.setReplSetString("mySet/node1:12345,node2:54321");
}
-void ReplCoordTest::tearDown() {
+ReplCoordTest::~ReplCoordTest() {
getGlobalFailPointRegistry()
->getFailPoint("blockHeartbeatReconfigFinish")
->setMode(FailPoint::off);
diff --git a/src/mongo/db/repl/replication_coordinator_test_fixture.h b/src/mongo/db/repl/replication_coordinator_test_fixture.h
index 67f30ceeff9..3f0cb66f838 100644
--- a/src/mongo/db/repl/replication_coordinator_test_fixture.h
+++ b/src/mongo/db/repl/replication_coordinator_test_fixture.h
@@ -33,6 +33,7 @@
#include "mongo/db/client.h"
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/repl/replication_coordinator.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/task_executor.h"
#include "mongo/unittest/unittest.h"
@@ -55,7 +56,7 @@ using executor::NetworkInterfaceMock;
/**
* Fixture for testing ReplicationCoordinatorImpl behaviors.
*/
-class ReplCoordTest : public mongo::unittest::Test {
+class ReplCoordTest : public ServiceContextMongoDTest {
public:
/**
* Makes a command response with the given "doc" response and optional elapsed time "millis".
@@ -81,8 +82,8 @@ public:
static BSONObj addProtocolVersion(const BSONObj& configDoc, int protocolVersion);
protected:
- virtual void setUp();
- virtual void tearDown();
+ ReplCoordTest();
+ virtual ~ReplCoordTest();
/**
* Asserts that calling start(configDoc, selfHost) successfully initiates the
@@ -131,27 +132,6 @@ protected:
}
/**
- * Makes a new OperationContext on the default Client for this test.
- */
- ServiceContext::UniqueOperationContext makeOperationContext() {
- return _client->makeOperationContext();
- }
-
- /**
- * Returns the ServiceContext for this test.
- */
- ServiceContext* getServiceContext() {
- return getGlobalServiceContext();
- }
-
- /**
- * Returns the default Client for this test.
- */
- Client* getClient() {
- return _client.get();
- }
-
- /**
* Adds "selfHost" to the list of hosts that identify as "this" host.
*/
void addSelf(const HostAndPort& selfHost);
@@ -298,7 +278,6 @@ private:
ReplSettings _settings;
bool _callShutdown = false;
- ServiceContext::UniqueClient _client = getGlobalServiceContext()->makeClient("testClient");
};
} // namespace repl
diff --git a/src/mongo/db/repl/rollback_impl_test.cpp b/src/mongo/db/repl/rollback_impl_test.cpp
index 427ff7688a4..8561743e303 100644
--- a/src/mongo/db/repl/rollback_impl_test.cpp
+++ b/src/mongo/db/repl/rollback_impl_test.cpp
@@ -419,7 +419,7 @@ void _assertDocsInOplog(OperationContext* opCtx, std::vector<int> timestamps) {
}
TEST_F(RollbackImplTest, TestFixtureSetUpInitializesStorageEngine) {
- auto serviceContext = _serviceContextMongoDTest.getServiceContext();
+ auto serviceContext = getServiceContext();
ASSERT_TRUE(serviceContext);
ASSERT_TRUE(serviceContext->getStorageEngine());
}
diff --git a/src/mongo/db/repl/rollback_test_fixture.cpp b/src/mongo/db/repl/rollback_test_fixture.cpp
index b0d49b1473a..db6b01e3d02 100644
--- a/src/mongo/db/repl/rollback_test_fixture.cpp
+++ b/src/mongo/db/repl/rollback_test_fixture.cpp
@@ -68,9 +68,8 @@ ReplSettings createReplSettings() {
} // namespace
void RollbackTest::setUp() {
- _serviceContextMongoDTest.setUp();
_storageInterface = new StorageInterfaceRollback();
- auto serviceContext = _serviceContextMongoDTest.getServiceContext();
+ auto serviceContext = getServiceContext();
auto consistencyMarkers = stdx::make_unique<ReplicationConsistencyMarkersMock>();
auto recovery =
stdx::make_unique<ReplicationRecoveryImpl>(_storageInterface, consistencyMarkers.get());
@@ -85,7 +84,7 @@ void RollbackTest::setUp() {
std::unique_ptr<ReplicationCoordinator>(_coordinator));
setOplogCollectionName(serviceContext);
- _opCtx = cc().makeOperationContext();
+ _opCtx = makeOperationContext();
_replicationProcess->getConsistencyMarkers()->clearAppliedThrough(_opCtx.get(), {});
_replicationProcess->getConsistencyMarkers()->setMinValid(_opCtx.get(), OpTime{});
_replicationProcess->initializeRollbackID(_opCtx.get()).transitional_ignore();
@@ -95,24 +94,6 @@ void RollbackTest::setUp() {
logger::LogComponent::kReplicationRollback, logger::LogSeverity::Debug(2));
}
-void RollbackTest::tearDown() {
- _coordinator = nullptr;
- _opCtx.reset();
-
- SessionCatalog::get(_serviceContextMongoDTest.getServiceContext())->reset_forTest();
-
- // We cannot unset the global replication coordinator because ServiceContextMongoD::tearDown()
- // calls Databse::dropAllDatabasesExceptLocal() which requires the replication coordinator to
- // clear all snapshots.
- _serviceContextMongoDTest.tearDown();
-
- // ServiceContextMongoD::tearDown() does not destroy service context so it is okay
- // to access the service context after tearDown().
- auto serviceContext = _serviceContextMongoDTest.getServiceContext();
- _replicationProcess.reset();
- ReplicationCoordinator::set(serviceContext, {});
-}
-
RollbackTest::ReplicationCoordinatorRollbackMock::ReplicationCoordinatorRollbackMock(
ServiceContext* service)
: ReplicationCoordinatorMock(service, createReplSettings()) {}
diff --git a/src/mongo/db/repl/rollback_test_fixture.h b/src/mongo/db/repl/rollback_test_fixture.h
index 4f43fb47945..8d31c63564f 100644
--- a/src/mongo/db/repl/rollback_test_fixture.h
+++ b/src/mongo/db/repl/rollback_test_fixture.h
@@ -49,7 +49,7 @@ namespace repl {
* storage layer. The storage engine is initialized as part of the ServiceContextForMongoD test
* fixture.
*/
-class RollbackTest : public unittest::Test {
+class RollbackTest : public ServiceContextMongoDTest {
public:
RollbackTest() = default;
@@ -59,15 +59,6 @@ public:
void setUp() override;
/**
- * Destroys the service context and task executor.
- *
- * Note on overriding tearDown() in tests:
- * This cancels outstanding tasks and remote command requests scheduled using the task
- * executor.
- */
- void tearDown() override;
-
- /**
* Creates a collection with the given namespace and options.
*/
static Collection* _createCollection(OperationContext* opCtx,
@@ -101,9 +92,6 @@ public:
Timestamp ts, OptionalCollectionUUID uuid, StringData nss, BSONObj cmdObj, int recordId);
protected:
- // Test fixture used to manage the service context and global storage engine.
- ServiceContextMongoDTest _serviceContextMongoDTest;
-
// OperationContext provided to test cases for storage layer operations.
ServiceContext::UniqueOperationContext _opCtx;
diff --git a/src/mongo/db/repl/rs_rollback_test.cpp b/src/mongo/db/repl/rs_rollback_test.cpp
index 4573e277d83..8b254a65988 100644
--- a/src/mongo/db/repl/rs_rollback_test.cpp
+++ b/src/mongo/db/repl/rs_rollback_test.cpp
@@ -69,23 +69,8 @@ using namespace mongo::repl::rollback_internal;
const auto kIndexVersion = IndexDescriptor::IndexVersion::kV2;
-class RSRollbackTest : public RollbackTest {
-private:
- void setUp() override;
- void tearDown() override;
-};
-
-void RSRollbackTest::setUp() {
- RollbackTest::setUp();
- auto observerRegistry = stdx::make_unique<OpObserverRegistry>();
- observerRegistry->addObserver(stdx::make_unique<UUIDCatalogObserver>());
- _serviceContextMongoDTest.getServiceContext()->setOpObserver(
- std::unique_ptr<OpObserver>(observerRegistry.release()));
-}
+class RSRollbackTest : public RollbackTest {};
-void RSRollbackTest::tearDown() {
- RollbackTest::tearDown();
-}
OplogInterfaceMock::Operation makeNoopOplogEntryAndRecordId(Seconds seconds) {
OpTime ts(Timestamp(seconds, 0), 0);
diff --git a/src/mongo/db/repl/service_context_repl_mock.cpp b/src/mongo/db/repl/service_context_repl_mock.cpp
deleted file mode 100644
index c8d87716e8d..00000000000
--- a/src/mongo/db/repl/service_context_repl_mock.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Copyright (C) 2016 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/service_context_repl_mock.h"
-
-#include "mongo/db/concurrency/lock_state.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/stdx/memory.h"
-
-namespace mongo {
-namespace repl {
-
-std::unique_ptr<OperationContext> ServiceContextReplMock::_newOpCtx(Client* client, unsigned opId) {
- auto opCtx = stdx::make_unique<OperationContextNoop>(client, opId);
- opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>());
- return {std::move(opCtx)};
-}
-
-} // namespace repl
-} // namespace mongo
diff --git a/src/mongo/db/repl/service_context_repl_mock.h b/src/mongo/db/repl/service_context_repl_mock.h
deleted file mode 100644
index 8ffb92a9da1..00000000000
--- a/src/mongo/db/repl/service_context_repl_mock.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright (C) 2016 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.
- */
-
-#pragma once
-
-#include "mongo/db/service_context_noop.h"
-
-namespace mongo {
-namespace repl {
-
-/**
- * Testing-only service context that extends ServiceContextNoop so that makeOperationContext()
- * returns an instance of OperationContextReplMock.
- */
-class ServiceContextReplMock : public ServiceContextNoop {
-private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
-};
-
-} // namespace repl
-} // namespace mongo
diff --git a/src/mongo/db/repl/task_runner_test_fixture.cpp b/src/mongo/db/repl/task_runner_test_fixture.cpp
index f16bfa67be0..3e510603d8a 100644
--- a/src/mongo/db/repl/task_runner_test_fixture.cpp
+++ b/src/mongo/db/repl/task_runner_test_fixture.cpp
@@ -30,7 +30,7 @@
#include "mongo/db/repl/task_runner_test_fixture.h"
-#include "mongo/db/operation_context_noop.h"
+#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/repl/task_runner.h"
#include "mongo/stdx/functional.h"
#include "mongo/stdx/memory.h"
diff --git a/src/mongo/db/repl/task_runner_test_fixture.h b/src/mongo/db/repl/task_runner_test_fixture.h
index 2787419a1e5..9076bea4135 100644
--- a/src/mongo/db/repl/task_runner_test_fixture.h
+++ b/src/mongo/db/repl/task_runner_test_fixture.h
@@ -31,7 +31,7 @@
#include <memory>
#include "mongo/base/status.h"
-#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/concurrency/thread_pool.h"
@@ -48,7 +48,7 @@ class TaskRunner;
* Test fixture for tests that require a TaskRunner and/or
* ThreadPool.
*/
-class TaskRunnerTest : public unittest::Test {
+class TaskRunnerTest : public ServiceContextTest {
public:
static Status getDetectableErrorStatus();
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript
index 2c2cadc63f4..b3e68cd3e20 100644
--- a/src/mongo/db/s/SConscript
+++ b/src/mongo/db/s/SConscript
@@ -309,6 +309,7 @@ env.CppUnitTest(
'sharding_runtime_d',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/query/query_request',
+ '$BUILD_DIR/mongo/db/service_context_d_test_fixture',
'$BUILD_DIR/mongo/s/catalog/dist_lock_manager_mock',
'$BUILD_DIR/mongo/s/catalog/sharding_catalog_client_impl',
'$BUILD_DIR/mongo/s/catalog/sharding_catalog_client_mock',
diff --git a/src/mongo/db/s/active_migrations_registry_test.cpp b/src/mongo/db/s/active_migrations_registry_test.cpp
index 5450296d505..ba0d148b863 100644
--- a/src/mongo/db/s/active_migrations_registry_test.cpp
+++ b/src/mongo/db/s/active_migrations_registry_test.cpp
@@ -32,7 +32,7 @@
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/client.h"
#include "mongo/db/s/active_migrations_registry.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/s/request_types/move_chunk_request.h"
#include "mongo/unittest/unittest.h"
@@ -41,26 +41,8 @@ namespace {
using unittest::assertGet;
-class MoveChunkRegistration : public unittest::Test {
+class MoveChunkRegistration : public ServiceContextMongoDTest {
protected:
- void setUp() override {
- _client = _serviceContext.makeClient("MoveChunkRegistrationTest");
- _opCtx = _serviceContext.makeOperationContext(_client.get());
- }
-
- void tearDown() override {
- _opCtx.reset();
- _client.reset();
- }
-
- OperationContext* getTxn() const {
- return _opCtx.get();
- }
-
- ServiceContextNoop _serviceContext;
- ServiceContext::UniqueClient _client;
- ServiceContext::UniqueOperationContext _opCtx;
-
ActiveMigrationsRegistry _registry;
};
@@ -133,8 +115,9 @@ TEST_F(MoveChunkRegistration, SecondMigrationWithSameArgumentsJoinsFirst) {
ASSERT(!secondScopedDonateChunk.mustExecute());
originalScopedDonateChunk.signalComplete({ErrorCodes::InternalError, "Test error"});
+ auto opCtx = makeOperationContext();
ASSERT_EQ(Status(ErrorCodes::InternalError, "Test error"),
- secondScopedDonateChunk.waitForCompletion(getTxn()));
+ secondScopedDonateChunk.waitForCompletion(opCtx.get()));
}
} // namespace
diff --git a/src/mongo/db/s/active_move_primaries_registry_test.cpp b/src/mongo/db/s/active_move_primaries_registry_test.cpp
index b196fdc2621..25c028e3b48 100644
--- a/src/mongo/db/s/active_move_primaries_registry_test.cpp
+++ b/src/mongo/db/s/active_move_primaries_registry_test.cpp
@@ -29,7 +29,7 @@
#include "mongo/db/s/active_move_primaries_registry.h"
#include "mongo/bson/bsonmisc.h"
#include "mongo/db/client.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/s/request_types/move_primary_gen.h"
#include "mongo/unittest/unittest.h"
@@ -38,26 +38,8 @@ namespace {
using unittest::assertGet;
-class MovePrimaryRegistration : public unittest::Test {
+class MovePrimaryRegistration : public ServiceContextMongoDTest {
protected:
- void setUp() override {
- _client = _serviceContext.makeClient("MovePrimaryRegistrationTest");
- _opCtx = _serviceContext.makeOperationContext(_client.get());
- }
-
- void tearDown() override {
- _opCtx.reset();
- _client.reset();
- }
-
- OperationContext* getTxn() const {
- return _opCtx.get();
- }
-
- ServiceContextNoop _serviceContext;
- ServiceContext::UniqueClient _client;
- ServiceContext::UniqueOperationContext _opCtx;
-
ActiveMovePrimariesRegistry _registry;
};
@@ -120,8 +102,9 @@ TEST_F(MovePrimaryRegistration, SecondMovePrimaryWithSameArgumentsJoinsFirst) {
ASSERT(!secondScopedMovePrimary.mustExecute());
originalScopedMovePrimary.signalComplete({ErrorCodes::InternalError, "Test error"});
+ auto opCtx = makeOperationContext();
ASSERT_EQ(Status(ErrorCodes::InternalError, "Test error"),
- secondScopedMovePrimary.waitForCompletion(getTxn()));
+ secondScopedMovePrimary.waitForCompletion(opCtx.get()));
}
} // namespace
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp b/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp
index 1ec6b87f2cc..565729e8458 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_add_shard_test.cpp
@@ -390,6 +390,7 @@ TEST_F(AddShardTest, StandaloneBasicSuccess) {
operationContext()->setWriteConcern(ShardingCatalogClient::kMajorityWriteConcern);
auto future = launchAsync([this, expectedShardName] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName =
assertGet(ShardingCatalogManager::get(operationContext())
@@ -472,6 +473,7 @@ TEST_F(AddShardTest, StandaloneGenerateName) {
DatabaseType discoveredDB2("TestDB2", ShardId(expectedShardName), false);
auto future = launchAsync([this, &expectedShardName, &shardTarget] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(
ShardingCatalogManager::get(operationContext())
@@ -563,6 +565,7 @@ TEST_F(AddShardTest, UnreachableHost) {
std::string expectedShardName = "StandaloneShard";
auto future = launchAsync([this, &expectedShardName, &shardTarget] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status =
ShardingCatalogManager::get(operationContext())
@@ -590,6 +593,7 @@ TEST_F(AddShardTest, AddMongosAsShard) {
std::string expectedShardName = "StandaloneShard";
auto future = launchAsync([this, &expectedShardName, &shardTarget] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status =
ShardingCatalogManager::get(operationContext())
@@ -617,6 +621,7 @@ TEST_F(AddShardTest, AddReplicaSetShardAsStandalone) {
std::string expectedShardName = "Standalone";
auto future = launchAsync([this, expectedShardName, shardTarget] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status =
ShardingCatalogManager::get(operationContext())
@@ -649,6 +654,7 @@ TEST_F(AddShardTest, AddStandaloneHostShardAsReplicaSet) {
std::string expectedShardName = "StandaloneShard";
auto future = launchAsync([this, expectedShardName, connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status = ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), &expectedShardName, connString, 100);
@@ -677,6 +683,7 @@ TEST_F(AddShardTest, ReplicaSetMistmatchedReplicaSetName) {
std::string expectedShardName = "StandaloneShard";
auto future = launchAsync([this, expectedShardName, connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status = ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), &expectedShardName, connString, 100);
@@ -707,6 +714,7 @@ TEST_F(AddShardTest, ShardIsCSRSConfigServer) {
std::string expectedShardName = "StandaloneShard";
auto future = launchAsync([this, expectedShardName, connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status = ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), &expectedShardName, connString, 100);
@@ -740,6 +748,7 @@ TEST_F(AddShardTest, ReplicaSetMissingHostsProvidedInSeedList) {
std::string expectedShardName = "StandaloneShard";
auto future = launchAsync([this, expectedShardName, connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status = ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), &expectedShardName, connString, 100);
@@ -775,6 +784,7 @@ TEST_F(AddShardTest, AddShardWithNameConfigFails) {
std::string expectedShardName = "config";
auto future = launchAsync([this, expectedShardName, connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status = ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), &expectedShardName, connString, 100);
@@ -820,6 +830,7 @@ TEST_F(AddShardTest, ShardContainsExistingDatabase) {
auto future = launchAsync([this, expectedShardName, connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto status = ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), &expectedShardName, connString, 100);
@@ -867,6 +878,7 @@ TEST_F(AddShardTest, SuccessfullyAddReplicaSet) {
DatabaseType discoveredDB("shardDB", ShardId(expectedShardName), false);
auto future = launchAsync([this, &expectedShardName, &connString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), nullptr, connString, 100));
@@ -932,6 +944,7 @@ TEST_F(AddShardTest, ReplicaSetExtraHostsDiscovered) {
DatabaseType discoveredDB("shardDB", ShardId(expectedShardName), false);
auto future = launchAsync([this, &expectedShardName, &seedString] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(ShardingCatalogManager::get(operationContext())
->addShard(operationContext(), nullptr, seedString, 100));
@@ -1007,6 +1020,7 @@ TEST_F(AddShardTest, AddShardSucceedsEvenIfAddingDBsFromNewShardFails) {
ON_BLOCK_EXIT([&] { failPoint->setMode(FailPoint::off); });
auto future = launchAsync([this, &expectedShardName, &shardTarget] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(
ShardingCatalogManager::get(operationContext())
@@ -1098,6 +1112,7 @@ TEST_F(AddShardTest, AddExistingShardStandalone) {
// Adding the same standalone host with a different shard name should fail.
std::string differentName = "anotherShardName";
auto future1 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(ErrorCodes::IllegalOperation,
ShardingCatalogManager::get(operationContext())
@@ -1113,6 +1128,7 @@ TEST_F(AddShardTest, AddExistingShardStandalone) {
// Adding the same standalone host with a different maxSize should fail.
auto future2 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(ErrorCodes::IllegalOperation,
ShardingCatalogManager::get(operationContext())
@@ -1128,6 +1144,7 @@ TEST_F(AddShardTest, AddExistingShardStandalone) {
// can't change the sharded cluster's notion of the shard from standalone to replica set just
// by calling addShard.
auto future3 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(ErrorCodes::IllegalOperation,
ShardingCatalogManager::get(operationContext())
@@ -1143,6 +1160,7 @@ TEST_F(AddShardTest, AddExistingShardStandalone) {
// Adding the same standalone host with the same options should succeed.
auto future4 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(ShardingCatalogManager::get(operationContext())
->addShard(operationContext(),
@@ -1159,6 +1177,7 @@ TEST_F(AddShardTest, AddExistingShardStandalone) {
// Adding the same standalone host with the same options (without explicitly specifying the
// shard name) should succeed.
auto future5 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(ShardingCatalogManager::get(operationContext())
->addShard(operationContext(),
@@ -1202,6 +1221,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
// Adding the same connection string with a different shard name should fail.
std::string differentName = "anotherShardName";
auto future1 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(
ErrorCodes::IllegalOperation,
@@ -1216,6 +1236,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
// Adding the same connection string with a different maxSize should fail.
auto future2 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(
ErrorCodes::IllegalOperation,
@@ -1234,6 +1255,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
// the sharded cluster's notion of the shard from replica set to standalone just by calling
// addShard.
auto future3 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(ErrorCodes::IllegalOperation,
ShardingCatalogManager::get(operationContext())
@@ -1252,6 +1274,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
// change the replica set name the sharded cluster knows for it just by calling addShard again.
std::string differentSetName = "differentSet";
auto future4 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
ASSERT_EQUALS(ErrorCodes::IllegalOperation,
ShardingCatalogManager::get(operationContext())
@@ -1268,6 +1291,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
// Adding the same host with the same options should succeed.
auto future5 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(ShardingCatalogManager::get(operationContext())
->addShard(operationContext(),
@@ -1281,6 +1305,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
// Adding the same host with the same options (without explicitly specifying the shard name)
// should succeed.
auto future6 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(
ShardingCatalogManager::get(operationContext())
@@ -1305,6 +1330,7 @@ TEST_F(AddShardTest, AddExistingShardReplicaSet) {
targeterFactory()->addTargeterToReturn(otherHostConnString, std::move(otherHostTargeter));
}
auto future7 = launchAsync([&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto shardName = assertGet(ShardingCatalogManager::get(operationContext())
->addShard(operationContext(),
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
index 08557545c09..51eab4f8477 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
@@ -558,7 +558,7 @@ StatusWith<BSONObj> MigrationChunkClonerSourceLegacy::_callRecipient(const BSONO
executor::RemoteCommandResponse responseStatus(
Status{ErrorCodes::InternalError, "Uninitialized value"});
- auto executor = grid.getExecutorPool()->getFixedExecutor();
+ auto executor = Grid::get(getGlobalServiceContext())->getExecutorPool()->getFixedExecutor();
auto scheduleStatus = executor->scheduleRemoteCommand(
executor::RemoteCommandRequest(_recipientHost, "admin", cmdObj, nullptr),
[&responseStatus](const executor::TaskExecutor::RemoteCommandCallbackArgs& args) {
diff --git a/src/mongo/db/s/namespace_metadata_change_notifications_test.cpp b/src/mongo/db/s/namespace_metadata_change_notifications_test.cpp
index 6f55ce54dd2..c39dd541396 100644
--- a/src/mongo/db/s/namespace_metadata_change_notifications_test.cpp
+++ b/src/mongo/db/s/namespace_metadata_change_notifications_test.cpp
@@ -30,7 +30,8 @@
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/s/namespace_metadata_change_notifications.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/stdx/memory.h"
#include "mongo/stdx/thread.h"
#include "mongo/unittest/unittest.h"
@@ -41,23 +42,11 @@ namespace {
const NamespaceString kNss("foo.bar");
-class NamespaceMetadataChangeNotificationsTest : public unittest::Test {
+class NamespaceMetadataChangeNotificationsTest : public ServiceContextMongoDTest {
protected:
NamespaceMetadataChangeNotificationsTest() {
- _serviceCtx.setTickSource(stdx::make_unique<TickSourceMock>());
+ getServiceContext()->setTickSource(stdx::make_unique<TickSourceMock>());
}
-
- void setUp() override {
- _client = _serviceCtx.makeClient("Test");
- }
-
- Client* client() const {
- return _client.get();
- }
-
-private:
- ServiceContextNoop _serviceCtx;
- ServiceContext::UniqueClient _client;
};
TEST_F(NamespaceMetadataChangeNotificationsTest, WaitForNotify) {
@@ -66,7 +55,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, WaitForNotify) {
auto scopedNotif = notifications.createNotification(kNss);
{
- auto opCtx = client()->makeOperationContext();
+ auto opCtx = getClient()->makeOperationContext();
opCtx->setDeadlineAfterNowBy(Milliseconds{0}, ErrorCodes::ExceededTimeLimit);
ASSERT_THROWS_CODE(
scopedNotif.get(opCtx.get()), AssertionException, ErrorCodes::ExceededTimeLimit);
@@ -75,7 +64,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, WaitForNotify) {
notifications.notifyChange(kNss);
{
- auto opCtx = client()->makeOperationContext();
+ auto opCtx = getClient()->makeOperationContext();
scopedNotif.get(opCtx.get());
}
}
@@ -85,7 +74,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, GiveUpWaitingForNotify) {
{
auto scopedNotif = notifications.createNotification(kNss);
- auto opCtx = client()->makeOperationContext();
+ auto opCtx = getClient()->makeOperationContext();
opCtx->setDeadlineAfterNowBy(Milliseconds{0}, ErrorCodes::ExceededTimeLimit);
ASSERT_THROWS_CODE(
scopedNotif.get(opCtx.get()), AssertionException, ErrorCodes::ExceededTimeLimit);
@@ -101,7 +90,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, MoveConstructionWaitForNotify)
auto movedScopedNotif = std::move(scopedNotif);
{
- auto opCtx = client()->makeOperationContext();
+ auto opCtx = getClient()->makeOperationContext();
opCtx->setDeadlineAfterNowBy(Milliseconds{0}, ErrorCodes::ExceededTimeLimit);
ASSERT_THROWS_CODE(
movedScopedNotif.get(opCtx.get()), AssertionException, ErrorCodes::ExceededTimeLimit);
@@ -110,7 +99,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, MoveConstructionWaitForNotify)
notifications.notifyChange(kNss);
{
- auto opCtx = client()->makeOperationContext();
+ auto opCtx = getClient()->makeOperationContext();
movedScopedNotif.get(opCtx.get());
}
}
diff --git a/src/mongo/db/s/sharding_state.cpp b/src/mongo/db/s/sharding_state.cpp
index 3850454d36f..f5e22df6838 100644
--- a/src/mongo/db/s/sharding_state.cpp
+++ b/src/mongo/db/s/sharding_state.cpp
@@ -79,7 +79,8 @@ const auto getShardingState = ServiceContext::declareDecoration<ShardingState>()
*/
void updateShardIdentityConfigStringCB(const std::string& setName,
const std::string& newConnectionString) {
- auto configsvrConnStr = grid.shardRegistry()->getConfigServerConnectionString();
+ auto configsvrConnStr =
+ Grid::get(getGlobalServiceContext())->shardRegistry()->getConfigServerConnectionString();
if (configsvrConnStr.getSetName() != setName) {
// Ignore all change notification for other sets that are not the config server.
return;
diff --git a/src/mongo/db/service_context.cpp b/src/mongo/db/service_context.cpp
index 92389a0f6a1..6e2e9210119 100644
--- a/src/mongo/db/service_context.cpp
+++ b/src/mongo/db/service_context.cpp
@@ -26,19 +26,26 @@
* it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
#include "mongo/platform/basic.h"
#include "mongo/db/service_context.h"
+#include "mongo/base/init.h"
#include "mongo/bson/bsonobj.h"
#include "mongo/db/client.h"
+#include "mongo/db/concurrency/locker_noop.h"
#include "mongo/db/op_observer.h"
#include "mongo/db/operation_context.h"
+#include "mongo/db/storage/recovery_unit_noop.h"
+#include "mongo/stdx/list.h"
#include "mongo/stdx/memory.h"
#include "mongo/transport/service_entry_point.h"
#include "mongo/transport/session.h"
#include "mongo/transport/transport_layer.h"
#include "mongo/util/assert_util.h"
+#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
#include "mongo/util/system_clock_source.h"
#include "mongo/util/system_tick_source.h"
@@ -46,9 +53,9 @@
namespace mongo {
namespace {
+using ConstructorActionList = stdx::list<ServiceContext::ConstructorDestructorActions>;
+
ServiceContext* globalServiceContext = nullptr;
-stdx::mutex globalServiceContextMutex;
-stdx::condition_variable globalServiceContextCV;
} // namespace
@@ -61,26 +68,12 @@ ServiceContext* getGlobalServiceContext() {
return globalServiceContext;
}
-ServiceContext* waitAndGetGlobalServiceContext() {
- stdx::unique_lock<stdx::mutex> lk(globalServiceContextMutex);
- globalServiceContextCV.wait(lk, [] { return globalServiceContext; });
- fassert(40549, globalServiceContext);
- return globalServiceContext;
-}
-
-void setGlobalServiceContext(std::unique_ptr<ServiceContext>&& serviceContext) {
+void setGlobalServiceContext(ServiceContext::UniqueServiceContext&& serviceContext) {
if (globalServiceContext) {
// Make sure that calling getGlobalServiceContext() during the destructor results in
// nullptr. Decorations might try and do this.
- auto oldServiceContext = globalServiceContext;
+ ServiceContext::UniqueServiceContext oldServiceContext{globalServiceContext};
globalServiceContext = nullptr;
- delete oldServiceContext;
- }
-
- stdx::lock_guard<stdx::mutex> lk(globalServiceContextMutex);
-
- if (!globalServiceContext) {
- globalServiceContextCV.notify_all();
}
globalServiceContext = serviceContext.release();
@@ -106,28 +99,70 @@ ServiceContext::ServiceContext()
ServiceContext::~ServiceContext() {
stdx::lock_guard<stdx::mutex> lk(_mutex);
+ for (const auto& client : _clients) {
+ severe() << "Client " << client->desc() << " still exists while destroying ServiceContext@"
+ << static_cast<void*>(this);
+ }
invariant(_clients.empty());
}
-ServiceContext::UniqueClient ServiceContext::makeClient(std::string desc,
- transport::SessionHandle session) {
- std::unique_ptr<Client> client(new Client(std::move(desc), this, std::move(session)));
- auto observer = _clientObservers.cbegin();
+namespace {
+
+//
+// These onDestroy and onCreate functions are utilities for correctly executing supplemental
+// constructor and destructor methods for the ServiceContext, Client and OperationContext types.
+//
+// Note that destructors run in reverse order of constructors, and that failed construction
+// leads to corresponding destructors to run, similarly to how member variable construction and
+// destruction behave.
+//
+
+template <typename T, typename ObserversIterator>
+void onDestroy(T* object,
+ const ObserversIterator& observerBegin,
+ const ObserversIterator& observerEnd) {
try {
- for (; observer != _clientObservers.cend(); ++observer) {
- observer->get()->onCreateClient(client.get());
+ auto observer = observerEnd;
+ while (observer != observerBegin) {
+ --observer;
+ observer->onDestroy(object);
}
} catch (...) {
- try {
- while (observer != _clientObservers.cbegin()) {
- --observer;
- observer->get()->onDestroyClient(client.get());
- }
- } catch (...) {
- std::terminate();
+ std::terminate();
+ }
+}
+template <typename T, typename ObserversContainer>
+void onDestroy(T* object, const ObserversContainer& observers) {
+ onDestroy(object, observers.cbegin(), observers.cend());
+}
+
+template <typename T, typename ObserversIterator>
+void onCreate(T* object,
+ const ObserversIterator& observerBegin,
+ const ObserversIterator& observerEnd) {
+ auto observer = observerBegin;
+ try {
+ for (; observer != observerEnd; ++observer) {
+ observer->onCreate(object);
}
+ } catch (...) {
+ onDestroy(object, observerBegin, observer);
throw;
}
+}
+
+template <typename T, typename ObserversContainer>
+void onCreate(T* object, const ObserversContainer& observers) {
+ onCreate(object, observers.cbegin(), observers.cend());
+}
+
+
+} // namespace
+
+ServiceContext::UniqueClient ServiceContext::makeClient(std::string desc,
+ transport::SessionHandle session) {
+ std::unique_ptr<Client> client(new Client(std::move(desc), this, std::move(session)));
+ onCreate(client.get(), _clientObservers);
{
stdx::lock_guard<stdx::mutex> lk(_mutex);
invariant(_clients.insert(client.get()).second);
@@ -196,33 +231,19 @@ void ServiceContext::ClientDeleter::operator()(Client* client) const {
stdx::lock_guard<stdx::mutex> lk(service->_mutex);
invariant(service->_clients.erase(client));
}
- try {
- for (const auto& observer : service->_clientObservers) {
- observer->onDestroyClient(client);
- }
- } catch (...) {
- std::terminate();
- }
+ onDestroy(client, service->_clientObservers);
delete client;
}
ServiceContext::UniqueOperationContext ServiceContext::makeOperationContext(Client* client) {
- auto opCtx = _newOpCtx(client, _nextOpId.fetchAndAdd(1));
- auto observer = _clientObservers.begin();
- try {
- for (; observer != _clientObservers.cend(); ++observer) {
- observer->get()->onCreateOperationContext(opCtx.get());
- }
- } catch (...) {
- try {
- while (observer != _clientObservers.cbegin()) {
- --observer;
- observer->get()->onDestroyOperationContext(opCtx.get());
- }
- } catch (...) {
- std::terminate();
- }
- throw;
+ auto opCtx = std::make_unique<OperationContext>(client, _nextOpId.fetchAndAdd(1));
+ onCreate(opCtx.get(), _clientObservers);
+ if (!opCtx->lockState()) {
+ opCtx->setLockState(std::make_unique<LockerNoop>());
+ }
+ if (!opCtx->recoveryUnit()) {
+ opCtx->setRecoveryUnit(new RecoveryUnitNoop(),
+ WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork);
}
{
stdx::lock_guard<Client> lk(*client);
@@ -238,18 +259,12 @@ void ServiceContext::OperationContextDeleter::operator()(OperationContext* opCtx
stdx::lock_guard<Client> lk(*client);
client->resetOperationContext();
}
- try {
- for (const auto& observer : service->_clientObservers) {
- observer->onDestroyOperationContext(opCtx);
- }
- } catch (...) {
- std::terminate();
- }
+ onDestroy(opCtx, service->_clientObservers);
delete opCtx;
}
void ServiceContext::registerClientObserver(std::unique_ptr<ClientObserver> observer) {
- _clientObservers.push_back(std::move(observer));
+ _clientObservers.emplace_back(std::move(observer));
}
ServiceContext::LockedClientsCursor::LockedClientsCursor(ServiceContext* service)
@@ -339,4 +354,55 @@ void ServiceContext::notifyStartupComplete() {
_startupCompleteCondVar.notify_all();
}
+namespace {
+
+/**
+ * Accessor function to get the global list of ServiceContext constructor and destructor
+ * functions.
+ */
+ConstructorActionList& registeredConstructorActions() {
+ static ConstructorActionList cal;
+ return cal;
+}
+
+} // namespace
+
+ServiceContext::ConstructorActionRegisterer::ConstructorActionRegisterer(
+ std::string name, ConstructorAction constructor, DestructorAction destructor)
+ : ConstructorActionRegisterer(
+ std::move(name), {}, std::move(constructor), std::move(destructor)) {}
+
+ServiceContext::ConstructorActionRegisterer::ConstructorActionRegisterer(
+ std::string name,
+ std::vector<std::string> prereqs,
+ ConstructorAction constructor,
+ DestructorAction destructor) {
+ if (!destructor)
+ destructor = [](ServiceContext*) {};
+ _registerer.emplace(std::move(name),
+ std::move(prereqs),
+ [this, constructor, destructor](InitializerContext* context) {
+ _iter = registeredConstructorActions().emplace(
+ registeredConstructorActions().end(),
+ std::move(constructor),
+ std::move(destructor));
+ return Status::OK();
+ },
+ [this](DeinitializerContext* context) {
+ registeredConstructorActions().erase(_iter);
+ return Status::OK();
+ });
+}
+
+ServiceContext::UniqueServiceContext ServiceContext::make() {
+ auto service = std::make_unique<ServiceContext>();
+ onCreate(service.get(), registeredConstructorActions());
+ return UniqueServiceContext{service.release()};
+}
+
+void ServiceContext::ServiceContextDeleter::operator()(ServiceContext* service) const {
+ onDestroy(service, registeredConstructorActions());
+ delete service;
+}
+
} // namespace mongo
diff --git a/src/mongo/db/service_context.h b/src/mongo/db/service_context.h
index 73b272470e6..24905f2fc4d 100644
--- a/src/mongo/db/service_context.h
+++ b/src/mongo/db/service_context.h
@@ -28,14 +28,17 @@
#pragma once
+#include <boost/optional.hpp>
#include <vector>
#include "mongo/base/disallow_copying.h"
+#include "mongo/base/global_initializer_registerer.h"
#include "mongo/db/logical_session_id.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/functional.h"
+#include "mongo/stdx/list.h"
#include "mongo/stdx/memory.h"
#include "mongo/stdx/mutex.h"
#include "mongo/stdx/unordered_set.h"
@@ -89,20 +92,11 @@ protected:
* A ServiceContext is the root of a hierarchy of contexts. A ServiceContext owns
* zero or more Clients, which in turn each own OperationContexts.
*/
-class ServiceContext : public Decorable<ServiceContext> {
+class ServiceContext final : public Decorable<ServiceContext> {
MONGO_DISALLOW_COPYING(ServiceContext);
public:
/**
- * Special deleter used for cleaning up Client objects owned by a ServiceContext.
- * See UniqueClient, below.
- */
- class ClientDeleter {
- public:
- void operator()(Client* client) const;
- };
-
- /**
* Observer interface implemented to hook client and operation context creation and
* destruction.
*/
@@ -172,12 +166,23 @@ public:
};
/**
- * Special deleter used for cleaning up OperationContext objects owned by a ServiceContext.
- * See UniqueOperationContext, below.
+ * Special deleter used for cleaning up ServiceContext objects.
+ * See UniqueServiceContext, below.
*/
- class OperationContextDeleter {
+ class ServiceContextDeleter {
public:
- void operator()(OperationContext* opCtx) const;
+ void operator()(ServiceContext* service) const;
+ };
+
+ using UniqueServiceContext = std::unique_ptr<ServiceContext, ServiceContextDeleter>;
+
+ /**
+ * Special deleter used for cleaning up Client objects owned by a ServiceContext.
+ * See UniqueClient, below.
+ */
+ class ClientDeleter {
+ public:
+ void operator()(Client* client) const;
};
/**
@@ -186,11 +191,96 @@ public:
using UniqueClient = std::unique_ptr<Client, ClientDeleter>;
/**
+ * Special deleter used for cleaning up OperationContext objects owned by a ServiceContext.
+ * See UniqueOperationContext, below.
+ */
+ class OperationContextDeleter {
+ public:
+ void operator()(OperationContext* opCtx) const;
+ };
+
+ /**
* This is the unique handle type for OperationContexts created by a ServiceContext.
*/
using UniqueOperationContext = std::unique_ptr<OperationContext, OperationContextDeleter>;
- virtual ~ServiceContext();
+ /**
+ * Register a function of this type using an instance of ConstructorActionRegisterer,
+ * below, to cause the function to be executed on new ServiceContext instances.
+ */
+ using ConstructorAction = stdx::function<void(ServiceContext*)>;
+
+ /**
+ * Register a function of this type using an instance of ConstructorActionRegisterer,
+ * below, to cause the function to be executed on ServiceContext instances before they
+ * are destroyed.
+ */
+ using DestructorAction = stdx::function<void(ServiceContext*) noexcept>;
+
+ /**
+ * Representation of a paired ConstructorAction and DestructorAction.
+ */
+ class ConstructorDestructorActions {
+ public:
+ ConstructorDestructorActions(ConstructorAction constructor, DestructorAction destructor)
+ : _constructor(std::move(constructor)), _destructor(std::move(destructor)) {}
+
+ void onCreate(ServiceContext* service) const {
+ _constructor(service);
+ }
+ void onDestroy(ServiceContext* service) const {
+ _destructor(service);
+ }
+
+ private:
+ ConstructorAction _constructor;
+ DestructorAction _destructor;
+ };
+
+ /**
+ * Registers a function to execute on new service contexts when they are created, and optionally
+ * also register a function to execute before those contexts are destroyed.
+ *
+ * Construct instances of this type during static initialization only, as they register
+ * MONGO_INITIALIZERS.
+ */
+ class ConstructorActionRegisterer {
+ public:
+ /**
+ * This constructor registers a constructor and optional destructor with the given
+ * "name" and no prerequisite constructors or mongo initializers.
+ */
+ ConstructorActionRegisterer(std::string name,
+ ConstructorAction constructor,
+ DestructorAction destructor = {});
+
+ /**
+ * This constructor registers a constructor and optional destructor with the given
+ * "name", and a list of names of prerequisites, "prereqs".
+ *
+ * The named constructor will run after all of its prereqs successfully complete,
+ * and the corresponding destructor, if provided, will run before any of its
+ * prerequisites execute.
+ */
+ ConstructorActionRegisterer(std::string name,
+ std::vector<std::string> prereqs,
+ ConstructorAction constructor,
+ DestructorAction destructor = {});
+
+ private:
+ using ConstructorActionListIterator = stdx::list<ConstructorDestructorActions>::iterator;
+ ConstructorActionListIterator _iter;
+ boost::optional<GlobalInitializerRegisterer> _registerer;
+ };
+
+ /**
+ * Factory function for making instances of ServiceContext. It is the only means by which they
+ * should be created.
+ */
+ static UniqueServiceContext make();
+
+ ServiceContext();
+ ~ServiceContext();
/**
* Registers an observer of lifecycle events on Clients created by this ServiceContext.
@@ -411,20 +501,29 @@ public:
*/
void setServiceExecutor(std::unique_ptr<transport::ServiceExecutor> exec);
-protected:
- ServiceContext();
+private:
+ class ClientObserverHolder {
+ public:
+ explicit ClientObserverHolder(std::unique_ptr<ClientObserver> observer)
+ : _observer(std::move(observer)) {}
+ void onCreate(Client* client) const {
+ _observer->onCreateClient(client);
+ }
+ void onDestroy(Client* client) const {
+ _observer->onDestroyClient(client);
+ }
+ void onCreate(OperationContext* opCtx) const {
+ _observer->onCreateOperationContext(opCtx);
+ }
+ void onDestroy(OperationContext* opCtx) const {
+ _observer->onDestroyOperationContext(opCtx);
+ }
- /**
- * Mutex used to synchronize access to mutable state of this ServiceContext instance,
- * including possibly by its subclasses.
- */
- stdx::mutex _mutex;
+ private:
+ std::unique_ptr<ClientObserver> _observer;
+ };
-private:
- /**
- * Returns a new OperationContext. Private, for use by makeOperationContext.
- */
- virtual std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) = 0;
+ stdx::mutex _mutex;
/**
* The storage engine, if any.
@@ -454,7 +553,7 @@ private:
/**
* Vector of registered observers.
*/
- std::vector<std::unique_ptr<ClientObserver>> _clientObservers;
+ std::vector<ClientObserverHolder> _clientObservers;
ClientSet _clients;
/**
@@ -503,23 +602,12 @@ bool hasGlobalServiceContext();
ServiceContext* getGlobalServiceContext();
/**
- * Warning - This function is temporary. Do not introduce new uses of this API.
- *
- * Returns the singleton ServiceContext for this server process.
- *
- * Waits until there is a valid global ServiceContext.
- *
- * Caller does not own pointer.
- */
-ServiceContext* waitAndGetGlobalServiceContext();
-
-/**
* Sets the global ServiceContext. If 'serviceContext' is NULL, un-sets and deletes
* the current global ServiceContext.
*
* Takes ownership of 'serviceContext'.
*/
-void setGlobalServiceContext(std::unique_ptr<ServiceContext>&& serviceContext);
+void setGlobalServiceContext(ServiceContext::UniqueServiceContext&& serviceContext);
/**
* Shortcut for querying the storage engine about whether it supports document-level locking.
diff --git a/src/mongo/db/service_context_d.cpp b/src/mongo/db/service_context_d.cpp
deleted file mode 100644
index b4595b97c98..00000000000
--- a/src/mongo/db/service_context_d.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (C) 2014 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.
- */
-
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/db/service_context_d.h"
-
-#include "mongo/base/init.h"
-#include "mongo/base/initializer.h"
-#include "mongo/db/client.h"
-#include "mongo/db/concurrency/lock_state.h"
-#include "mongo/db/operation_context.h"
-#include "mongo/db/service_context_registrar.h"
-#include "mongo/db/service_entry_point_mongod.h"
-#include "mongo/db/storage/storage_engine.h"
-#include "mongo/db/storage/storage_engine_lock_file.h"
-#include "mongo/db/storage/storage_engine_metadata.h"
-#include "mongo/db/storage/storage_options.h"
-#include "mongo/stdx/memory.h"
-#include "mongo/util/log.h"
-#include "mongo/util/map_util.h"
-#include "mongo/util/mongoutils/str.h"
-#include "mongo/util/scopeguard.h"
-#include "mongo/util/system_clock_source.h"
-#include "mongo/util/system_tick_source.h"
-
-namespace mongo {
-namespace {
-ServiceContextRegistrar serviceContextCreator([]() {
- auto service = std::make_unique<ServiceContextMongoD>();
- service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service.get()));
- service->setTickSource(std::make_unique<SystemTickSource>());
- service->setFastClockSource(std::make_unique<SystemClockSource>());
- service->setPreciseClockSource(std::make_unique<SystemClockSource>());
- return service;
-});
-} // namespace
-
-extern bool _supportsDocLocking;
-
-ServiceContextMongoD::ServiceContextMongoD() = default;
-
-ServiceContextMongoD::~ServiceContextMongoD() = default;
-
-std::unique_ptr<OperationContext> ServiceContextMongoD::_newOpCtx(Client* client, unsigned opId) {
- invariant(&cc() == client);
- auto opCtx = stdx::make_unique<OperationContext>(client, opId);
-
- if (isMMAPV1()) {
- opCtx->setLockState(stdx::make_unique<MMAPV1LockerImpl>());
- } else {
- opCtx->setLockState(stdx::make_unique<DefaultLockerImpl>());
- }
-
- opCtx->setRecoveryUnit(getStorageEngine()->newRecoveryUnit(),
- WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork);
- return opCtx;
-}
-
-} // namespace mongo
diff --git a/src/mongo/db/service_context_d.h b/src/mongo/db/service_context_d.h
deleted file mode 100644
index dfab1926390..00000000000
--- a/src/mongo/db/service_context_d.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (C) 2014 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.
- */
-
-#pragma once
-
-#include "mongo/db/service_context.h"
-
-namespace mongo {
-
-class Client;
-class StorageEngineLockFile;
-
-class ServiceContextMongoD final : public ServiceContext {
-public:
- ServiceContextMongoD();
-
- ~ServiceContextMongoD();
-
-private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
-};
-
-} // namespace mongo
diff --git a/src/mongo/db/service_context_d_test_fixture.cpp b/src/mongo/db/service_context_d_test_fixture.cpp
index 185728b19bb..1965c44a2a8 100644
--- a/src/mongo/db/service_context_d_test_fixture.cpp
+++ b/src/mongo/db/service_context_d_test_fixture.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2016 MongoDB Inc.
+ * Copyright (C) 2016-2018 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,
@@ -30,50 +30,46 @@
#include "mongo/db/service_context_d_test_fixture.h"
+#include <memory>
+
#include "mongo/base/checked_cast.h"
-#include "mongo/db/catalog/database.h"
-#include "mongo/db/catalog/database_holder.h"
+#include "mongo/db/catalog/catalog_control.h"
#include "mongo/db/catalog/uuid_catalog.h"
-#include "mongo/db/client.h"
-#include "mongo/db/concurrency/write_conflict_exception.h"
-#include "mongo/db/curop.h"
-#include "mongo/db/db_raii.h"
+#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/logical_clock.h"
-#include "mongo/db/op_observer_noop.h"
#include "mongo/db/op_observer_registry.h"
-#include "mongo/db/service_context_d.h"
+#include "mongo/db/service_entry_point_mongod.h"
#include "mongo/db/storage/storage_engine_init.h"
#include "mongo/db/storage/storage_options.h"
-#include "mongo/stdx/memory.h"
-#include "mongo/unittest/temp_dir.h"
#include "mongo/util/assert_util.h"
-#include "mongo/util/scopeguard.h"
#include "mongo/db/catalog/database_holder.h"
namespace mongo {
-void ServiceContextMongoDTest::setUp() {
- Test::setUp();
- Client::initThread(getThreadName());
+ServiceContextMongoDTest::ServiceContextMongoDTest()
+ : ServiceContextMongoDTest("ephemeralForTest") {}
- auto const serviceContext = getServiceContext();
+ServiceContextMongoDTest::ServiceContextMongoDTest(std::string engine)
+ : ServiceContextMongoDTest(engine, RepairAction::kNoRepair) {}
+
+ServiceContextMongoDTest::ServiceContextMongoDTest(std::string engine, RepairAction repair)
+ : _tempDir("service_context_d_test_fixture") {
- auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext);
+ _stashedStorageParams.engine = std::exchange(storageGlobalParams.engine, std::move(engine));
+ _stashedStorageParams.engineSetByUser =
+ std::exchange(storageGlobalParams.engineSetByUser, true);
+ _stashedStorageParams.repair =
+ std::exchange(storageGlobalParams.repair, (repair == RepairAction::kRepair));
+
+ auto const serviceContext = getServiceContext();
+ serviceContext->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(serviceContext));
+ auto logicalClock = std::make_unique<LogicalClock>(serviceContext);
LogicalClock::set(serviceContext, std::move(logicalClock));
- if (!serviceContext->getStorageEngine()) {
- // When using the "ephemeralForTest" storage engine, it is fine for the temporary directory
- // to go away after the global storage engine is initialized.
- unittest::TempDir tempDir("service_context_d_test_fixture");
- storageGlobalParams.dbpath = tempDir.path();
- storageGlobalParams.engine = "ephemeralForTest";
- storageGlobalParams.engineSetByUser = true;
-
- createLockFile(serviceContext);
- initializeStorageEngine(serviceContext, StorageEngineInitFlags::kNone);
- serviceContext->setOpObserver(stdx::make_unique<OpObserverNoop>());
- }
+ storageGlobalParams.dbpath = _tempDir.path();
+
+ initializeStorageEngine(serviceContext, StorageEngineInitFlags::kNone);
// Set up UUID Catalog observer. This is necessary because the Collection destructor contains an
// invariant to ensure the UUID corresponding to that Collection object is no longer associated
@@ -81,44 +77,20 @@ void ServiceContextMongoDTest::setUp() {
// directly in certain code paths, but they can only be removed from the UUIDCatalog via a
// UUIDCatalogObserver. It is therefore necessary to install the observer to ensure the
// invariant in the Collection destructor is not triggered.
- auto observerRegistry = stdx::make_unique<OpObserverRegistry>();
- observerRegistry->addObserver(stdx::make_unique<UUIDCatalogObserver>());
- serviceContext->setOpObserver(std::unique_ptr<OpObserver>(observerRegistry.release()));
+ auto observerRegistry = checked_cast<OpObserverRegistry*>(serviceContext->getOpObserver());
+ observerRegistry->addObserver(std::make_unique<UUIDCatalogObserver>());
}
-void ServiceContextMongoDTest::tearDown() {
- ON_BLOCK_EXIT([&] { Client::destroy(); });
- auto opCtx = cc().makeOperationContext();
- _dropAllDBs(opCtx.get());
- Test::tearDown();
-}
-
-ServiceContext* ServiceContextMongoDTest::getServiceContext() {
- return getGlobalServiceContext();
-}
-
-void ServiceContextMongoDTest::_doTest() {
- MONGO_UNREACHABLE;
-}
-
-void ServiceContextMongoDTest::_dropAllDBs(OperationContext* opCtx) {
- Database::dropAllDatabasesExceptLocal(opCtx);
-
- Lock::GlobalWrite lk(opCtx);
- AutoGetDb autoDBLocal(opCtx, "local", MODE_X);
- const auto localDB = autoDBLocal.getDb();
- if (localDB) {
- writeConflictRetry(opCtx, "_dropAllDBs", "local", [&] {
- // Do not wrap in a WriteUnitOfWork until SERVER-17103 is addressed.
- autoDBLocal.getDb()->dropDatabase(opCtx, localDB);
- });
+ServiceContextMongoDTest::~ServiceContextMongoDTest() {
+ {
+ auto opCtx = getClient()->makeOperationContext();
+ Lock::GlobalLock glk(opCtx.get(), MODE_X);
+ DatabaseHolder::getDatabaseHolder().closeAll(opCtx.get(), "all databases dropped");
}
-
- // Database::dropAllDatabasesExceptLocal() does not close empty databases. However the holder
- // still allocates resources to track these empty databases. These resources not released by
- // Database::dropAllDatabasesExceptLocal() will be leaked at exit unless we call
- // DatabaseHolder::closeAll.
- DatabaseHolder::getDatabaseHolder().closeAll(opCtx, "all databases dropped");
+ shutdownGlobalStorageEngineCleanly(getGlobalServiceContext());
+ std::swap(storageGlobalParams.engine, _stashedStorageParams.engine);
+ std::swap(storageGlobalParams.engineSetByUser, _stashedStorageParams.engineSetByUser);
+ std::swap(storageGlobalParams.repair, _stashedStorageParams.repair);
}
} // namespace mongo
diff --git a/src/mongo/db/service_context_d_test_fixture.h b/src/mongo/db/service_context_d_test_fixture.h
index 35932b64814..63ee49e8d58 100644
--- a/src/mongo/db/service_context_d_test_fixture.h
+++ b/src/mongo/db/service_context_d_test_fixture.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2016 MongoDB Inc.
+ * Copyright (C) 2016-2018 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,
@@ -29,7 +29,8 @@
#pragma once
#include "mongo/db/operation_context.h"
-#include "mongo/db/service_context.h"
+#include "mongo/db/service_context_test_fixture.h"
+#include "mongo/unittest/temp_dir.h"
#include "mongo/unittest/unittest.h"
namespace mongo {
@@ -37,40 +38,26 @@ namespace mongo {
/**
* Test fixture class for tests that use either the "ephemeralForTest" or "devnull" storage engines.
*/
-class ServiceContextMongoDTest : public unittest::Test {
-public:
- /**
- * Initializes global storage engine.
- */
- void setUp() override;
+class ServiceContextMongoDTest : public ServiceContextTest {
+protected:
+ enum class RepairAction { kNoRepair, kRepair };
- /**
- * Clear all databases.
- */
- void tearDown() override;
+ ServiceContextMongoDTest();
/**
- * Returns a service context, which is only valid for this instance of the test.
- * Must not be called before setUp or after tearDown.
+ * Build a ServiceContextMongoDTest, using the named storage engine.
*/
- ServiceContext* getServiceContext();
+ explicit ServiceContextMongoDTest(std::string engine);
+ ServiceContextMongoDTest(std::string engine, RepairAction repair);
+ virtual ~ServiceContextMongoDTest();
private:
- /**
- * Unused implementation of test function. This allows us to instantiate
- * ServiceContextMongoDTest on its own without the need to inherit from it in a test.
- * This supports using ServiceContextMongoDTest inside another test fixture and works around the
- * limitation that tests cannot inherit from multiple test fixtures.
- *
- * It is an error to call this implementation of _doTest() directly.
- */
- void _doTest() override;
-
- /**
- * Drops all databases. Call this before global ReplicationCoordinator is destroyed -- it is
- * used to drop the databases.
- */
- void _dropAllDBs(OperationContext* opCtx);
+ struct {
+ std::string engine;
+ bool engineSetByUser;
+ bool repair;
+ } _stashedStorageParams;
+ unittest::TempDir _tempDir;
};
} // namespace mongo
diff --git a/src/mongo/db/service_context_noop.cpp b/src/mongo/db/service_context_noop.cpp
deleted file mode 100644
index e2cc4b7d41e..00000000000
--- a/src/mongo/db/service_context_noop.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (C) 2014 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/service_context_noop.h"
-
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/stdx/memory.h"
-
-namespace mongo {
-
-std::unique_ptr<OperationContext> ServiceContextNoop::_newOpCtx(Client* client, unsigned opId) {
- return stdx::make_unique<OperationContextNoop>(client, opId);
-}
-
-} // namespace mongo
diff --git a/src/mongo/db/service_context_noop.h b/src/mongo/db/service_context_noop.h
deleted file mode 100644
index 77e8119accd..00000000000
--- a/src/mongo/db/service_context_noop.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright (C) 2014 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.
- */
-
-#pragma once
-
-#include "mongo/db/service_context.h"
-
-namespace mongo {
-
-class ServiceContextNoop : public ServiceContext {
-private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
-};
-
-} // namespace mongo
diff --git a/src/mongo/db/service_context_noop_init.cpp b/src/mongo/db/service_context_noop_init.cpp
deleted file mode 100644
index 27e4306ad49..00000000000
--- a/src/mongo/db/service_context_noop_init.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2015 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/base/init.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
-#include "mongo/db/service_context_registrar.h"
-#include "mongo/stdx/memory.h"
-
-
-namespace mongo {
-namespace {
-
-ServiceContextRegistrar serviceContextEmbeddedFactory([]() {
- return std::make_unique<ServiceContextNoop>();
-});
-
-} // namespace
-} // namespace mongo
diff --git a/src/mongo/db/service_context_registrar.cpp b/src/mongo/db/service_context_registrar.cpp
deleted file mode 100644
index 061936c98ec..00000000000
--- a/src/mongo/db/service_context_registrar.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * Copyright (C) 2018 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/service_context_registrar.h"
-
-#include "mongo/base/init.h"
-#include "mongo/db/service_context.h"
-
-namespace mongo {
-namespace {
-std::function<std::unique_ptr<ServiceContext>()>& getServiceContextFactory() {
- static std::function<std::unique_ptr<ServiceContext>()> factory;
- return factory;
-}
-
-// clang-format off
-GlobalInitializerRegisterer registerCreateServiceContext{
- "ServiceContext",
- {"default"},
- [](InitializerContext* context) {
- // Set the global service context if a service context factory was previously registered.
- if (getServiceContextFactory()) {
- setGlobalServiceContext(getServiceContextFactory()());
- }
- 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
-
-} // namespace
-
-ServiceContextRegistrar::ServiceContextRegistrar(
- std::function<std::unique_ptr<ServiceContext>()> fn) {
- invariant(!getServiceContextFactory());
- getServiceContextFactory() = std::move(fn);
-}
-
-} // namespace mongo
diff --git a/src/mongo/db/service_context_registrar.h b/src/mongo/db/service_context_registrar.h
deleted file mode 100644
index 72f6e6ea2dd..00000000000
--- a/src/mongo/db/service_context_registrar.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
-* Copyright (C) 2018 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.
-*/
-
-#pragma once
-
-#include <functional>
-#include <memory>
-
-namespace mongo {
-class ServiceContext;
-
-// This is a initialization registration system similar to MONGO_INITIALIZER. But it cannot be an
-// MONGO_INITIALIZER because we need to create the service context before the MONGO_INITIALIZERS
-// execute. This class should probably be refactored to use the shim system from this ticket:
-// https://jira.mongodb.org/browse/SERVER-32645
-class ServiceContextRegistrar {
-public:
- explicit ServiceContextRegistrar(std::function<std::unique_ptr<ServiceContext>()> fn);
-};
-
-} // namespace mongo
diff --git a/src/mongo/db/repl/service_context_repl_mock_init.cpp b/src/mongo/db/service_context_test_fixture.cpp
index c35b47f61d7..e9aba482801 100644
--- a/src/mongo/db/repl/service_context_repl_mock_init.cpp
+++ b/src/mongo/db/service_context_test_fixture.cpp
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2016 MongoDB Inc.
+/**
+ * Copyright (C) 2016-2018 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,
@@ -28,22 +28,41 @@
#include "mongo/platform/basic.h"
-#include "mongo/base/init.h"
-#include "mongo/db/repl/service_context_repl_mock.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_registrar.h"
-#include "mongo/util/clock_source_mock.h"
+#include "mongo/db/service_context_test_fixture.h"
#include <memory>
+#include "mongo/db/client.h"
+#include "mongo/db/op_observer_registry.h"
+#include "mongo/util/assert_util.h"
+
namespace mongo {
-namespace repl {
-namespace {
-ServiceContextRegistrar serviceContextCreator([]() {
- return std::make_unique<ServiceContextReplMock>();
-});
+ScopedGlobalServiceContextForTest::ScopedGlobalServiceContextForTest() {
+ setGlobalServiceContext(ServiceContext::make());
+ auto const serviceContext = getGlobalServiceContext();
+ auto observerRegistry = std::make_unique<OpObserverRegistry>();
+ serviceContext->setOpObserver(std::move(observerRegistry));
+}
+
+ScopedGlobalServiceContextForTest::~ScopedGlobalServiceContextForTest() {
+ setGlobalServiceContext({});
+}
+
+ServiceContext* ScopedGlobalServiceContextForTest::getServiceContext() {
+ return getGlobalServiceContext();
+}
+
+ServiceContextTest::ServiceContextTest() {
+ Client::initThread(getThreadName());
+}
+
+ServiceContextTest::~ServiceContextTest() {
+ Client::destroy();
+}
+
+Client* ServiceContextTest::getClient() {
+ return Client::getCurrent();
+}
-} // namespace
-} // namespace repl
} // namespace mongo
diff --git a/src/mongo/embedded/service_context_embedded.h b/src/mongo/db/service_context_test_fixture.h
index 3f697ec9a91..8588b1e18e5 100644
--- a/src/mongo/embedded/service_context_embedded.h
+++ b/src/mongo/db/service_context_test_fixture.h
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2018 MongoDB Inc.
+ * Copyright (C) 2016-2018 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,
@@ -28,21 +28,43 @@
#pragma once
+#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
+#include "mongo/unittest/unittest.h"
namespace mongo {
-class Client;
-class StorageEngineLockFile;
-class ServiceContextMongoEmbedded final : public ServiceContext {
+class ScopedGlobalServiceContextForTest {
public:
- ServiceContextMongoEmbedded();
+ /**
+ * 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();
- ~ServiceContextMongoEmbedded();
+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.
+ */
+ Client* getClient();
+
+ ServiceContext::UniqueOperationContext makeOperationContext() {
+ return getClient()->makeOperationContext();
+ }
-private:
- std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override;
+protected:
+ ServiceContextTest();
+ virtual ~ServiceContextTest();
};
} // namespace mongo
diff --git a/src/mongo/db/service_liaison_mock.h b/src/mongo/db/service_liaison_mock.h
index 26aaf611589..177f0f8ba7c 100644
--- a/src/mongo/db/service_liaison_mock.h
+++ b/src/mongo/db/service_liaison_mock.h
@@ -29,7 +29,6 @@
#pragma once
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/db/service_liaison.h"
#include "mongo/executor/async_timer_mock.h"
#include "mongo/platform/atomic_word.h"
@@ -132,7 +131,7 @@ protected:
private:
std::shared_ptr<MockServiceLiaisonImpl> _impl;
- std::unique_ptr<ServiceContextNoop> _serviceContext;
+ ServiceContext::UniqueServiceContext _serviceContext;
};
} // namespace mongo
diff --git a/src/mongo/db/session_catalog_test.cpp b/src/mongo/db/session_catalog_test.cpp
index f6e04a2d016..1d4ba8ec87d 100644
--- a/src/mongo/db/session_catalog_test.cpp
+++ b/src/mongo/db/session_catalog_test.cpp
@@ -39,6 +39,7 @@
#include "mongo/stdx/memory.h"
#include "mongo/unittest/death_test.h"
#include "mongo/unittest/unittest.h"
+#include "mongo/util/scopeguard.h"
namespace mongo {
namespace {
@@ -120,6 +121,7 @@ TEST_F(SessionCatalogTest, GetOrCreateSessionAfterCheckOutSession) {
ocs.emplace(opCtx(), true, boost::none, false, "testDB", "insert");
stdx::async(stdx::launch::async, [&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto sideOpCtx = Client::getCurrent()->makeOperationContext();
auto scopedSession =
@@ -132,6 +134,7 @@ TEST_F(SessionCatalogTest, GetOrCreateSessionAfterCheckOutSession) {
ocs.reset();
stdx::async(stdx::launch::async, [&] {
+ ON_BLOCK_EXIT([&] { Client::destroy(); });
Client::initThreadIfNotAlready();
auto sideOpCtx = Client::getCurrent()->makeOperationContext();
auto scopedSession =
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 3ba4e8a98c3..0af136f0c63 100644
--- a/src/mongo/db/sorter/sorter_test.cpp
+++ b/src/mongo/db/sorter/sorter_test.cpp
@@ -36,9 +36,7 @@
#include "mongo/base/init.h"
#include "mongo/base/static_assert.h"
#include "mongo/config.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
-#include "mongo/db/service_context_registrar.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/stdx/thread.h"
#include "mongo/unittest/temp_dir.h"
#include "mongo/unittest/unittest.h"
@@ -54,14 +52,6 @@ using namespace mongo::sorter;
using std::make_shared;
using std::pair;
-namespace {
-
-// Stub to avoid including the server environment library.
-ServiceContextRegistrar serviceContextCreator([]() {
- return std::make_unique<ServiceContextNoop>();
-});
-} // namespace
-
//
// Sorter framework testing utilities
//
@@ -249,7 +239,7 @@ public:
}
};
-class SortedFileWriterAndFileIteratorTests {
+class SortedFileWriterAndFileIteratorTests : public ScopedGlobalServiceContextForTest {
public:
void run() {
unittest::TempDir tempDir("sortedFileWriterTests");
@@ -335,7 +325,7 @@ public:
};
namespace SorterTests {
-class Basic {
+class Basic : public ScopedGlobalServiceContextForTest {
public:
virtual ~Basic() {}
diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript
index b3fe81322ec..f38bc6ef834 100644
--- a/src/mongo/db/storage/SConscript
+++ b/src/mongo/db/storage/SConscript
@@ -199,6 +199,7 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/service_context',
+ '$BUILD_DIR/mongo/db/concurrency/lock_manager',
'storage_engine_lock_file',
'storage_engine_metadata',
'storage_options',
diff --git a/src/mongo/db/storage/devnull/devnull_init.cpp b/src/mongo/db/storage/devnull/devnull_init.cpp
index 68e80902d29..e6272dbb163 100644
--- a/src/mongo/db/storage/devnull/devnull_init.cpp
+++ b/src/mongo/db/storage/devnull/devnull_init.cpp
@@ -31,7 +31,6 @@
#include "mongo/base/init.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
#include "mongo/db/storage/devnull/devnull_kv_engine.h"
#include "mongo/db/storage/kv/kv_storage_engine.h"
#include "mongo/db/storage/storage_engine_init.h"
@@ -65,10 +64,8 @@ public:
};
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(DevNullEngineInit, ("ServiceContext"))
-(InitializerContext* context) {
- registerStorageEngine(getGlobalServiceContext(),
- std::make_unique<DevNullStorageEngineFactory>());
- return Status::OK();
-}
+ServiceContext::ConstructorActionRegisterer registerDevNull(
+ "RegisterDevNullEngine", [](ServiceContext* service) {
+ registerStorageEngine(service, std::make_unique<DevNullStorageEngineFactory>());
+ });
} // namespace mongo
diff --git a/src/mongo/db/storage/encryption_hooks.cpp b/src/mongo/db/storage/encryption_hooks.cpp
index ffa7f319a06..c703c80fda4 100644
--- a/src/mongo/db/storage/encryption_hooks.cpp
+++ b/src/mongo/db/storage/encryption_hooks.cpp
@@ -40,30 +40,21 @@
namespace mongo {
-/* Make a EncryptionHooks pointer a decoration on the global ServiceContext */
-GlobalInitializerRegisterer encryptionHooksInitializer(
- "SetEncryptionHooks",
- {"ServiceContext"},
- [](InitializerContext* context) {
- EncryptionHooks::set(getGlobalServiceContext(), stdx::make_unique<EncryptionHooks>());
- return Status::OK();
- },
- [](DeinitializerContext* context) {
- EncryptionHooks::set(getGlobalServiceContext(), nullptr);
- return Status::OK();
- });
-
namespace {
-const auto getEncryptionHooks =
- ServiceContext::declareDecoration<std::unique_ptr<EncryptionHooks>>();
+
+struct EncryptionHooksHolder {
+ std::unique_ptr<EncryptionHooks> ptr = std::make_unique<EncryptionHooks>();
+};
+
+const auto getEncryptionHooks = ServiceContext::declareDecoration<EncryptionHooksHolder>();
} // namespace
void EncryptionHooks::set(ServiceContext* service, std::unique_ptr<EncryptionHooks> custHooks) {
- getEncryptionHooks(service) = std::move(custHooks);
+ getEncryptionHooks(service).ptr = std::move(custHooks);
}
EncryptionHooks* EncryptionHooks::get(ServiceContext* service) {
- return getEncryptionHooks(service).get();
+ return getEncryptionHooks(service).ptr.get();
}
EncryptionHooks::~EncryptionHooks() {}
diff --git a/src/mongo/db/storage/ephemeral_for_test/SConscript b/src/mongo/db/storage/ephemeral_for_test/SConscript
index 0b1c846d3a6..add504fffc0 100644
--- a/src/mongo/db/storage/ephemeral_for_test/SConscript
+++ b/src/mongo/db/storage/ephemeral_for_test/SConscript
@@ -80,6 +80,5 @@ env.CppUnitTest(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/repl/service_context_repl_mock_init',
],
)
diff --git a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp
index a4de16caf63..fa23b283c3a 100644
--- a/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp
+++ b/src/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_init.cpp
@@ -29,7 +29,6 @@
#include "mongo/platform/basic.h"
-#include "mongo/base/init.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/ephemeral_for_test/ephemeral_for_test_engine.h"
#include "mongo/db/storage/kv/kv_storage_engine.h"
@@ -69,12 +68,10 @@ public:
}
};
-} // namespace
-
-MONGO_INITIALIZER_WITH_PREREQUISITES(EphemeralForTestEngineInit, ("ServiceContext"))
-(InitializerContext* context) {
- registerStorageEngine(getGlobalServiceContext(), std::make_unique<EphemeralForTestFactory>());
- return Status::OK();
-}
+ServiceContext::ConstructorActionRegisterer registerEphemeralForTest(
+ "RegisterEphemeralForTestEngine", [](ServiceContext* service) {
+ registerStorageEngine(service, std::make_unique<EphemeralForTestFactory>());
+ });
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/storage/kv/SConscript b/src/mongo/db/storage/kv/SConscript
index d8e8f7665f7..384738813c0 100644
--- a/src/mongo/db/storage/kv/SConscript
+++ b/src/mongo/db/storage/kv/SConscript
@@ -96,6 +96,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/service_context',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/db/storage/storage_options',
'$BUILD_DIR/mongo/unittest/unittest',
'$BUILD_DIR/mongo/util/clock_source_mock',
@@ -113,7 +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_noop_init',
+ '$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,7 +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_noop_init',
+ '$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/kv/kv_engine_test_timestamps.cpp b/src/mongo/db/storage/kv/kv_engine_test_timestamps.cpp
index 0e8384a4afe..d2c24f3b44e 100644
--- a/src/mongo/db/storage/kv/kv_engine_test_timestamps.cpp
+++ b/src/mongo/db/storage/kv/kv_engine_test_timestamps.cpp
@@ -35,7 +35,7 @@
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/repl/read_concern_level.h"
#include "mongo/db/repl/replication_coordinator.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/db/storage/kv/kv_engine.h"
#include "mongo/db/storage/record_store.h"
#include "mongo/db/storage/snapshot_manager.h"
@@ -46,7 +46,7 @@
namespace mongo {
namespace {
-class SnapshotManagerTests : public unittest::Test {
+class SnapshotManagerTests : public ServiceContextTest {
public:
/**
* Usable as an OperationContext* but owns both the Client and the OperationContext.
@@ -89,7 +89,8 @@ public:
};
Operation makeOperation() {
- return Operation(service.makeClient(""), helper->getEngine()->newRecoveryUnit());
+ return Operation(getServiceContext()->makeClient(""),
+ helper->getEngine()->newRecoveryUnit());
}
// Returns the timestamp before incrementing.
@@ -200,7 +201,6 @@ public:
ASSERT(rs);
}
- ServiceContextNoop service;
std::unique_ptr<KVHarnessHelper> helper;
KVEngine* engine;
SnapshotManager* snapshotManager;
diff --git a/src/mongo/db/storage/kv/kv_storage_engine_test.cpp b/src/mongo/db/storage/kv/kv_storage_engine_test.cpp
index 6d106ca45c5..b89329fee0f 100644
--- a/src/mongo/db/storage/kv/kv_storage_engine_test.cpp
+++ b/src/mongo/db/storage/kv/kv_storage_engine_test.cpp
@@ -28,6 +28,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/base/checked_cast.h"
#include "mongo/base/status_with.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/db_raii.h"
@@ -51,26 +52,13 @@
namespace mongo {
namespace {
-class KVStorageEngineTest : public unittest::Test {
+class KVStorageEngineTest : public ServiceContextMongoDTest {
public:
- enum class RepairAction { kNoRepair, kRepair };
-
KVStorageEngineTest() : KVStorageEngineTest(RepairAction::kNoRepair) {}
- KVStorageEngineTest(RepairAction repair) {
- KVStorageEngineOptions options;
- options.forRepair = (repair == RepairAction::kRepair);
- _storageEngine.reset(new KVStorageEngine(new EphemeralForTestEngine(), options));
- }
-
- void setUp() final {
- _serviceContext.setUp();
- }
-
- void tearDown() final {
- _storageEngine->cleanShutdown();
- _serviceContext.tearDown();
- }
+ KVStorageEngineTest(RepairAction repair)
+ : ServiceContextMongoDTest("ephemeralForTest", repair),
+ _storageEngine(checked_cast<KVStorageEngine*>(getServiceContext()->getStorageEngine())) {}
/**
* Create a collection in the catalog and in the KVEngine. Return the storage engine's `ident`.
@@ -153,8 +141,7 @@ public:
return Status::OK();
}
- ServiceContextMongoDTest _serviceContext;
- std::unique_ptr<KVStorageEngine> _storageEngine;
+ KVStorageEngine* _storageEngine;
};
class KVStorageEngineRepairTest : public KVStorageEngineTest {
diff --git a/src/mongo/db/storage/mmap_v1/SConscript b/src/mongo/db/storage/mmap_v1/SConscript
index 857bcfac99f..9c04fa3344f 100644
--- a/src/mongo/db/storage/mmap_v1/SConscript
+++ b/src/mongo/db/storage/mmap_v1/SConscript
@@ -224,6 +224,7 @@ if mmapv1:
'$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',
],
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp
index 42ba6cb864c..d70dc497a79 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_init.cpp
@@ -77,10 +77,9 @@ public:
} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(MMAPV1EngineInit, ("ServiceContext"))
-(InitializerContext* context) {
- registerStorageEngine(getGlobalServiceContext(), std::make_unique<MMAPV1Factory>());
- return Status::OK();
-}
+ServiceContext::ConstructorActionRegisterer registerMMAPV1EngineInit{
+ "MMAPV1EngineInit", [](ServiceContext* service) {
+ registerStorageEngine(service, std::make_unique<MMAPV1Factory>());
+ }};
} // namespace mongo
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_init_test.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_init_test.cpp
index dff7166e77a..b8916e02a36 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_init_test.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_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"
@@ -41,13 +42,13 @@ namespace {
using namespace mongo;
-class MMAPV1FactoryTest : public mongo::unittest::Test {
+class MMAPV1FactoryTest : public ServiceContextTest {
private:
virtual void setUp() {
- ServiceContext* globalEnv = getGlobalServiceContext();
- ASSERT_TRUE(globalEnv);
- ASSERT_TRUE(isRegisteredStorageEngine(globalEnv, "mmapv1"));
- factory = getFactoryForStorageEngine(globalEnv, "mmapv1");
+ ServiceContext* sc = getServiceContext();
+ ASSERT_TRUE(sc);
+ ASSERT_TRUE(isRegisteredStorageEngine(sc, "mmapv1"));
+ factory = getFactoryForStorageEngine(sc, "mmapv1");
ASSERT_TRUE(factory);
}
diff --git a/src/mongo/db/storage/mobile/SConscript b/src/mongo/db/storage/mobile/SConscript
index 5ff2276f1c0..5d627509ffd 100644
--- a/src/mongo/db/storage/mobile/SConscript
+++ b/src/mongo/db/storage/mobile/SConscript
@@ -92,6 +92,5 @@ env.CppUnitTest(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/repl/service_context_repl_mock_init',
],
)
diff --git a/src/mongo/db/storage/mobile/mobile_init.cpp b/src/mongo/db/storage/mobile/mobile_init.cpp
index 41a5dc83159..76e863993de 100644
--- a/src/mongo/db/storage/mobile/mobile_init.cpp
+++ b/src/mongo/db/storage/mobile/mobile_init.cpp
@@ -69,15 +69,10 @@ public:
return BSONObj();
}
};
-} // namespace
-
-GlobalInitializerRegisterer mobileKVEngineInitializer(
- "MobileKVEngineInit",
- {"ServiceContext"},
- [](InitializerContext* context) {
- registerStorageEngine(getGlobalServiceContext(), std::make_unique<MobileFactory>());
- return Status::OK();
- },
- [](DeinitializerContext* const) { return Status::OK(); });
+ServiceContext::ConstructorActionRegisterer mobileKVEngineInitializer{
+ "MobileKVEngineInit", [](ServiceContext* service) {
+ registerStorageEngine(service, std::make_unique<MobileFactory>());
+ }};
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/storage/record_store_test_harness.h b/src/mongo/db/storage/record_store_test_harness.h
index 8b6e35faf19..3f94ad76ad2 100644
--- a/src/mongo/db/storage/record_store_test_harness.h
+++ b/src/mongo/db/storage/record_store_test_harness.h
@@ -33,7 +33,7 @@
#include <cstdint>
#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/db/storage/test_harness_helper.h"
#include "mongo/stdx/memory.h"
diff --git a/src/mongo/db/storage/sorted_data_interface_test_harness.h b/src/mongo/db/storage/sorted_data_interface_test_harness.h
index 5966755397e..40b18e1ab56 100644
--- a/src/mongo/db/storage/sorted_data_interface_test_harness.h
+++ b/src/mongo/db/storage/sorted_data_interface_test_harness.h
@@ -35,7 +35,6 @@
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/record_id.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/db/storage/sorted_data_interface.h"
#include "mongo/db/storage/test_harness_helper.h"
#include "mongo/stdx/memory.h"
diff --git a/src/mongo/db/storage/storage_engine_init.cpp b/src/mongo/db/storage/storage_engine_init.cpp
index d69673679fb..2c4a526e64b 100644
--- a/src/mongo/db/storage/storage_engine_init.cpp
+++ b/src/mongo/db/storage/storage_engine_init.cpp
@@ -34,28 +34,38 @@
#include <map>
+#include "mongo/base/init.h"
#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/db/concurrency/lock_state.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/storage/storage_engine_lock_file.h"
#include "mongo/db/storage/storage_engine_metadata.h"
#include "mongo/db/storage/storage_options.h"
#include "mongo/db/unclean_shutdown.h"
+#include "mongo/stdx/memory.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
namespace mongo {
+namespace {
+/**
+ * Creates the lock file used to prevent concurrent processes from accessing the data files,
+ * as appropriate.
+ */
+void createLockFile(ServiceContext* service);
+} // namespace
+
extern bool _supportsDocLocking;
-void initializeStorageEngine(ServiceContext* service, StorageEngineInitFlags initFlags) {
+void initializeStorageEngine(ServiceContext* service, const StorageEngineInitFlags initFlags) {
// This should be set once.
invariant(!service->getStorageEngine());
- // We should have a lock file or be in read-only mode. Confusingly, we can still have a lockFile
- // if we are in read-only mode. This can happen if the server is started in read-only mode on a
- // writable dbpath.
- invariant((initFlags & StorageEngineInitFlags::kAllowNoLockFile) ||
- StorageEngineLockFile::get(service) || storageGlobalParams.readOnly);
+ if (0 == (initFlags & StorageEngineInitFlags::kAllowNoLockFile)) {
+ createLockFile(service);
+ }
const std::string dbpath = storageGlobalParams.dbpath;
if (auto existingStorageEngine = StorageEngineMetadata::getStorageEngineForPath(dbpath)) {
@@ -192,6 +202,8 @@ void shutdownGlobalStorageEngineCleanly(ServiceContext* service) {
}
}
+namespace {
+
void createLockFile(ServiceContext* service) {
auto& lockFile = StorageEngineLockFile::get(service);
try {
@@ -223,8 +235,6 @@ void createLockFile(ServiceContext* service) {
}
}
-namespace {
-
using FactoryMap = std::map<std::string, std::unique_ptr<StorageEngine::Factory>>;
auto storageFactories = ServiceContext::declareDecoration<FactoryMap>();
@@ -306,4 +316,40 @@ void appendStorageEngineList(ServiceContext* service, BSONObjBuilder* result) {
result->append("storageEngines", storageEngineList(service));
}
+namespace {
+
+class StorageClientObserver final : public ServiceContext::ClientObserver {
+public:
+ void onCreateClient(Client* client) override{};
+ void onDestroyClient(Client* client) override{};
+ void onCreateOperationContext(OperationContext* opCtx) {
+ auto service = opCtx->getServiceContext();
+ auto storageEngine = service->getStorageEngine();
+ // NOTE(schwerin): The following uassert would be more desirable than the early return when
+ // no storage engine is set, but to achieve that we would have to ensure that this file was
+ // never linked into a test binary that didn't actually need/use the storage engine.
+ //
+ // uassert(<some code>,
+ // "Must instantiate storage engine before creating OperationContext",
+ // storageEngine);
+ if (!storageEngine) {
+ return;
+ }
+ if (storageEngine->isMmapV1()) {
+ opCtx->setLockState(stdx::make_unique<MMAPV1LockerImpl>());
+ } else {
+ opCtx->setLockState(stdx::make_unique<DefaultLockerImpl>());
+ }
+ opCtx->setRecoveryUnit(storageEngine->newRecoveryUnit(),
+ WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork);
+ }
+ void onDestroyOperationContext(OperationContext* opCtx) {}
+};
+
+ServiceContext::ConstructorActionRegisterer registerStorageClientObserverConstructor{
+ "RegisterStorageClientObserverConstructor", [](ServiceContext* service) {
+ service->registerClientObserver(std::make_unique<StorageClientObserver>());
+ }};
+
+} // namespace
} // namespace mongo
diff --git a/src/mongo/db/storage/storage_engine_init.h b/src/mongo/db/storage/storage_engine_init.h
index 1cf30ff43ad..47e57d5b5cd 100644
--- a/src/mongo/db/storage/storage_engine_init.h
+++ b/src/mongo/db/storage/storage_engine_init.h
@@ -56,12 +56,6 @@ void initializeStorageEngine(ServiceContext* service, StorageEngineInitFlags ini
void shutdownGlobalStorageEngineCleanly(ServiceContext* service);
/**
- * Creates the lock file used to prevent concurrent processes from accessing the data files,
- * as appropriate.
- */
-void createLockFile(ServiceContext* service);
-
-/**
* Registers a storage engine onto the given "service".
*/
void registerStorageEngine(ServiceContext* service,
diff --git a/src/mongo/db/storage/test_harness_helper.cpp b/src/mongo/db/storage/test_harness_helper.cpp
index 62d99709c29..99f3b023847 100644
--- a/src/mongo/db/storage/test_harness_helper.cpp
+++ b/src/mongo/db/storage/test_harness_helper.cpp
@@ -37,15 +37,24 @@ namespace mongo {
namespace {
stdx::function<std::unique_ptr<HarnessHelper>()> basicHarnessFactory;
} // namespace
-} // namespace mongo
-mongo::HarnessHelper::~HarnessHelper() = default;
+HarnessHelper::HarnessHelper() {
+ setGlobalServiceContext(ServiceContext::make());
+ Client::initThread(getThreadName());
+}
+
+HarnessHelper::~HarnessHelper() {
+ Client::destroy();
+ setGlobalServiceContext({});
+}
-void mongo::registerHarnessHelperFactory(stdx::function<std::unique_ptr<HarnessHelper>()> factory) {
+void registerHarnessHelperFactory(stdx::function<std::unique_ptr<HarnessHelper>()> factory) {
basicHarnessFactory = std::move(factory);
}
-auto mongo::newHarnessHelper() -> std::unique_ptr<HarnessHelper> {
+auto newHarnessHelper() -> std::unique_ptr<HarnessHelper> {
return basicHarnessFactory();
}
+
+} // namespace mongo
diff --git a/src/mongo/db/storage/test_harness_helper.h b/src/mongo/db/storage/test_harness_helper.h
index 8ce241bcb3e..cd21223be1b 100644
--- a/src/mongo/db/storage/test_harness_helper.h
+++ b/src/mongo/db/storage/test_harness_helper.h
@@ -36,7 +36,6 @@
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/record_id.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/db/storage/sorted_data_interface.h"
#include "mongo/stdx/functional.h"
#include "mongo/stdx/memory.h"
@@ -45,9 +44,9 @@
namespace mongo {
class HarnessHelper {
public:
- virtual ~HarnessHelper() = 0;
+ virtual ~HarnessHelper();
- explicit HarnessHelper() = default;
+ explicit HarnessHelper();
virtual ServiceContext::UniqueOperationContext newOperationContext(Client* const client) {
auto opCtx = client->makeOperationContext();
@@ -57,26 +56,23 @@ public:
}
virtual ServiceContext::UniqueOperationContext newOperationContext() {
- return newOperationContext(_client.get());
+ return newOperationContext(client());
}
Client* client() const {
- return _client.get();
+ return Client::getCurrent();
}
ServiceContext* serviceContext() {
- return &_serviceContext;
+ return getGlobalServiceContext();
}
const ServiceContext* serviceContext() const {
- return &_serviceContext;
+ return getGlobalServiceContext();
}
private:
virtual std::unique_ptr<RecoveryUnit> newRecoveryUnit() = 0;
-
- ServiceContextNoop _serviceContext;
- ServiceContext::UniqueClient _client = _serviceContext.makeClient("hh");
};
namespace harness_helper_detail {
diff --git a/src/mongo/db/storage/wiredtiger/SConscript b/src/mongo/db/storage/wiredtiger/SConscript
index aee0fb5d8a5..25bd55e1bb1 100644
--- a/src/mongo/db/storage/wiredtiger/SConscript
+++ b/src/mongo/db/storage/wiredtiger/SConscript
@@ -127,6 +127,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_customization_hooks.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp
index 3d4d7ccb3cf..edc40080909 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.cpp
@@ -37,17 +37,14 @@
#include "mongo/stdx/memory.h"
namespace mongo {
+namespace {
-/* Make a WiredTigerCustomizationHooks pointer a decoration on the global ServiceContext */
-MONGO_INITIALIZER_WITH_PREREQUISITES(SetWiredTigerCustomizationHooks, ("ServiceContext"))
-(InitializerContext* context) {
- auto customizationHooks = stdx::make_unique<WiredTigerCustomizationHooks>();
- WiredTigerCustomizationHooks::set(getGlobalServiceContext(), std::move(customizationHooks));
-
- return Status::OK();
-}
+ServiceContext::ConstructorActionRegisterer setWiredTigerCustomizationHooks{
+ "SetWiredTigerCustomizationHooks", [](ServiceContext* service) {
+ auto customizationHooks = stdx::make_unique<WiredTigerCustomizationHooks>();
+ WiredTigerCustomizationHooks::set(service, std::move(customizationHooks));
+ }};
-namespace {
const auto getCustomizationHooks =
ServiceContext::declareDecoration<std::unique_ptr<WiredTigerCustomizationHooks>>();
} // namespace
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp
index b2df3f8c99c..c6e04dc0483 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.cpp
@@ -31,35 +31,18 @@
#include "mongo/db/storage/wiredtiger/wiredtiger_extensions.h"
-#include "mongo/base/init.h"
#include "mongo/base/string_data.h"
#include "mongo/db/service_context.h"
#include "mongo/stdx/memory.h"
namespace mongo {
-MONGO_INITIALIZER_WITH_PREREQUISITES(SetWiredTigerExtensions, ("ServiceContext"))
-(InitializerContext* context) {
- auto configHooks = stdx::make_unique<WiredTigerExtensions>();
- WiredTigerExtensions::set(getGlobalServiceContext(), std::move(configHooks));
-
- return Status::OK();
-}
-
namespace {
-const auto getConfigHooks =
- ServiceContext::declareDecoration<std::unique_ptr<WiredTigerExtensions>>();
+const auto getConfigHooks = ServiceContext::declareDecoration<WiredTigerExtensions>();
} // namespace
-void WiredTigerExtensions::set(ServiceContext* service,
- std::unique_ptr<WiredTigerExtensions> configHooks) {
- auto& hooks = getConfigHooks(service);
- invariant(configHooks);
- hooks = std::move(configHooks);
-}
-
WiredTigerExtensions* WiredTigerExtensions::get(ServiceContext* service) {
- return getConfigHooks(service).get();
+ return &getConfigHooks(service);
}
std::string WiredTigerExtensions::getOpenExtensionsConfig() const {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.h b/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.h
index ba73a7ff060..94767a08c9b 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_extensions.h
@@ -39,8 +39,6 @@ class ServiceContext;
class WiredTigerExtensions {
public:
- static void set(ServiceContext* service, std::unique_ptr<WiredTigerExtensions> custHooks);
-
static WiredTigerExtensions* get(ServiceContext* service);
/**
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
index 9408642b210..9290b113405 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
@@ -39,7 +39,6 @@
#include "mongo/db/catalog/collection_options.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
#include "mongo/db/storage/kv/kv_storage_engine.h"
#include "mongo/db/storage/storage_engine_init.h"
#include "mongo/db/storage/storage_engine_lock_file.h"
@@ -179,11 +178,10 @@ public:
return true;
}
};
-} // namespace
-MONGO_INITIALIZER_WITH_PREREQUISITES(WiredTigerEngineInit, ("ServiceContext"))
-(InitializerContext* context) {
- registerStorageEngine(getGlobalServiceContext(), std::make_unique<WiredTigerFactory>());
- return Status::OK();
-}
-}
+ServiceContext::ConstructorActionRegisterer registerWiredTiger(
+ "WiredTigerEngineInit", [](ServiceContext* service) {
+ registerStorageEngine(service, std::make_unique<WiredTigerFactory>());
+ });
+} // namespace
+} // namespace
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.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index e598b0e926a..1fb14fecf3b 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -215,6 +215,7 @@ public:
virtual void run() {
Client::initThread(name().c_str());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
LOG(1) << "starting " << name() << " thread";
@@ -262,6 +263,7 @@ public:
virtual void run() {
Client::initThread(name().c_str());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
LOG(1) << "starting " << name() << " thread";
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 4b1a9c28e15..074fa37ab55 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp
@@ -53,6 +53,8 @@ class WiredTigerKVHarnessHelper : public KVHarnessHelper {
public:
WiredTigerKVHarnessHelper(bool forRepair = false)
: _dbpath("wt-kv-harness"), _forRepair(forRepair) {
+ if (!hasGlobalServiceContext())
+ setGlobalServiceContext(ServiceContext::make());
_engine.reset(makeEngine());
repl::ReplicationCoordinator::set(
getGlobalServiceContext(),
@@ -101,7 +103,7 @@ private:
class WiredTigerKVEngineTest : public unittest::Test {
public:
void setUp() override {
-
+ setGlobalServiceContext(ServiceContext::make());
Client::initThread(getThreadName());
_helper = makeHelper();
@@ -111,6 +113,7 @@ public:
void tearDown() override {
_helper.reset(nullptr);
Client::destroy();
+ setGlobalServiceContext({});
}
std::unique_ptr<OperationContext> makeOperationContext() {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp
index 118471655ad..2eb689e642d 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mock.cpp
@@ -34,8 +34,6 @@
#include "mongo/base/init.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h"
#include <memory>
@@ -52,8 +50,5 @@ MONGO_INITIALIZER(SetInitRsOplogBackgroundThreadCallback)(InitializerContext* co
return Status::OK();
}
-ServiceContextRegistrar serviceContextCreator([]() {
- return std::make_unique<ServiceContextNoop>();
-});
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp
index ac4ecfce606..c73e6d949b3 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_mongod.cpp
@@ -128,6 +128,7 @@ public:
virtual void run() {
Client::initThread(_name.c_str());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
while (!globalInShutdownDeprecated()) {
if (!_deleteExcessDocuments()) {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp
index 5433a581a02..479bd470bf5 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp
@@ -69,14 +69,7 @@ using std::stringstream;
class WiredTigerHarnessHelper final : public RecordStoreHarnessHelper {
public:
- WiredTigerHarnessHelper()
- : _dbpath("wt_test"),
- _engine(kWiredTigerEngineName, _dbpath.path(), &_cs, "", 1, false, false, false, false) {
- repl::ReplicationCoordinator::set(
- getGlobalServiceContext(),
- std::unique_ptr<repl::ReplicationCoordinator>(new repl::ReplicationCoordinatorMock(
- getGlobalServiceContext(), repl::ReplSettings())));
- }
+ WiredTigerHarnessHelper() : WiredTigerHarnessHelper(""_sd) {}
WiredTigerHarnessHelper(StringData extraStrings)
: _dbpath("wt_test"),
@@ -88,8 +81,11 @@ public:
false,
false,
false,
- false) {}
-
+ false) {
+ repl::ReplicationCoordinator::set(serviceContext(),
+ std::make_unique<repl::ReplicationCoordinatorMock>(
+ serviceContext(), repl::ReplSettings()));
+ }
~WiredTigerHarnessHelper() {}
diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp
index ee50be543fd..2c62a927b25 100644
--- a/src/mongo/db/ttl.cpp
+++ b/src/mongo/db/ttl.cpp
@@ -85,6 +85,7 @@ public:
virtual void run() {
Client::initThread(name().c_str());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
AuthorizationSession::get(cc())->grantInternalAuthorization();
while (!globalInShutdownDeprecated()) {
diff --git a/src/mongo/db/update/SConscript b/src/mongo/db/update/SConscript
index 37895498200..ad97577a94a 100644
--- a/src/mongo/db/update/SConscript
+++ b/src/mongo/db/update/SConscript
@@ -117,10 +117,10 @@ 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',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'update',
],
)
diff --git a/src/mongo/db/update/object_replace_node_test.cpp b/src/mongo/db/update/object_replace_node_test.cpp
index 27bb8aea7b3..e3cff950dcd 100644
--- a/src/mongo/db/update/object_replace_node_test.cpp
+++ b/src/mongo/db/update/object_replace_node_test.cpp
@@ -34,7 +34,6 @@
#include "mongo/bson/mutable/mutable_bson_test_utils.h"
#include "mongo/db/json.h"
#include "mongo/db/logical_clock.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/db/update/update_node_test_fixture.h"
#include "mongo/unittest/unittest.h"
diff --git a/src/mongo/db/update/update_node_test_fixture.h b/src/mongo/db/update/update_node_test_fixture.h
index 7a3e47636c1..6da205a2cb8 100644
--- a/src/mongo/db/update/update_node_test_fixture.h
+++ b/src/mongo/db/update/update_node_test_fixture.h
@@ -29,13 +29,14 @@
#pragma once
#include "mongo/db/logical_clock.h"
-#include "mongo/db/service_context_noop.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/db/views/SConscript b/src/mongo/db/views/SConscript
index 3eed93ef638..672323fa39a 100644
--- a/src/mongo/db/views/SConscript
+++ b/src/mongo/db/views/SConscript
@@ -47,7 +47,6 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/query/collation/collator_interface_mock',
'$BUILD_DIR/mongo/db/query/query_test_service_context',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/repl/replmocks',
'$BUILD_DIR/mongo/s/is_mongos',
'$BUILD_DIR/mongo/unittest/unittest',
diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp
index 8e811f3827a..6a65d1a2e2b 100644
--- a/src/mongo/db/views/view_catalog_test.cpp
+++ b/src/mongo/db/views/view_catalog_test.cpp
@@ -44,7 +44,7 @@
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/repl/storage_interface_mock.h"
#include "mongo/db/server_options.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/db/views/durable_view_catalog.h"
#include "mongo/db/views/view.h"
#include "mongo/db/views/view_catalog.h"
diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp
index 91d32f7e032..afea20eb7f5 100644
--- a/src/mongo/dbtests/dbtests.cpp
+++ b/src/mongo/dbtests/dbtests.cpp
@@ -49,8 +49,7 @@
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/repl/storage_interface_mock.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
-#include "mongo/db/service_context_registrar.h"
+#include "mongo/db/service_entry_point_mongod.h"
#include "mongo/db/wire_version.h"
#include "mongo/dbtests/framework.h"
#include "mongo/scripting/engine.h"
@@ -137,7 +136,9 @@ int dbtestsMain(int argc, char** argv, char** envp) {
ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo40);
repl::ReplSettings replSettings;
replSettings.setOplogSizeBytes(10 * 1024 * 1024);
+ setGlobalServiceContext(ServiceContext::make());
ServiceContext* service = getGlobalServiceContext();
+ service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service));
auto logicalClock = stdx::make_unique<LogicalClock>(service);
LogicalClock::set(service, std::move(logicalClock));
diff --git a/src/mongo/dbtests/framework.cpp b/src/mongo/dbtests/framework.cpp
index 0a9d923eb4e..66713babef9 100644
--- a/src/mongo/dbtests/framework.cpp
+++ b/src/mongo/dbtests/framework.cpp
@@ -43,7 +43,6 @@
#include "mongo/db/op_observer_registry.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
#include "mongo/db/storage/storage_engine_init.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/dbtests/framework_options.h"
@@ -90,7 +89,6 @@ int runDbTests(int argc, char** argv) {
srand((unsigned)frameworkGlobalParams.seed);
- createLockFile(globalServiceContext);
initializeStorageEngine(globalServiceContext, StorageEngineInitFlags::kNone);
auto registry = stdx::make_unique<OpObserverRegistry>();
registry->addObserver(stdx::make_unique<UUIDCatalogObserver>());
diff --git a/src/mongo/dbtests/indexupdatetests.cpp b/src/mongo/dbtests/indexupdatetests.cpp
index 650370c7bb1..247f1147bb5 100644
--- a/src/mongo/dbtests/indexupdatetests.cpp
+++ b/src/mongo/dbtests/indexupdatetests.cpp
@@ -40,7 +40,6 @@
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
#include "mongo/db/storage/storage_engine_init.h"
#include "mongo/dbtests/dbtests.h"
diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp
index c581aa74023..2b2be34bf2b 100644
--- a/src/mongo/dbtests/querytests.cpp
+++ b/src/mongo/dbtests/querytests.cpp
@@ -46,7 +46,6 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/query/find.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/util/timer.h"
@@ -702,7 +701,7 @@ public:
// Check number of results and filterSet flag in explain.
// filterSet is not available in oplog replay mode.
BSONObj explainObj = c->next();
- ASSERT(explainObj.hasField("executionStats"));
+ ASSERT(explainObj.hasField("executionStats")) << explainObj;
BSONObj execStats = explainObj["executionStats"].Obj();
ASSERT_EQUALS(1, execStats.getIntField("nReturned"));
diff --git a/src/mongo/dbtests/validate_tests.cpp b/src/mongo/dbtests/validate_tests.cpp
index 818ae60ee0b..28d4f5e8498 100644
--- a/src/mongo/dbtests/validate_tests.cpp
+++ b/src/mongo/dbtests/validate_tests.cpp
@@ -38,7 +38,6 @@
#include "mongo/db/dbdirectclient.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
#include "mongo/dbtests/dbtests.h"
namespace ValidateTests {
diff --git a/src/mongo/embedded/SConscript b/src/mongo/embedded/SConscript
index 172c215cb87..913bc6e0380 100644
--- a/src/mongo/embedded/SConscript
+++ b/src/mongo/embedded/SConscript
@@ -34,7 +34,6 @@ env.Library(
'embedded_options_parser_init.cpp',
'periodic_runner_embedded.cpp',
'replication_coordinator_embedded.cpp',
- 'service_context_embedded.cpp',
'service_entry_point_embedded.cpp',
],
LIBDEPS=[
diff --git a/src/mongo/embedded/embedded.cpp b/src/mongo/embedded/embedded.cpp
index 9849aa0a151..f712e3a749b 100644
--- a/src/mongo/embedded/embedded.cpp
+++ b/src/mongo/embedded/embedded.cpp
@@ -51,7 +51,6 @@
#include "mongo/db/op_observer_registry.h"
#include "mongo/db/repair_database_and_check_version.h"
#include "mongo/db/repl/storage_interface_impl.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/db/session_catalog.h"
#include "mongo/db/session_killer.h"
#include "mongo/db/storage/encryption_hooks.h"
@@ -59,7 +58,6 @@
#include "mongo/db/ttl.h"
#include "mongo/embedded/periodic_runner_embedded.h"
#include "mongo/embedded/replication_coordinator_embedded.h"
-#include "mongo/embedded/service_context_embedded.h"
#include "mongo/embedded/service_entry_point_embedded.h"
#include "mongo/logger/log_component.h"
#include "mongo/scripting/dbdirectclient_factory.h"
@@ -100,11 +98,10 @@ MONGO_INITIALIZER_GENERAL(ForkServer, ("EndStartupOptionHandling"), ("default"))
// Create a minimalistic replication coordinator to provide a limited interface for users. Not
// functional to provide any replication logic.
-GlobalInitializerRegisterer replicationManagerInitializer(
+ServiceContext::ConstructorActionRegisterer replicationManagerInitializer(
"CreateReplicationManager",
- {"SSLManager", "ServiceContext", "default"},
- [](InitializerContext* context) {
- auto serviceContext = getGlobalServiceContext();
+ {"SSLManager", "default"},
+ [](ServiceContext* serviceContext) {
repl::StorageInterface::set(serviceContext, std::make_unique<repl::StorageInterfaceImpl>());
auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext);
@@ -113,16 +110,6 @@ GlobalInitializerRegisterer replicationManagerInitializer(
auto replCoord = std::make_unique<ReplicationCoordinatorEmbedded>(serviceContext);
repl::ReplicationCoordinator::set(serviceContext, std::move(replCoord));
repl::setOplogCollectionName(serviceContext);
- return Status::OK();
- },
- [](DeinitializerContext* context) {
- auto serviceContext = getGlobalServiceContext();
-
- repl::ReplicationCoordinator::set(serviceContext, nullptr);
- LogicalClock::set(serviceContext, nullptr);
- repl::StorageInterface::set(serviceContext, nullptr);
-
- return Status::OK();
});
MONGO_INITIALIZER(fsyncLockedForWriting)(InitializerContext* context) {
@@ -197,12 +184,14 @@ 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");
initWireSpec();
auto serviceContext = getGlobalServiceContext();
+ serviceContext->setServiceEntryPoint(std::make_unique<ServiceEntryPointEmbedded>());
auto opObserverRegistry = std::make_unique<OpObserverRegistry>();
opObserverRegistry->addObserver(std::make_unique<OpObserverImpl>());
diff --git a/src/mongo/embedded/service_context_embedded.cpp b/src/mongo/embedded/service_context_embedded.cpp
deleted file mode 100644
index cc90580fb04..00000000000
--- a/src/mongo/embedded/service_context_embedded.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright (C) 2018 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.
- */
-
-#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/base/init.h"
-#include "mongo/base/initializer.h"
-#include "mongo/db/client.h"
-#include "mongo/db/concurrency/lock_state.h"
-#include "mongo/db/operation_context.h"
-#include "mongo/db/service_context_registrar.h"
-#include "mongo/db/storage/storage_engine.h"
-#include "mongo/db/storage/storage_engine_lock_file.h"
-#include "mongo/db/storage/storage_engine_metadata.h"
-#include "mongo/db/storage/storage_options.h"
-#include "mongo/embedded/service_context_embedded.h"
-#include "mongo/embedded/service_entry_point_embedded.h"
-#include "mongo/stdx/memory.h"
-#include "mongo/util/log.h"
-#include "mongo/util/map_util.h"
-#include "mongo/util/mongoutils/str.h"
-#include "mongo/util/scopeguard.h"
-#include "mongo/util/system_clock_source.h"
-#include "mongo/util/system_tick_source.h"
-
-namespace mongo {
-namespace {
-ServiceContextRegistrar serviceContextCreator([]() {
- auto service = std::make_unique<ServiceContextMongoEmbedded>();
- service->setServiceEntryPoint(std::make_unique<ServiceEntryPointEmbedded>());
- service->setTickSource(std::make_unique<SystemTickSource>());
- service->setFastClockSource(std::make_unique<SystemClockSource>());
- service->setPreciseClockSource(std::make_unique<SystemClockSource>());
- return service;
-});
-} // namespace
-
-extern bool _supportsDocLocking;
-
-ServiceContextMongoEmbedded::ServiceContextMongoEmbedded() = default;
-
-ServiceContextMongoEmbedded::~ServiceContextMongoEmbedded() = default;
-
-std::unique_ptr<OperationContext> ServiceContextMongoEmbedded::_newOpCtx(Client* client,
- unsigned opId) {
- invariant(&cc() == client);
- auto opCtx = stdx::make_unique<OperationContext>(client, opId);
-
- if (isMMAPV1()) {
- opCtx->setLockState(stdx::make_unique<MMAPV1LockerImpl>());
- } else {
- opCtx->setLockState(stdx::make_unique<DefaultLockerImpl>());
- }
-
- opCtx->setRecoveryUnit(getStorageEngine()->newRecoveryUnit(),
- WriteUnitOfWork::RecoveryUnitState::kNotInUnitOfWork);
- return opCtx;
-}
-
-} // namespace mongo
diff --git a/src/mongo/executor/SConscript b/src/mongo/executor/SConscript
index 0222cb4b278..2b3286f9d0d 100644
--- a/src/mongo/executor/SConscript
+++ b/src/mongo/executor/SConscript
@@ -171,6 +171,7 @@ env.CppIntegrationTest(
'network_interface_fixture',
'$BUILD_DIR/mongo/db/commands/test_commands_enabled',
'$BUILD_DIR/mongo/db/wire_version',
+ '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
],
)
@@ -241,7 +242,6 @@ env.CppUnitTest(
'thread_pool_task_executor_test.cpp',
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/unittest/concurrency',
'thread_pool_task_executor_test_fixture',
]
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/rpc/SConscript b/src/mongo/rpc/SConscript
index 4ef1f443cc4..fff0a749384 100644
--- a/src/mongo/rpc/SConscript
+++ b/src/mongo/rpc/SConscript
@@ -271,6 +271,7 @@ env.CppIntegrationTest(
LIBDEPS=[
'protocol',
'$BUILD_DIR/mongo/client/clientdriver_network',
+ '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
'$BUILD_DIR/mongo/util/version_impl',
],
)
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 7f3f2dd2801..eaea9695299 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -178,7 +178,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/db/query/collation/collator_factory_mock',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/executor/task_executor_pool',
'$BUILD_DIR/mongo/s/catalog/dist_lock_manager_mock',
'$BUILD_DIR/mongo/s/catalog/sharding_catalog_client_impl',
@@ -443,9 +443,8 @@ env.CppUnitTest(
'client/shard_connection_test.cpp',
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
'$BUILD_DIR/mongo/dbtests/mocklib',
- '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
'$BUILD_DIR/mongo/util/net/network',
'client/sharding_connection_hook',
'sharding_legacy_api',
diff --git a/src/mongo/s/async_requests_sender.cpp b/src/mongo/s/async_requests_sender.cpp
index 54c92f48290..ea7648cf6f3 100644
--- a/src/mongo/s/async_requests_sender.cpp
+++ b/src/mongo/s/async_requests_sender.cpp
@@ -377,7 +377,7 @@ Status AsyncRequestsSender::RemoteData::resolveShardIdToHostAndPort(
std::shared_ptr<Shard> AsyncRequestsSender::RemoteData::getShard() {
// TODO: Pass down an OperationContext* to use here.
- return grid.shardRegistry()->getShardNoReload(shardId);
+ return Grid::get(getGlobalServiceContext())->shardRegistry()->getShardNoReload(shardId);
}
AsyncRequestsSender::BatonDetacher::BatonDetacher(OperationContext* opCtx)
diff --git a/src/mongo/s/catalog_cache_test_fixture.cpp b/src/mongo/s/catalog_cache_test_fixture.cpp
index af4f0fc4a85..5c1ec551994 100644
--- a/src/mongo/s/catalog_cache_test_fixture.cpp
+++ b/src/mongo/s/catalog_cache_test_fixture.cpp
@@ -56,15 +56,15 @@ void CatalogCacheTestFixture::setUp() {
setRemote(HostAndPort("FakeRemoteClient:34567"));
configTargeter()->setFindHostReturnValue(kConfigHostAndPort);
- CollatorFactoryInterface::set(serviceContext(), stdx::make_unique<CollatorFactoryMock>());
+ CollatorFactoryInterface::set(getServiceContext(), stdx::make_unique<CollatorFactoryMock>());
}
executor::NetworkTestEnv::FutureHandle<boost::optional<CachedCollectionRoutingInfo>>
CatalogCacheTestFixture::scheduleRoutingInfoRefresh(const NamespaceString& nss) {
return launchAsync([this, nss] {
- auto client = serviceContext()->makeClient("Test");
+ auto client = getServiceContext()->makeClient("Test");
auto opCtx = client->makeOperationContext();
- auto const catalogCache = Grid::get(serviceContext())->catalogCache();
+ auto const catalogCache = Grid::get(getServiceContext())->catalogCache();
catalogCache->invalidateShardedCollection(nss);
return boost::make_optional(
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/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp
index ddc749edcd9..e450fa9e54e 100644
--- a/src/mongo/s/client/shard_registry.cpp
+++ b/src/mongo/s/client/shard_registry.cpp
@@ -345,7 +345,7 @@ void ShardRegistry::replicaSetChangeShardRegistryUpdateHook(
// Inform the ShardRegsitry of the new connection string for the shard.
auto connString = fassert(28805, ConnectionString::parse(newConnectionString));
invariant(setName == connString.getSetName());
- grid.shardRegistry()->updateReplSetHosts(connString);
+ Grid::get(getGlobalServiceContext())->shardRegistry()->updateReplSetHosts(connString);
}
void ShardRegistry::replicaSetChangeConfigServerUpdateHook(const std::string& setName,
diff --git a/src/mongo/s/client/sharding_network_connection_hook.cpp b/src/mongo/s/client/sharding_network_connection_hook.cpp
index 88ed8882b60..7bc307e4ab7 100644
--- a/src/mongo/s/client/sharding_network_connection_hook.cpp
+++ b/src/mongo/s/client/sharding_network_connection_hook.cpp
@@ -53,7 +53,8 @@ Status ShardingNetworkConnectionHook::validateHost(
Status ShardingNetworkConnectionHook::validateHostImpl(
const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) {
- auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost);
+ auto shard =
+ Grid::get(getGlobalServiceContext())->shardRegistry()->getShardForHostNoReload(remoteHost);
if (!shard) {
return {ErrorCodes::ShardNotFound,
str::stream() << "No shard found for host: " << remoteHost.toString()};
diff --git a/src/mongo/s/cluster_cursor_stats.cpp b/src/mongo/s/cluster_cursor_stats.cpp
index 4aa5ca97891..2906fbfc8df 100644
--- a/src/mongo/s/cluster_cursor_stats.cpp
+++ b/src/mongo/s/cluster_cursor_stats.cpp
@@ -44,12 +44,13 @@ public:
ClusterCursorStats() : ServerStatusMetric("cursor") {}
void appendAtLeaf(BSONObjBuilder& b) const final {
+ auto grid = Grid::get(getGlobalServiceContext());
BSONObjBuilder cursorBob(b.subobjStart(_leafName));
cursorBob.append("timedOut",
- static_cast<long long>(grid.getCursorManager()->cursorsTimedOut()));
+ static_cast<long long>(grid->getCursorManager()->cursorsTimedOut()));
{
BSONObjBuilder openBob(cursorBob.subobjStart("open"));
- auto stats = grid.getCursorManager()->stats();
+ auto stats = grid->getCursorManager()->stats();
openBob.append("multiTarget", static_cast<long long>(stats.cursorsMultiTarget));
openBob.append("singleTarget", static_cast<long long>(stats.cursorsSingleTarget));
openBob.append("pinned", static_cast<long long>(stats.cursorsPinned));
diff --git a/src/mongo/s/cluster_identity_loader_test.cpp b/src/mongo/s/cluster_identity_loader_test.cpp
index 98817150d6b..18685da1086 100644
--- a/src/mongo/s/cluster_identity_loader_test.cpp
+++ b/src/mongo/s/cluster_identity_loader_test.cpp
@@ -35,7 +35,7 @@
#include "mongo/client/remote_command_targeter_mock.h"
#include "mongo/db/commands.h"
#include "mongo/db/query/query_request.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/task_executor.h"
#include "mongo/rpc/metadata/repl_set_metadata.h"
@@ -67,19 +67,10 @@ BSONObj getReplSecondaryOkMetadata() {
class ClusterIdentityTest : public ShardingTestFixture {
public:
- void setUp() override {
- ShardingTestFixture::setUp();
-
+ ClusterIdentityTest() {
configTargeter()->setFindHostReturnValue(configHost);
}
- void tearDown() override {
- ShardingTestFixture::tearDown();
-
- // Reset the global service context so that the cluster identity gets cleared
- setGlobalServiceContext(std::make_unique<ServiceContextNoop>());
- }
-
void expectConfigVersionLoad(StatusWith<OID> result) {
onFindCommand([&](const RemoteCommandRequest& request) {
ASSERT_EQUALS(configHost, request.target);
diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript
index 6369009c1e3..d6e8c18e9a5 100644
--- a/src/mongo/s/commands/SConscript
+++ b/src/mongo/s/commands/SConscript
@@ -140,7 +140,6 @@ env.CppUnitTest(
LIBDEPS=[
'cluster_commands_helpers',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/logical_time',
'$BUILD_DIR/mongo/unittest/unittest',
]
@@ -155,7 +154,6 @@ env.CppUnitTest(
'cluster_commands_helpers',
'$BUILD_DIR/mongo/s/catalog_cache_test_fixture',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/db/logical_clock',
'$BUILD_DIR/mongo/unittest/unittest',
]
@@ -170,7 +168,6 @@ env.CppUnitTest(
'cluster_commands',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/auth/saslauth',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/s/catalog_cache_test_fixture',
],
)
diff --git a/src/mongo/s/commands/cluster_aggregate_test.cpp b/src/mongo/s/commands/cluster_aggregate_test.cpp
index 37a94a57c5a..4f11447faac 100644
--- a/src/mongo/s/commands/cluster_aggregate_test.cpp
+++ b/src/mongo/s/commands/cluster_aggregate_test.cpp
@@ -69,10 +69,10 @@ protected:
CatalogCacheTestFixture::setupNShards(numShards);
// Set up a logical clock with an initial time.
- auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext());
+ auto logicalClock = stdx::make_unique<LogicalClock>(getServiceContext());
LogicalTime initialTime(Timestamp(10, 1));
logicalClock->setClusterTimeFromTrustedSource(initialTime);
- LogicalClock::set(serviceContext(), std::move(logicalClock));
+ LogicalClock::set(getServiceContext(), std::move(logicalClock));
auto keysCollectionClient = stdx::make_unique<KeysCollectionClientSharded>(
Grid::get(operationContext())->catalogClient());
@@ -81,7 +81,7 @@ protected:
"dummy", std::move(keysCollectionClient), Seconds(KeysRotationIntervalSec));
auto validator = stdx::make_unique<LogicalTimeValidator>(keyManager);
- LogicalTimeValidator::set(serviceContext(), std::move(validator));
+ LogicalTimeValidator::set(getServiceContext(), std::move(validator));
// ReadConcern 'snapshot' is only supported with test commands enabled.
setTestCommandsEnabled(true);
@@ -123,7 +123,7 @@ protected:
DbResponse runAggregateCommand(BSONObj aggCmd) {
// Create a new client/operation context per command, and setup a test session ID and
// transaction number.
- auto client = serviceContext()->makeClient("ClusterAggClient");
+ auto client = getServiceContext()->makeClient("ClusterAggClient");
auto opCtx = client->makeOperationContext();
opCtx->setLogicalSessionId(makeLogicalSessionIdForTest());
opCtx->setTxnNumber(1);
diff --git a/src/mongo/s/commands/compute_at_cluster_time_test.cpp b/src/mongo/s/commands/compute_at_cluster_time_test.cpp
index a4701547bbb..4d34d390326 100644
--- a/src/mongo/s/commands/compute_at_cluster_time_test.cpp
+++ b/src/mongo/s/commands/compute_at_cluster_time_test.cpp
@@ -71,9 +71,9 @@ protected:
repl::ReadConcernArgs(repl::ReadConcernLevel::kSnapshotReadConcern);
// Set up a logical clock with an initial time.
- auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext());
+ auto logicalClock = stdx::make_unique<LogicalClock>(getServiceContext());
logicalClock->setClusterTimeFromTrustedSource(kInMemoryLogicalTime);
- LogicalClock::set(serviceContext(), std::move(logicalClock));
+ LogicalClock::set(getServiceContext(), std::move(logicalClock));
}
};
@@ -131,9 +131,9 @@ protected:
CatalogCacheTestFixture::setupNShards(2);
// Set up a logical clock with an initial time.
- auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext());
+ auto logicalClock = stdx::make_unique<LogicalClock>(getServiceContext());
logicalClock->setClusterTimeFromTrustedSource(kInMemoryLogicalTime);
- LogicalClock::set(serviceContext(), std::move(logicalClock));
+ LogicalClock::set(getServiceContext(), std::move(logicalClock));
}
};
diff --git a/src/mongo/s/grid.cpp b/src/mongo/s/grid.cpp
index 6570ca0c751..65d8b1c1f8c 100644
--- a/src/mongo/s/grid.cpp
+++ b/src/mongo/s/grid.cpp
@@ -44,15 +44,17 @@
namespace mongo {
+namespace {
// Global grid instance
-Grid grid;
+const auto grid = ServiceContext::declareDecoration<Grid>();
+}
Grid::Grid() = default;
Grid::~Grid() = default;
Grid* Grid::get(ServiceContext* serviceContext) {
- return &grid;
+ return &grid(serviceContext);
}
Grid* Grid::get(OperationContext* operationContext) {
diff --git a/src/mongo/s/grid.h b/src/mongo/s/grid.h
index 443c9b81304..02da388532b 100644
--- a/src/mongo/s/grid.h
+++ b/src/mongo/s/grid.h
@@ -200,8 +200,4 @@ private:
bool _allowLocalShard{true};
};
-// Reference to the global Grid instance. Do not use in new code. Use one of the Grid::get methods
-// instead.
-extern Grid grid;
-
} // namespace mongo
diff --git a/src/mongo/s/metadata_filtering_test.cpp b/src/mongo/s/metadata_filtering_test.cpp
index c00e165f0c0..f37cb265f7e 100644
--- a/src/mongo/s/metadata_filtering_test.cpp
+++ b/src/mongo/s/metadata_filtering_test.cpp
@@ -52,7 +52,7 @@ protected:
setupNShards(2);
- _manager = std::make_shared<MetadataManager>(serviceContext(), kNss, executor());
+ _manager = std::make_shared<MetadataManager>(getServiceContext(), kNss, executor());
}
void expectGetDatabase() {
diff --git a/src/mongo/s/query/SConscript b/src/mongo/s/query/SConscript
index 023a966bcab..f153381d12c 100644
--- a/src/mongo/s/query/SConscript
+++ b/src/mongo/s/query/SConscript
@@ -30,7 +30,6 @@ env.CppUnitTest(
LIBDEPS=[
'cluster_query',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/s/catalog_cache_test_fixture',
],
)
@@ -77,7 +76,6 @@ env.CppUnitTest(
LIBDEPS=[
'router_exec_stage',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
],
)
@@ -117,7 +115,6 @@ env.CppUnitTest(
'cluster_client_cursor',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/query/query_request',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
'$BUILD_DIR/mongo/s/sharding_router_test_fixture',
],
@@ -132,7 +129,6 @@ env.CppUnitTest(
'async_results_merger',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/query/query_request',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/s/sharding_router_test_fixture',
],
)
@@ -159,7 +155,6 @@ env.CppUnitTest(
'store_possible_cursor',
'$BUILD_DIR/mongo/db/auth/authmocks',
'$BUILD_DIR/mongo/db/query/query_test_service_context',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/util/clock_source_mock',
],
)
@@ -187,6 +182,7 @@ env.CppUnitTest(
],
LIBDEPS=[
"$BUILD_DIR/mongo/db/logical_session_id",
+ "$BUILD_DIR/mongo/db/service_context_test_fixture",
"$BUILD_DIR/mongo/util/clock_source_mock",
"cluster_client_cursor_mock",
"cluster_cursor_manager",
@@ -213,6 +209,6 @@ env.CppUnitTest(
LIBDEPS=[
'cluster_client_cursor',
'$BUILD_DIR/mongo/db/auth/authmocks',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ '$BUILD_DIR/mongo/db/service_context_test_fixture',
],
)
diff --git a/src/mongo/s/query/async_results_merger_test.cpp b/src/mongo/s/query/async_results_merger_test.cpp
index 662d78e6dd0..64428771bb0 100644
--- a/src/mongo/s/query/async_results_merger_test.cpp
+++ b/src/mongo/s/query/async_results_merger_test.cpp
@@ -74,7 +74,6 @@ public:
AsyncResultsMergerTest() {}
void setUp() override {
- ShardingTestFixture::setUp();
setRemote(HostAndPort("ClientHost", 12345));
configTargeter()->setFindHostReturnValue(kTestConfigShardHost);
@@ -100,10 +99,6 @@ public:
setupShards(shards);
}
- void tearDown() override {
- ShardingTestFixture::tearDown();
- }
-
protected:
/**
* Constructs an ARM with the given vector of existing cursors.
@@ -2072,7 +2067,8 @@ DEATH_TEST_F(AsyncResultsMergerTest,
params.setOperationSessionInfo(sessionInfo);
// This should trigger an invariant.
- stdx::make_unique<AsyncResultsMerger>(operationContext(), executor(), std::move(params));
+ ASSERT_FALSE(
+ stdx::make_unique<AsyncResultsMerger>(operationContext(), executor(), std::move(params)));
}
DEATH_TEST_F(AsyncResultsMergerTest,
diff --git a/src/mongo/s/query/cluster_client_cursor_impl_test.cpp b/src/mongo/s/query/cluster_client_cursor_impl_test.cpp
index c73b33a68e4..faf4d29dda1 100644
--- a/src/mongo/s/query/cluster_client_cursor_impl_test.cpp
+++ b/src/mongo/s/query/cluster_client_cursor_impl_test.cpp
@@ -32,7 +32,7 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonobjbuilder.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/s/query/router_stage_mock.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
@@ -41,27 +41,11 @@ namespace mongo {
namespace {
-class ClusterClientCursorImplTest : public unittest::Test {
+class ClusterClientCursorImplTest : public ServiceContextTest {
protected:
- ServiceContextNoop _serviceContext;
- ServiceContext::UniqueOperationContext _opCtx;
- Client* _client;
-
-private:
- void setUp() final {
- auto client = _serviceContext.makeClient("testClient");
- _opCtx = client->makeOperationContext();
- _client = client.get();
- Client::setCurrent(std::move(client));
- }
-
- void tearDown() final {
- if (_opCtx) {
- _opCtx.reset();
- }
+ ClusterClientCursorImplTest() : _opCtx(makeOperationContext()) {}
- Client::releaseCurrent();
- }
+ ServiceContext::UniqueOperationContext _opCtx;
};
TEST_F(ClusterClientCursorImplTest, NumReturnedSoFar) {
@@ -196,7 +180,7 @@ TEST_F(ClusterClientCursorImplTest, ChecksForInterrupt) {
// Now interrupt the opCtx which the cursor is running under.
{
- stdx::lock_guard<Client> lk(*_client);
+ stdx::lock_guard<Client> lk(*_opCtx->getClient());
_opCtx->markKilled(ErrorCodes::CursorKilled);
}
diff --git a/src/mongo/s/query/cluster_cursor_cleanup_job.cpp b/src/mongo/s/query/cluster_cursor_cleanup_job.cpp
index d1f0438e655..2fcaf6b398e 100644
--- a/src/mongo/s/query/cluster_cursor_cleanup_job.cpp
+++ b/src/mongo/s/query/cluster_cursor_cleanup_job.cpp
@@ -49,6 +49,7 @@ std::string ClusterCursorCleanupJob::name() const {
void ClusterCursorCleanupJob::run() {
Client::initThread(name().c_str());
+ ON_BLOCK_EXIT([] { Client::destroy(); });
auto* const client = Client::getCurrent();
auto* const manager = Grid::get(client->getServiceContext())->getCursorManager();
diff --git a/src/mongo/s/query/cluster_cursor_manager_test.cpp b/src/mongo/s/query/cluster_cursor_manager_test.cpp
index b5a2832cb1e..04a9d074ad7 100644
--- a/src/mongo/s/query/cluster_cursor_manager_test.cpp
+++ b/src/mongo/s/query/cluster_cursor_manager_test.cpp
@@ -34,8 +34,8 @@
#include "mongo/db/logical_session_cache.h"
#include "mongo/db/logical_session_cache_noop.h"
-#include "mongo/db/operation_context_noop.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/s/query/cluster_client_cursor_mock.h"
#include "mongo/stdx/memory.h"
#include "mongo/unittest/unittest.h"
@@ -48,13 +48,17 @@ namespace {
using unittest::assertGet;
const NamespaceString nss("test.collection");
-class ClusterCursorManagerTest : public unittest::Test {
+class ClusterCursorManagerTest : public ServiceContextTest {
protected:
- ClusterCursorManagerTest() : _manager(&_clockSourceMock) {}
+ ClusterCursorManagerTest() : _opCtx(makeOperationContext()), _manager(&_clockSourceMock) {
+ LogicalSessionCache::set(getServiceContext(), stdx::make_unique<LogicalSessionCacheNoop>());
+ }
+
+ ~ClusterCursorManagerTest() {
+ _manager.shutdown(_opCtx.get());
+ }
- ServiceContextNoop serviceContext;
ServiceContext::UniqueOperationContext _opCtx;
- Client* _client;
static Status successAuthChecker(UserNameIterator userNames) {
return Status::OK();
@@ -106,49 +110,16 @@ protected:
}
void killCursorFromDifferentOpCtx(const NamespaceString& nss, CursorId cursorId) {
- // Set up another client to kill the cursor.
- auto killCursorClientOwned = serviceContext.makeClient("killCursorClient");
- // Keep around a raw pointer for when we transfer ownership of killingClientOwned to the
- // global current client.
- Client* killCursorClient = killCursorClientOwned.get();
-
- // Need to swap the current client in order to make an operation context.
- auto pinningClient = Client::releaseCurrent();
- Client::setCurrent(std::move(killCursorClientOwned));
+ // Set up another client to kill the cursor.
+ auto killCursorClient = getServiceContext()->makeClient("killCursorClient");
auto killCursorOpCtx = killCursorClient->makeOperationContext();
- invariant(killCursorOpCtx);
+ AlternativeClientRegion acr(killCursorClient);
ASSERT_OK(getManager()->killCursor(killCursorOpCtx.get(), nss, cursorId));
-
- // Restore the old client. We don't need 'killCursorClient' anymore.
- killCursorOpCtx.reset();
- Client::releaseCurrent();
-
- Client::setCurrent(std::move(pinningClient));
}
private:
- void setUp() final {
- auto client = serviceContext.makeClient("testClient");
- _opCtx = client->makeOperationContext();
- _client = client.get();
- Client::setCurrent(std::move(client));
-
- LogicalSessionCache::set(&serviceContext, stdx::make_unique<LogicalSessionCacheNoop>());
- }
-
- void tearDown() final {
- _manager.shutdown(_opCtx.get());
-
- if (_opCtx) {
- _opCtx.reset();
- }
-
- Client::releaseCurrent();
- LogicalSessionCache::set(&serviceContext, nullptr);
- }
-
// List of flags representing whether our allocated cursors have been killed yet. The value of
// the flag is true iff the cursor has been killed.
//
diff --git a/src/mongo/s/query/cluster_find_test.cpp b/src/mongo/s/query/cluster_find_test.cpp
index e588521c80b..ccba55977a6 100644
--- a/src/mongo/s/query/cluster_find_test.cpp
+++ b/src/mongo/s/query/cluster_find_test.cpp
@@ -65,9 +65,9 @@ protected:
CatalogCacheTestFixture::setupNShards(numShards);
// Set up a logical clock with an initial time.
- auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext());
+ auto logicalClock = stdx::make_unique<LogicalClock>(getServiceContext());
logicalClock->setClusterTimeFromTrustedSource(kInMemoryLogicalTime);
- LogicalClock::set(serviceContext(), std::move(logicalClock));
+ LogicalClock::set(getServiceContext(), std::move(logicalClock));
}
// The index of the shard expected to receive the response is used to prevent different shards
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index 7d8f848921b..cfa63a8c7ad 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -60,8 +60,6 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/db/session_killer.h"
#include "mongo/db/startup_warnings_common.h"
#include "mongo/db/wire_version.h"
@@ -112,8 +110,6 @@
#include "mongo/util/signal_handlers.h"
#include "mongo/util/stacktrace.h"
#include "mongo/util/stringutils.h"
-#include "mongo/util/system_clock_source.h"
-#include "mongo/util/system_tick_source.h"
#include "mongo/util/text.h"
#include "mongo/util/version.h"
@@ -547,14 +543,6 @@ MONGO_INITIALIZER_WITH_PREREQUISITES(SetFeatureCompatibilityVersion40, ("EndStar
return Status::OK();
}
-ServiceContextRegistrar serviceContextCreator([]() {
- auto service = std::make_unique<ServiceContextNoop>();
- service->setTickSource(std::make_unique<SystemTickSource>());
- service->setFastClockSource(std::make_unique<SystemClockSource>());
- service->setPreciseClockSource(std::make_unique<SystemClockSource>());
- return service;
-});
-
#ifdef MONGO_CONFIG_SSL
MONGO_INITIALIZER_GENERAL(setSSLManagerType, MONGO_NO_PREREQUISITES, ("SSLManager"))
(InitializerContext* context) {
@@ -571,7 +559,6 @@ ExitCode mongoSMain(int argc, char* argv[], char** envp) {
if (argc < 1)
return EXIT_BADOPTIONS;
- registerShutdownTask([&]() { cleanupTask(getGlobalServiceContext()); });
setupSignalHandlers();
@@ -581,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/s/sharding_mongod_test_fixture.cpp b/src/mongo/s/sharding_mongod_test_fixture.cpp
index f9a54847fd2..6fa3565cab9 100644
--- a/src/mongo/s/sharding_mongod_test_fixture.cpp
+++ b/src/mongo/s/sharding_mongod_test_fixture.cpp
@@ -33,6 +33,7 @@
#include <algorithm>
#include <vector>
+#include "mongo/base/checked_cast.h"
#include "mongo/base/status_with.h"
#include "mongo/client/remote_command_targeter_factory_mock.h"
#include "mongo/client/remote_command_targeter_mock.h"
@@ -55,7 +56,6 @@
#include "mongo/db/repl/storage_interface_mock.h"
#include "mongo/db/s/config_server_op_observer.h"
#include "mongo/db/s/shard_server_op_observer.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/task_executor_pool.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
@@ -135,14 +135,10 @@ void ShardingMongodTestFixture::setUp() {
repl::StorageInterface::set(service, std::move(storagePtr));
- auto makeOpObserver = [&] {
- auto opObserver = stdx::make_unique<OpObserverRegistry>();
- opObserver->addObserver(stdx::make_unique<OpObserverImpl>());
- opObserver->addObserver(stdx::make_unique<ConfigServerOpObserver>());
- opObserver->addObserver(stdx::make_unique<ShardServerOpObserver>());
- return opObserver;
- };
- service->setOpObserver(makeOpObserver());
+ auto opObserver = checked_cast<OpObserverRegistry*>(service->getOpObserver());
+ opObserver->addObserver(stdx::make_unique<OpObserverImpl>());
+ opObserver->addObserver(stdx::make_unique<ConfigServerOpObserver>());
+ opObserver->addObserver(stdx::make_unique<ShardServerOpObserver>());
repl::setOplogCollectionName(service);
repl::createOplog(_opCtx.get());
@@ -308,8 +304,6 @@ void ShardingMongodTestFixture::tearDown() {
Grid::get(operationContext())->clearForUnitTests();
_opCtx.reset();
- _client.reset();
-
ServiceContextMongoDTest::tearDown();
}
diff --git a/src/mongo/s/sharding_mongod_test_fixture.h b/src/mongo/s/sharding_mongod_test_fixture.h
index 222fbfd5184..02b41cfab5e 100644
--- a/src/mongo/s/sharding_mongod_test_fixture.h
+++ b/src/mongo/s/sharding_mongod_test_fixture.h
@@ -189,7 +189,6 @@ private:
const std::vector<HostAndPort> _servers{
_host, HostAndPort("node2:12345"), HostAndPort("node3:12345")};
- ServiceContext::UniqueClient _client;
ServiceContext::UniqueOperationContext _opCtx;
// Since the RemoteCommandTargeterFactory is currently a private member of ShardFactory, we
diff --git a/src/mongo/s/sharding_router_test_fixture.cpp b/src/mongo/s/sharding_router_test_fixture.cpp
index 78cda1a545a..d6b94f4c6df 100644
--- a/src/mongo/s/sharding_router_test_fixture.cpp
+++ b/src/mongo/s/sharding_router_test_fixture.cpp
@@ -44,7 +44,6 @@
#include "mongo/db/query/collation/collator_factory_mock.h"
#include "mongo/db/query/query_request.h"
#include "mongo/db/repl/read_concern_args.h"
-#include "mongo/db/service_context_noop.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/task_executor_pool.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
@@ -94,12 +93,8 @@ std::unique_ptr<ShardingTaskExecutor> makeShardingTestExecutor(
} // namespace
-ShardingTestFixture::ShardingTestFixture() = default;
-
-ShardingTestFixture::~ShardingTestFixture() = default;
-
-void ShardingTestFixture::setUp() {
- auto const service = serviceContext();
+ShardingTestFixture::ShardingTestFixture() {
+ auto const service = getServiceContext();
// Configure the service context
service->setFastClockSource(stdx::make_unique<ClockSourceMock>());
@@ -108,8 +103,7 @@ void ShardingTestFixture::setUp() {
CollatorFactoryInterface::set(service, stdx::make_unique<CollatorFactoryMock>());
_transportSession = transport::MockSession::create(nullptr);
- _client = service->makeClient("ShardingTestFixture", _transportSession);
- _opCtx = _client->makeOperationContext();
+ _opCtx = makeOperationContext();
// Set up executor pool used for most operations.
auto makeMetadataHookList = [&] {
@@ -194,16 +188,9 @@ void ShardingTestFixture::setUp() {
_mockNetwork);
}
-void ShardingTestFixture::tearDown() {
- CatalogCacheLoader::clearForTests(serviceContext());
-
- Grid::get(operationContext())->getExecutorPool()->shutdownAndJoin();
- Grid::get(operationContext())->catalogClient()->shutDown(_opCtx.get());
- Grid::get(operationContext())->clearForUnitTests();
- _transportSession.reset();
- _opCtx.reset();
- _client.reset();
+ShardingTestFixture::~ShardingTestFixture() {
+ CatalogCacheLoader::clearForTests(getServiceContext());
}
void ShardingTestFixture::shutdownExecutor() {
@@ -243,10 +230,6 @@ DistLockManagerMock* ShardingTestFixture::distLock() const {
return _distLockManager;
}
-ServiceContext* ShardingTestFixture::serviceContext() const {
- return getGlobalServiceContext();
-}
-
OperationContext* ShardingTestFixture::operationContext() const {
invariant(_opCtx);
diff --git a/src/mongo/s/sharding_router_test_fixture.h b/src/mongo/s/sharding_router_test_fixture.h
index 05c1fa37a88..3eadf92a225 100644
--- a/src/mongo/s/sharding_router_test_fixture.h
+++ b/src/mongo/s/sharding_router_test_fixture.h
@@ -28,6 +28,7 @@
#pragma once
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/s/sharding_test_fixture_common.h"
namespace mongo {
@@ -50,7 +51,7 @@ class TransportLayerMock;
* Sets up the mocked out objects for testing the replica-set backed catalog manager and catalog
* client.
*/
-class ShardingTestFixture : public unittest::Test, public ShardingTestFixtureCommon {
+class ShardingTestFixture : public ServiceContextTest, public ShardingTestFixtureCommon {
public:
ShardingTestFixture();
~ShardingTestFixture();
@@ -64,7 +65,6 @@ public:
DistLockManagerMock* distLock() const;
RemoteCommandTargeterMock* configTargeter() const;
- ServiceContext* serviceContext() const;
OperationContext* operationContext() const;
/**
@@ -170,10 +170,6 @@ public:
const NamespaceString& expectedNs,
const ChunkVersion& expectedChunkVersion);
- void setUp() override;
-
- void tearDown() override;
-
void shutdownExecutor();
void setRemote(const HostAndPort& remote);
diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp
index c2f2e3013f3..bf24f2897e8 100644
--- a/src/mongo/shell/dbshell.cpp
+++ b/src/mongo/shell/dbshell.cpp
@@ -47,7 +47,6 @@
#include "mongo/db/client.h"
#include "mongo/db/log_process_details.h"
#include "mongo/db/server_options.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/logger/console_appender.h"
#include "mongo/logger/logger.h"
#include "mongo/logger/message_event_utf8_encoder.h"
@@ -745,7 +744,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 6332f1cc5fe..01093145986 100644
--- a/src/mongo/tools/bridge.cpp
+++ b/src/mongo/tools/bridge.cpp
@@ -38,8 +38,6 @@
#include "mongo/db/dbmessage.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_noop.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/platform/random.h"
#include "mongo/rpc/command_request.h"
@@ -85,10 +83,6 @@ boost::optional<HostAndPort> extractHostInfo(const OpMsgRequest& request) {
return boost::none;
}
-ServiceContextRegistrar serviceContextCreator([]() {
- return std::make_unique<ServiceContextNoop>();
-});
-
} // namespace
class BridgeContext {
@@ -142,7 +136,7 @@ private:
HostSettingsMap _settings;
};
-const ServiceContextNoop::Decoration<BridgeContext> BridgeContext::_get =
+const ServiceContext::Decoration<BridgeContext> BridgeContext::_get =
ServiceContext::declareDecoration<BridgeContext>();
BridgeContext* BridgeContext::get() {
@@ -419,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/transport/SConscript b/src/mongo/transport/SConscript
index d12800b3273..0f61fbcf12c 100644
--- a/src/mongo/transport/SConscript
+++ b/src/mongo/transport/SConscript
@@ -74,7 +74,6 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'transport_layer',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
]
)
@@ -86,7 +85,6 @@ tlEnv.CppUnitTest(
LIBDEPS=[
'transport_layer',
'$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/db/service_context_noop_init',
'$BUILD_DIR/mongo/rpc/protocol',
'$BUILD_DIR/mongo/util/net/socket',
],
diff --git a/src/mongo/transport/service_executor_adaptive_test.cpp b/src/mongo/transport/service_executor_adaptive_test.cpp
index c851c738ac2..30227edf3b9 100644
--- a/src/mongo/transport/service_executor_adaptive_test.cpp
+++ b/src/mongo/transport/service_executor_adaptive_test.cpp
@@ -32,7 +32,7 @@
#include "boost/optional.hpp"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/transport/service_executor_adaptive.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/log.h"
@@ -107,8 +107,7 @@ struct RecursionOptions : public ServiceExecutorAdaptive::Options {
class ServiceExecutorAdaptiveFixture : public unittest::Test {
protected:
void setUp() override {
- auto scOwned = stdx::make_unique<ServiceContextNoop>();
- setGlobalServiceContext(std::move(scOwned));
+ setGlobalServiceContext(ServiceContext::make());
asioIoCtx = std::make_shared<asio::io_context>();
}
diff --git a/src/mongo/transport/service_executor_test.cpp b/src/mongo/transport/service_executor_test.cpp
index fbf374934ad..da2f6a867df 100644
--- a/src/mongo/transport/service_executor_test.cpp
+++ b/src/mongo/transport/service_executor_test.cpp
@@ -32,7 +32,7 @@
#include "boost/optional.hpp"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/transport/service_executor_adaptive.h"
#include "mongo/transport/service_executor_synchronous.h"
#include "mongo/transport/service_executor_task_names.h"
@@ -149,7 +149,7 @@ private:
class ServiceExecutorAdaptiveFixture : public unittest::Test {
protected:
void setUp() override {
- auto scOwned = stdx::make_unique<ServiceContextNoop>();
+ auto scOwned = ServiceContext::make();
setGlobalServiceContext(std::move(scOwned));
auto configOwned = stdx::make_unique<TestOptions>();
@@ -166,7 +166,7 @@ protected:
class ServiceExecutorSynchronousFixture : public unittest::Test {
protected:
void setUp() override {
- auto scOwned = stdx::make_unique<ServiceContextNoop>();
+ auto scOwned = ServiceContext::make();
setGlobalServiceContext(std::move(scOwned));
executor = stdx::make_unique<ServiceExecutorSynchronous>(getGlobalServiceContext());
diff --git a/src/mongo/transport/service_state_machine_test.cpp b/src/mongo/transport/service_state_machine_test.cpp
index 7ea13eaf12f..e29c33627a6 100644
--- a/src/mongo/transport/service_state_machine_test.cpp
+++ b/src/mongo/transport/service_state_machine_test.cpp
@@ -35,7 +35,7 @@
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/client.h"
#include "mongo/db/dbmessage.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/rpc/op_msg.h"
#include "mongo/stdx/memory.h"
#include "mongo/transport/mock_session.h"
@@ -272,7 +272,7 @@ class ServiceStateMachineFixture : public unittest::Test {
protected:
void setUp() override {
- auto scOwned = stdx::make_unique<ServiceContextNoop>();
+ auto scOwned = ServiceContext::make();
auto sc = scOwned.get();
setGlobalServiceContext(std::move(scOwned));
diff --git a/src/mongo/transport/transport_layer_egress_init.cpp b/src/mongo/transport/transport_layer_egress_init.cpp
index 628cf6c2dfc..ec8dd262515 100644
--- a/src/mongo/transport/transport_layer_egress_init.cpp
+++ b/src/mongo/transport/transport_layer_egress_init.cpp
@@ -34,25 +34,23 @@
#include "mongo/db/service_context.h"
#include "mongo/transport/transport_layer_asio.h"
+#include <iostream>
+
namespace mongo {
namespace {
-// Linking with this file will configure an egress-only TransportLayer on a ServiceContextNoop.
+// Linking with this file will configure an egress-only TransportLayer on all new ServiceContexts.
// Use this for unit/integration tests that require only egress networking.
-MONGO_INITIALIZER_WITH_PREREQUISITES(ConfigureEgressTransportLayer, ("ServiceContext"))
-(InitializerContext* context) {
- auto sc = getGlobalServiceContext();
- invariant(!sc->getTransportLayer());
-
- transport::TransportLayerASIO::Options opts;
- opts.mode = transport::TransportLayerASIO::Options::kEgress;
- sc->setTransportLayer(std::make_unique<transport::TransportLayerASIO>(opts, nullptr));
- auto status = sc->getTransportLayer()->setup();
- if (!status.isOK()) {
- return status;
- }
-
- return sc->getTransportLayer()->start();
-}
+
+ServiceContext::ConstructorActionRegisterer registerEgressTransportLayer{
+ "ConfigureEgressTransportLayer", [](ServiceContext* sc) {
+
+ invariant(!sc->getTransportLayer());
+ transport::TransportLayerASIO::Options opts;
+ opts.mode = transport::TransportLayerASIO::Options::kEgress;
+ sc->setTransportLayer(std::make_unique<transport::TransportLayerASIO>(opts, nullptr));
+ uassertStatusOK(sc->getTransportLayer()->setup());
+ uassertStatusOK(sc->getTransportLayer()->start());
+ }};
} // namespace
-} // namespace
+} // namespace mongo
diff --git a/src/mongo/unittest/SConscript b/src/mongo/unittest/SConscript
index 4645c23c19a..1193b6d2b07 100644
--- a/src/mongo/unittest/SConscript
+++ b/src/mongo/unittest/SConscript
@@ -47,7 +47,6 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/client/connection_string',
'$BUILD_DIR/mongo/db/service_context',
- '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
'$BUILD_DIR/mongo/util/options_parser/options_parser_init',
],
)
@@ -61,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 b4087176542..20d2d8e0546 100644
--- a/src/mongo/unittest/integration_test_main.cpp
+++ b/src/mongo/unittest/integration_test_main.cpp
@@ -37,7 +37,6 @@
#include "mongo/base/initializer.h"
#include "mongo/client/connection_string.h"
#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_registrar.h"
#include "mongo/transport/transport_layer_asio.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/log.h"
@@ -72,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));
}
diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript
index a71f295ba35..c9414e0c281 100644
--- a/src/mongo/util/SConscript
+++ b/src/mongo/util/SConscript
@@ -274,7 +274,7 @@ env.CppUnitTest(
"periodic_runner_impl_test.cpp",
],
LIBDEPS=[
- '$BUILD_DIR/mongo/db/service_context_noop_init',
+ "$BUILD_DIR/mongo/db/service_context_test_fixture",
"clock_source_mock",
"periodic_runner_impl",
],
diff --git a/src/mongo/util/periodic_runner_impl_test.cpp b/src/mongo/util/periodic_runner_impl_test.cpp
index 8575134688e..8e341f8e5b6 100644
--- a/src/mongo/util/periodic_runner_impl_test.cpp
+++ b/src/mongo/util/periodic_runner_impl_test.cpp
@@ -32,7 +32,7 @@
#include "mongo/util/periodic_runner_impl.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context_test_fixture.h"
#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/mutex.h"
#include "mongo/util/clock_source_mock.h"
@@ -43,12 +43,11 @@ class Client;
namespace {
-class PeriodicRunnerImplTestNoSetup : public unittest::Test {
+class PeriodicRunnerImplTestNoSetup : public ServiceContextTest {
public:
void setUp() override {
_clockSource = std::make_unique<ClockSourceMock>();
- _svc = stdx::make_unique<ServiceContextNoop>();
- _runner = stdx::make_unique<PeriodicRunnerImpl>(_svc.get(), _clockSource.get());
+ _runner = stdx::make_unique<PeriodicRunnerImpl>(getServiceContext(), _clockSource.get());
}
void tearDown() override {
@@ -64,7 +63,6 @@ public:
}
private:
- std::unique_ptr<ServiceContext> _svc;
std::unique_ptr<ClockSourceMock> _clockSource;
std::unique_ptr<PeriodicRunner> _runner;
};
diff --git a/src/mongo/util/producer_consumer_queue_test.cpp b/src/mongo/util/producer_consumer_queue_test.cpp
index 22577e791df..fa7af5e04a9 100644
--- a/src/mongo/util/producer_consumer_queue_test.cpp
+++ b/src/mongo/util/producer_consumer_queue_test.cpp
@@ -32,7 +32,7 @@
#include "mongo/util/producer_consumer_queue.h"
-#include "mongo/db/service_context_noop.h"
+#include "mongo/db/service_context.h"
#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/mutex.h"
#include "mongo/stdx/thread.h"
@@ -112,8 +112,6 @@ private:
class ProducerConsumerQueueTest : public unittest::Test {
public:
- ProducerConsumerQueueTest() : _serviceCtx(stdx::make_unique<ServiceContextNoop>()) {}
-
template <typename Callback>
stdx::thread runThread(StringData name, Callback&& cb) {
return stdx::thread([this, name, cb] {
@@ -153,7 +151,7 @@ public:
}
private:
- std::unique_ptr<ServiceContext> _serviceCtx;
+ ServiceContext::UniqueServiceContext _serviceCtx = ServiceContext::make();
};
class MoveOnly {