diff options
Diffstat (limited to 'src')
160 files changed, 1153 insertions, 2003 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index e2f48d3fdfb..2c5093dee1b 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -524,7 +524,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..2a49afcd2ca 100644 --- a/src/mongo/client/SConscript +++ b/src/mongo/client/SConscript @@ -36,8 +36,8 @@ env.CppUnitTest( 'mongo_uri_test.cpp', ], LIBDEPS=[ - 'clientdriver_network', '$BUILD_DIR/mongo/transport/transport_layer_egress_init', + 'clientdriver_network', ], ) @@ -211,6 +211,7 @@ env.CppIntegrationTest( ], LIBDEPS=[ 'clientdriver_network', + '$BUILD_DIR/mongo/transport/transport_layer_egress_init', '$BUILD_DIR/mongo/util/version_impl', ], ) @@ -326,7 +327,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/db/SConscript b/src/mongo/db/SConscript index 3fc627ea446..54445e732fd 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -234,7 +234,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', ], @@ -499,8 +498,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', ], @@ -517,16 +514,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", @@ -598,9 +585,9 @@ env.CppUnitTest( LIBDEPS=[ '$BUILD_DIR/mongo/idl/idl_parser', "commands", - "service_context_noop_init", "auth/authmocks", "repl/replmocks", + "service_context_test_fixture", ], ) @@ -665,7 +652,6 @@ env.CppUnitTest( 'auth/authmocks', 'catalog/database_holder_mock', 'catalog_raii', - 'service_context_noop_init', 'stats/fill_locker_info', ], ) @@ -714,7 +700,6 @@ env.Library( env.Library( target="service_context_d", source=[ - "service_context_d.cpp", "service_entry_point_mongod.cpp", ], LIBDEPS=[ @@ -931,9 +916,9 @@ env.Library( source=[ 'exec/projection_exec_agg.cpp', ], - LIBDEPS_PRIVATE=[ - 'pipeline/parsed_aggregation_projection' - ] + LIBDEPS=[ + 'pipeline/parsed_aggregation_projection', + ], ) env.Library( @@ -1196,13 +1181,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 +1382,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 +1392,7 @@ envWithAsio.CppUnitTest( 'logical_session_cache', 'logical_session_cache_impl', 'service_liaison_mock', + 'service_context_test_fixture', 'sessions_collection_mock', ], ) @@ -1755,6 +1739,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', @@ -1765,6 +1763,7 @@ env.Library( '$BUILD_DIR/mongo/db/storage/storage_options', '$BUILD_DIR/mongo/unittest/unittest', 'service_context_d', + 'service_context_test_fixture', ], ) @@ -1776,12 +1775,11 @@ env.Library( LIBDEPS=[ # this library is required only because of SERVER-29908 '$BUILD_DIR/mongo/db/s/sharding_runtime_d', + 'service_context_d_test_fixture', ], LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/db/auth/authmocks', '$BUILD_DIR/mongo/db/storage/devnull/storage_devnull', - '$BUILD_DIR/mongo/unittest/unittest', - 'service_context_d', ], ) @@ -1851,6 +1849,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(®isteredChanges); }; 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 c4873930036..0497c3fa74a 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/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/commands/index_filter_commands_test.cpp b/src/mongo/db/commands/index_filter_commands_test.cpp index 46423af1ed3..f9c6fb51f70 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 2be5c7c33d5..145f4f31846 100644 --- a/src/mongo/db/concurrency/d_concurrency_test.cpp +++ b/src/mongo/db/concurrency/d_concurrency_test.cpp @@ -37,6 +37,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" @@ -77,19 +78,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. @@ -101,8 +91,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)); @@ -129,20 +119,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(0LL, opDebug.writeConflicts); @@ -156,7 +143,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(), "", @@ -171,7 +158,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()); @@ -262,21 +249,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(); @@ -293,7 +280,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(); @@ -341,7 +328,7 @@ TEST_F(DConcurrencyTestFixture, TEST_F(DConcurrencyTestFixture, GlobalWriteRequiresSupportsDowngradeToIntentWriteModeWhileHoldingDatabaseLock) { - auto opCtx = makeOpCtx(); + auto opCtx = makeOperationContext(); opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>()); auto lockState = opCtx->lockState(); @@ -388,7 +375,7 @@ TEST_F(DConcurrencyTestFixture, TEST_F(DConcurrencyTestFixture, NestedGlobalWriteSupportsDowngradeToIntentWriteModeWhileHoldingDatabaseLock) { - auto opCtx = makeOpCtx(); + auto opCtx = makeOperationContext(); opCtx->swapLockState(stdx::make_unique<MMAPV1LockerImpl>()); auto lockState = opCtx->lockState(); @@ -595,7 +582,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()); @@ -609,7 +596,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()); @@ -825,7 +812,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); @@ -834,7 +821,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); @@ -843,7 +830,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); @@ -851,7 +838,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); @@ -859,7 +846,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); @@ -867,7 +854,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); @@ -875,7 +862,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); @@ -884,7 +871,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); @@ -897,7 +884,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); @@ -911,7 +898,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); @@ -925,7 +912,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(); @@ -956,7 +943,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 ea2fd75bb51..996a0123864 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -120,8 +120,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" @@ -323,8 +321,6 @@ ExitCode _initAndListen(int listenPort) { logProcessDetails(); - createLockFile(serviceContext); - serviceContext->setServiceEntryPoint( stdx::make_unique<ServiceEntryPointMongod>(serviceContext)); @@ -990,6 +986,8 @@ int mongoDbMain(int argc, char* argv[], char** envp) { severe(LogComponent::kControl) << "Failed global initialization: " << status; quickExit(EXIT_FAILURE); } + auto service = getGlobalServiceContext(); + service->setServiceEntryPoint(std::make_unique<ServiceEntryPointMongod>(service)); ErrorExtraInfo::invariantHaveAllParsers(); diff --git a/src/mongo/db/exec/SConscript b/src/mongo/db/exec/SConscript index 70d48105e2c..ba19b626965 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 29bf8ec9acd..76ba859fdee 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/logical_session_cache_test.cpp b/src/mongo/db/logical_session_cache_test.cpp index 98d3df0d000..37256c26670 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 96f2dd2ac51..7a314bd61b0 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 751aee986cc..4660afedd21 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 50a443d74f5..c272c6d3a2a 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 3d73e724af4..120996f96ff 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', @@ -353,7 +352,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', @@ -369,6 +367,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', @@ -396,8 +395,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', @@ -413,7 +411,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', ] ) @@ -503,7 +500,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 6a6d3232248..4062c497a53 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(DepsTracker::State::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 a52027feee7..7247f723a02 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -108,7 +108,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", ], @@ -203,6 +202,8 @@ env.Library( "$BUILD_DIR/mongo/db/logical_session_id", "$BUILD_DIR/mongo/db/service_context", ], + LIBDEPS_PRIVATE=[ + ], ) env.Library( @@ -263,6 +264,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/query_request_test.cpp b/src/mongo/db/query/query_request_test.cpp index cb0a537c85c..d52631051e5 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 { @@ -1322,20 +1322,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 187aa7f366c..ac1d6cb6f04 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -796,7 +796,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', @@ -852,10 +851,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', @@ -863,6 +862,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( @@ -885,7 +888,6 @@ env.CppUnitTest( 'repl_coordinator_impl', 'replmocks', '$BUILD_DIR/mongo/db/auth/authmocks', - '$BUILD_DIR/mongo/db/service_context_noop_init', ], ) @@ -908,7 +910,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', ], @@ -923,7 +924,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', ], @@ -939,7 +939,6 @@ env.CppUnitTest( 'replica_set_messages', 'replmocks', '$BUILD_DIR/mongo/db/auth/authmocks', - '$BUILD_DIR/mongo/db/service_context_noop_init', ], ) @@ -953,7 +952,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', ], @@ -992,7 +990,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=[ @@ -1007,17 +1004,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' @@ -1186,7 +1172,6 @@ env.CppUnitTest( source='oplog_fetcher_test.cpp', LIBDEPS=[ '$BUILD_DIR/mongo/db/auth/authmocks', - '$BUILD_DIR/mongo/db/service_context_noop_init', 'oplog_fetcher', 'data_replicator_external_state_mock', 'abstract_oplog_fetcher_test_fixture', @@ -1215,7 +1200,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', ], ) @@ -1300,7 +1284,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', ], ) @@ -1327,7 +1310,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', ], ) @@ -1351,7 +1333,6 @@ env.CppUnitTest( 'oplog_entry', 'replmocks', '$BUILD_DIR/mongo/db/auth/authmocks', - '$BUILD_DIR/mongo/db/service_context_noop_init', '$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture', '$BUILD_DIR/mongo/unittest/task_executor_proxy', ], @@ -1368,32 +1349,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', @@ -1442,7 +1415,6 @@ env.CppUnitTest( source='multiapplier_test.cpp', LIBDEPS=[ 'multiapplier', - 'service_context_repl_mock_init', '$BUILD_DIR/mongo/db/auth/authmocks', '$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture', '$BUILD_DIR/mongo/unittest/task_executor_proxy', @@ -1533,7 +1505,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/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/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index a3f3c3e2669..d009a9914fc 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -56,7 +56,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" @@ -828,10 +828,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" @@ -861,6 +857,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); @@ -869,10 +866,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" @@ -940,7 +933,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 cb57c8b8456..0af63a22dc6 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -306,6 +306,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/migration_chunk_cloner_source_legacy.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp index be6aafbe27f..43144f59b99 100644 --- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp +++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp @@ -557,7 +557,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 155eed7cae3..5e4cde64b6e 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}); 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()); } } @@ -86,7 +75,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, GiveUpWaitingForNotify) { { auto scopedNotif = notifications.createNotification(kNss); - auto opCtx = client()->makeOperationContext(); + auto opCtx = getClient()->makeOperationContext(); opCtx->setDeadlineAfterNowBy(Milliseconds{0}); ASSERT_THROWS_CODE( scopedNotif.get(opCtx.get()), AssertionException, ErrorCodes::ExceededTimeLimit); @@ -102,7 +91,7 @@ TEST_F(NamespaceMetadataChangeNotificationsTest, MoveConstructionWaitForNotify) auto movedScopedNotif = std::move(scopedNotif); { - auto opCtx = client()->makeOperationContext(); + auto opCtx = getClient()->makeOperationContext(); opCtx->setDeadlineAfterNowBy(Milliseconds{0}); ASSERT_THROWS_CODE( movedScopedNotif.get(opCtx.get()), AssertionException, ErrorCodes::ExceededTimeLimit); @@ -111,7 +100,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 c45ddb1e71d..d7843fcac26 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..a3749d29ce0 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,72 @@ void ServiceContext::notifyStartupComplete() { _startupCompleteCondVar.notify_all(); } +namespace { + +// clang-format off +GlobalInitializerRegisterer registerCreateServiceContext{ + "ServiceContext", + {"default"}, + [](InitializerContext* context) { + setGlobalServiceContext(ServiceContext::make()); + return Status::OK(); + }, + [](DeinitializerContext* context) { + // For now, deregistration is done manually after all deinitializers run, in case any + // erroneously access the globalServiceContext without expressing a dependency. + return Status::OK(); + } +}; +// clang-format on + +/** + * Accessor function to get the global list of ServiceContext constructor and destructor + * functions. + */ +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), + std::vector<std::string>{"ServiceContext"}, + [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 ae0e39a2ab4..3ae23161235 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,48 +30,40 @@ #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" namespace mongo { -void ServiceContextMongoDTest::setUp() { - Test::setUp(); - Client::initThread(getThreadName()); +ServiceContextMongoDTest::ServiceContextMongoDTest() + : ServiceContextMongoDTest("ephemeralForTest") {} - auto const serviceContext = getServiceContext(); +ServiceContextMongoDTest::ServiceContextMongoDTest(std::string engine) { - auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext); + _stashedStorageParams.engine = std::exchange(storageGlobalParams.engine, std::move(engine)); + _stashedStorageParams.engineSetByUser = + std::exchange(storageGlobalParams.engineSetByUser, true); + + 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; + unittest::TempDir tempDir("service_context_d_test_fixture"); + storageGlobalParams.dbpath = tempDir.path(); - createLockFile(serviceContext); - initializeStorageEngine(serviceContext, StorageEngineInitFlags::kNone); - serviceContext->setOpObserver(stdx::make_unique<OpObserverNoop>()); - } + 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 @@ -79,44 +71,19 @@ 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())); -} - -void ServiceContextMongoDTest::tearDown() { - ON_BLOCK_EXIT([&] { Client::destroy(); }); - auto opCtx = cc().makeOperationContext(); - _dropAllDBs(opCtx.get()); - Test::tearDown(); + auto observerRegistry = checked_cast<OpObserverRegistry*>(serviceContext->getOpObserver()); + observerRegistry->addObserver(std::make_unique<UUIDCatalogObserver>()); } -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); + catalog::closeCatalog(opCtx.get()); } - - // 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); } } // 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 bd56f4f2ae6..19619f0d0fe 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,7 @@ #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/unittest.h" namespace mongo { @@ -37,40 +37,21 @@ namespace mongo { /** * Test fixture class for tests that use the "ephemeralForTest" storage engine. */ -class ServiceContextMongoDTest : public unittest::Test { -public: - /** - * Initializes global storage engine. - */ - void setUp() override; - - /** - * Clear all databases. - */ - void tearDown() override; +class ServiceContextMongoDTest : public ServiceContextTest { +protected: + 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); + 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; + } _stashedStorageParams; }; } // namespace mongo diff --git a/src/mongo/db/service_context_devnull_test_fixture.cpp b/src/mongo/db/service_context_devnull_test_fixture.cpp index e3d47823733..6bd2ea21b5b 100644 --- a/src/mongo/db/service_context_devnull_test_fixture.cpp +++ b/src/mongo/db/service_context_devnull_test_fixture.cpp @@ -30,41 +30,9 @@ #include "mongo/db/service_context_devnull_test_fixture.h" -#include "mongo/db/client.h" -#include "mongo/db/operation_context.h" -#include "mongo/db/service_context.h" -#include "mongo/db/service_context_d.h" -#include "mongo/db/storage/storage_engine_init.h" -#include "mongo/stdx/memory.h" -#include "mongo/unittest/temp_dir.h" -#include "mongo/util/assert_util.h" - namespace mongo { -void ServiceContextDevnullTestFixture::setUp() { - Test::setUp(); - Client::initThread(getThreadName()); - - auto const serviceContext = getServiceContext(); - if (!serviceContext->getStorageEngine()) { - // When using the 'devnull' storage engine, it is fine for the temporary directory to - // go away after the global storage engine is initialized. - unittest::TempDir tempDir("service_context_devnull_test"); - mongo::storageGlobalParams.dbpath = tempDir.path(); - mongo::storageGlobalParams.engine = "devnull"; - mongo::storageGlobalParams.engineSetByUser = true; - createLockFile(serviceContext); - initializeStorageEngine(serviceContext, StorageEngineInitFlags::kNone); - } -} - -void ServiceContextDevnullTestFixture::tearDown() { - Client::destroy(); - Test::tearDown(); -} - -ServiceContext* ServiceContextDevnullTestFixture::getServiceContext() { - return getGlobalServiceContext(); -} +ServiceContextDevnullTestFixture::ServiceContextDevnullTestFixture() + : ServiceContextMongoDTest("devnull") {} } // namespace mongo diff --git a/src/mongo/db/service_context_devnull_test_fixture.h b/src/mongo/db/service_context_devnull_test_fixture.h index 77a0d551965..1304546f903 100644 --- a/src/mongo/db/service_context_devnull_test_fixture.h +++ b/src/mongo/db/service_context_devnull_test_fixture.h @@ -28,30 +28,16 @@ #pragma once -#include "mongo/unittest/unittest.h" +#include "mongo/db/service_context_d_test_fixture.h" namespace mongo { -class ServiceContext; - /** * Test fixture class for mongod tests that use the "devnull" storage engine. */ -class ServiceContextDevnullTestFixture : public unittest::Test { -public: - /** - * Initializes the devnull engine as the global storage engine. - * Also sets up a Client on the thread, which can be accessed via 'cc()'. - */ - void setUp() override; - - void tearDown() override; - - /** - * 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(); +class ServiceContextDevnullTestFixture : public ServiceContextMongoDTest { +protected: + ServiceContextDevnullTestFixture(); }; } // 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..486478f56e6 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,35 @@ #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>(); -}); +ServiceContextTest::ServiceContextTest() { + setGlobalServiceContext(ServiceContext::make()); + auto const serviceContext = getGlobalServiceContext(); + Client::initThread(getThreadName()); + auto observerRegistry = std::make_unique<OpObserverRegistry>(); + serviceContext->setOpObserver(std::move(observerRegistry)); +} + +ServiceContextTest::~ServiceContextTest() { + Client::destroy(); + setGlobalServiceContext({}); +} + +ServiceContext* ServiceContextTest::getServiceContext() { + return getGlobalServiceContext(); +} + +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..1e23c6666d2 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,35 @@ #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 { +/** + * Test fixture for tests that require a properly initialized global service context. + */ +class ServiceContextTest : public unittest::Test { public: - ServiceContextMongoEmbedded(); - - ~ServiceContextMongoEmbedded(); - -private: - std::unique_ptr<OperationContext> _newOpCtx(Client* client, unsigned opId) override; + /** + * 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(); + + /** + * Returns the default Client for this test. + */ + Client* getClient(); + + ServiceContext::UniqueOperationContext makeOperationContext() { + return getClient()->makeOperationContext(); + } + +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/sorter/sorter_test.cpp b/src/mongo/db/sorter/sorter_test.cpp index 6fb550b24cd..3d9fc03b58f 100644 --- a/src/mongo/db/sorter/sorter_test.cpp +++ b/src/mongo/db/sorter/sorter_test.cpp @@ -36,9 +36,6 @@ #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/platform/random.h" #include "mongo/stdx/thread.h" #include "mongo/unittest/temp_dir.h" @@ -55,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 // diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript index 398007c45fa..0a2e629e9b6 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..7edb39d2366 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,6 @@ 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/storage/devnull/storage_devnull_core', '$BUILD_DIR/mongo/db/storage/ephemeral_for_test/ephemeral_for_test_record_store', ], @@ -131,7 +131,6 @@ 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/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_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 4330a4906fa..e9d6c0accab 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" @@ -48,21 +49,13 @@ #include "mongo/unittest/unittest.h" namespace mongo { +namespace { -class KVStorageEngineTest : public unittest::Test { +class KVStorageEngineTest : public ServiceContextMongoDTest { public: KVStorageEngineTest() - : _storageEngine(stdx::make_unique<KVStorageEngine>(new EphemeralForTestEngine(), - KVStorageEngineOptions())) {} - - void setUp() final { - _serviceContext.setUp(); - } - - void tearDown() final { - _storageEngine->cleanShutdown(); - _serviceContext.tearDown(); - } + : ServiceContextMongoDTest("ephemeralForTest"), + _storageEngine(checked_cast<KVStorageEngine*>(getServiceContext()->getStorageEngine())) {} /** * Create a collection in the catalog and in the KVEngine. Return the storage engine's `ident`. @@ -134,8 +127,7 @@ public: return Status::OK(); } - ServiceContextMongoDTest _serviceContext; - std::unique_ptr<KVStorageEngine> _storageEngine; + KVStorageEngine* _storageEngine; }; TEST_F(KVStorageEngineTest, ReconcileIdentsTest) { @@ -229,4 +221,6 @@ TEST_F(KVStorageEngineTest, RecreateIndexes) { return str.find("index-") == 0; })); } + +} // namespace } // namespace mongo 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 c0891f0235d..e21947e917c 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" @@ -54,9 +53,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(); @@ -66,26 +65,22 @@ 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(); } virtual std::unique_ptr<RecoveryUnit> newRecoveryUnit() = 0; - -private: - ServiceContextNoop _serviceContext; - ServiceContext::UniqueClient _client = _serviceContext.makeClient("hh"); }; namespace harness_helper_detail { 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_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_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/update/SConscript b/src/mongo/db/update/SConscript index 37895498200..405f3a5bb9c 100644 --- a/src/mongo/db/update/SConscript +++ b/src/mongo/db/update/SConscript @@ -120,7 +120,6 @@ env.CppUnitTest( '$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..050c9444e75 100644 --- a/src/mongo/db/update/update_node_test_fixture.h +++ b/src/mongo/db/update/update_node_test_fixture.h @@ -29,7 +29,7 @@ #pragma once #include "mongo/db/logical_clock.h" -#include "mongo/db/service_context_noop.h" +#include "mongo/db/service_context.h" #include "mongo/db/update/update_node.h" #include "mongo/unittest/unittest.h" diff --git a/src/mongo/db/views/SConscript b/src/mongo/db/views/SConscript index 95300503828..b03379bd81a 100644 --- a/src/mongo/db/views/SConscript +++ b/src/mongo/db/views/SConscript @@ -46,7 +46,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 e4e5061a21c..ac22a1b6247 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 2aff3249936..a0823458812 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" @@ -171,6 +170,7 @@ int dbtestsMain(int argc, char** argv, char** envp) { repl::ReplSettings replSettings; replSettings.setOplogSizeBytes(10 * 1024 * 1024); 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 e7926489671..697a8ce1abd 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 6cda42ae07f..d954cf9d727 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 0cfb20659f8..73dc960d1c3 100644 --- a/src/mongo/embedded/SConscript +++ b/src/mongo/embedded/SConscript @@ -21,7 +21,6 @@ env.Library( 'embedded_options_parser_init.cpp', 'index_create_impl_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 a548a6922e2..a7c5c6c719d 100644 --- a/src/mongo/embedded/embedded.cpp +++ b/src/mongo/embedded/embedded.cpp @@ -50,14 +50,12 @@ #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" #include "mongo/db/storage/storage_engine_init.h" #include "mongo/db/ttl.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" @@ -98,11 +96,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); @@ -111,16 +108,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) { @@ -188,6 +175,7 @@ ServiceContext* initialize(const char* yaml_config) { 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/rpc/SConscript b/src/mongo/rpc/SConscript index 1acf5acae73..35651a9edd6 100644 --- a/src/mongo/rpc/SConscript +++ b/src/mongo/rpc/SConscript @@ -270,6 +270,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 bda3163ced7..553f2211387 100644 --- a/src/mongo/s/SConscript +++ b/src/mongo/s/SConscript @@ -180,7 +180,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', @@ -485,9 +485,7 @@ env.CppUnitTest( 'client/shard_connection_test.cpp', ], LIBDEPS=[ - '$BUILD_DIR/mongo/db/service_context_noop_init', '$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 b944ac0bb8d..61efb9ae468 100644 --- a/src/mongo/s/async_requests_sender.cpp +++ b/src/mongo/s/async_requests_sender.cpp @@ -392,7 +392,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 a1ab2acbba7..835aedebf2f 100644 --- a/src/mongo/s/catalog_cache_test_fixture.cpp +++ b/src/mongo/s/catalog_cache_test_fixture.cpp @@ -57,15 +57,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_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 cfb4aca929c..c1e7a9d1092 100644 --- a/src/mongo/s/commands/SConscript +++ b/src/mongo/s/commands/SConscript @@ -129,7 +129,6 @@ env.CppUnitTest( LIBDEPS=[ 'shared_cluster_commands', '$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', ] @@ -144,7 +143,6 @@ env.CppUnitTest( 'shared_cluster_commands', '$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', ] @@ -159,7 +157,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 826ac629429..42926b7e5e6 100644 --- a/src/mongo/s/metadata_filtering_test.cpp +++ b/src/mongo/s/metadata_filtering_test.cpp @@ -53,7 +53,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 cd9a6c903c4..07ace658aab 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_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 5978f4d4f4c..9e7358b2ca6 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) { 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 132e375b160..e42c1e41316 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 c06d9a568b7..964e70e18b6 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" diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp index 6332f1cc5fe..26086ee29d1 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() { 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 8e749228631..86e7187a37f 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" @@ -135,7 +135,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>(); @@ -152,7 +152,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..e3593d9ff8b 100644 --- a/src/mongo/unittest/SConscript +++ b/src/mongo/unittest/SConscript @@ -46,8 +46,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', ], ) diff --git a/src/mongo/unittest/integration_test_main.cpp b/src/mongo/unittest/integration_test_main.cpp index b4087176542..b2e3168bccc 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" diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript index d83b7c86759..54caf685b28 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 cd2937c50e1..1ffda65bfaa 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 { |