diff options
author | Benety Goh <benety@mongodb.com> | 2021-09-27 19:08:32 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-27 23:35:27 +0000 |
commit | 6b3acc72af58963a772213cc882e34b6db5bf144 (patch) | |
tree | 1c37708f6b81afac87a0f4605261f304695cfdd5 | |
parent | 8f7c3dd749c5f2a6c410e19e78fad96fb0bf03cb (diff) | |
download | mongo-6b3acc72af58963a772213cc882e34b6db5bf144.tar.gz |
SERVER-59618 add LockerNoopClientObserver and register this ClientObserver in unit tests with Service Context
18 files changed, 166 insertions, 20 deletions
diff --git a/src/mongo/db/concurrency/locker_noop_client_observer.h b/src/mongo/db/concurrency/locker_noop_client_observer.h new file mode 100644 index 00000000000..2e179601443 --- /dev/null +++ b/src/mongo/db/concurrency/locker_noop_client_observer.h @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2021-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/db/concurrency/locker_noop.h" +#include "mongo/db/service_context.h" + +namespace mongo { + +/** + * ServiceContext hook that ensures OperationContexts are created with a valid + * Locker instance. Intended for use in tests that do not require a storage engine. + */ +class LockerNoopClientObserver : public ServiceContext::ClientObserver { +public: + LockerNoopClientObserver() = default; + ~LockerNoopClientObserver() = default; + + void onCreateClient(Client* client) final {} + + void onDestroyClient(Client* client) final {} + + void onCreateOperationContext(OperationContext* opCtx) final { + opCtx->setLockState(std::make_unique<LockerNoop>()); + } + + void onDestroyOperationContext(OperationContext* opCtx) final {} +}; + +} // namespace mongo diff --git a/src/mongo/db/concurrency/locker_noop_service_context_test_fixture.h b/src/mongo/db/concurrency/locker_noop_service_context_test_fixture.h new file mode 100644 index 00000000000..ef4394056d3 --- /dev/null +++ b/src/mongo/db/concurrency/locker_noop_service_context_test_fixture.h @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2021-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/db/concurrency/locker_noop_client_observer.h" +#include "mongo/db/service_context_test_fixture.h" + +namespace mongo { + +/** + * Test fixture for tests that require a properly initialized global service context + * and a stub Locker implementation whenever an OperationContext is requested. + */ +class LockerNoopServiceContextTest : public ServiceContextTest { +protected: + LockerNoopServiceContextTest() { + auto service = getServiceContext(); + service->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + } + + ~LockerNoopServiceContextTest() = default; +}; + +} // namespace mongo diff --git a/src/mongo/db/exec/sbe/SConscript b/src/mongo/db/exec/sbe/SConscript index 68c00419ae6..3a52248e9ac 100644 --- a/src/mongo/db/exec/sbe/SConscript +++ b/src/mongo/db/exec/sbe/SConscript @@ -116,6 +116,9 @@ env.Library( '$BUILD_DIR/mongo/unittest/unittest', 'query_sbe', ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/service_context_test_fixture', + ], ) env.CppUnitTest( diff --git a/src/mongo/db/ftdc/ftdc_test.h b/src/mongo/db/ftdc/ftdc_test.h index 2076d77a1ac..902b9104987 100644 --- a/src/mongo/db/ftdc/ftdc_test.h +++ b/src/mongo/db/ftdc/ftdc_test.h @@ -30,12 +30,12 @@ #include <boost/filesystem.hpp> #include <vector> +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/db/jsobj.h" -#include "mongo/db/service_context_test_fixture.h" namespace mongo { -class FTDCTest : public ServiceContextTest { +class FTDCTest : public LockerNoopServiceContextTest { public: FTDCTest(); }; diff --git a/src/mongo/db/stats/resource_consumption_metrics_test.cpp b/src/mongo/db/stats/resource_consumption_metrics_test.cpp index 8c7d8a756ef..74245509594 100644 --- a/src/mongo/db/stats/resource_consumption_metrics_test.cpp +++ b/src/mongo/db/stats/resource_consumption_metrics_test.cpp @@ -29,8 +29,8 @@ #include "mongo/platform/basic.h" +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/db/repl/replication_coordinator_mock.h" -#include "mongo/db/service_context_test_fixture.h" #include "mongo/db/stats/operation_resource_consumption_gen.h" #include "mongo/db/stats/resource_consumption_metrics.h" #include "mongo/unittest/unittest.h" @@ -49,7 +49,7 @@ ServerParameter* getServerParameter(const std::string& name) { } } // namespace -class ResourceConsumptionMetricsTest : public ServiceContextTest { +class ResourceConsumptionMetricsTest : public LockerNoopServiceContextTest { public: void setUp() { _opCtx = makeOperationContext(); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp index 5d9f038bcbe..daa8626b616 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.cpp @@ -29,6 +29,7 @@ #include "mongo/db/storage/wiredtiger/wiredtiger_record_store_test_harness.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/operation_context_noop.h" #include "mongo/db/repl/replication_coordinator_mock.h" @@ -46,6 +47,9 @@ WiredTigerHarnessHelper::WiredTigerHarnessHelper(StringData extraStrings) false, false, false) { + auto service = getServiceContext(); + service->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + repl::ReplicationCoordinator::set( serviceContext(), std::make_unique<repl::ReplicationCoordinatorMock>(serviceContext(), repl::ReplSettings())); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_standard_index_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_standard_index_test.cpp index b050a4a2f88..09c654ca822 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_standard_index_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_standard_index_test.cpp @@ -35,6 +35,7 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/catalog/collection_mock.h" #include "mongo/db/catalog/index_catalog_entry.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/json.h" #include "mongo/db/operation_context_noop.h" @@ -56,6 +57,9 @@ using std::string; class WiredTigerIndexHarnessHelper final : public SortedDataInterfaceHarnessHelper { public: WiredTigerIndexHarnessHelper() : _dbpath("wt_test"), _conn(nullptr) { + auto service = getServiceContext(); + service->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + const char* config = "create,cache_size=1G,"; int ret = wiredtiger_open(_dbpath.path().c_str(), nullptr, config, &_conn); invariantWTOK(ret); diff --git a/src/mongo/db/update/update_node_test_fixture.h b/src/mongo/db/update/update_node_test_fixture.h index b9c27ed8bc0..22065cc7088 100644 --- a/src/mongo/db/update/update_node_test_fixture.h +++ b/src/mongo/db/update/update_node_test_fixture.h @@ -29,8 +29,8 @@ #pragma once +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/db/service_context.h" -#include "mongo/db/service_context_test_fixture.h" #include "mongo/db/update/update_node.h" #include "mongo/db/update/v1_log_builder.h" #include "mongo/db/update/v2_log_builder.h" @@ -38,7 +38,7 @@ namespace mongo { -class UpdateNodeTest : public ServiceContextTest { +class UpdateNodeTest : public LockerNoopServiceContextTest { public: ~UpdateNodeTest() override = default; diff --git a/src/mongo/executor/task_executor_cursor_integration_test.cpp b/src/mongo/executor/task_executor_cursor_integration_test.cpp index f145d67826e..e3c3fde671d 100644 --- a/src/mongo/executor/task_executor_cursor_integration_test.cpp +++ b/src/mongo/executor/task_executor_cursor_integration_test.cpp @@ -32,6 +32,7 @@ #include "mongo/executor/task_executor_cursor.h" #include "mongo/client/dbclient_base.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/namespace_string.h" #include "mongo/executor/network_interface_factory.h" #include "mongo/executor/network_interface_thread_pool.h" @@ -45,6 +46,10 @@ namespace { class TaskExecutorCursorFixture : public mongo::unittest::Test { public: + TaskExecutorCursorFixture() { + _serviceCtx->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + } + void setUp() override { std::shared_ptr<NetworkInterface> ni = makeNetworkInterface("TaskExecutorCursorTest"); auto tp = std::make_unique<NetworkInterfaceThreadPool>(ni.get()); diff --git a/src/mongo/executor/task_executor_cursor_test.cpp b/src/mongo/executor/task_executor_cursor_test.cpp index 31b1ae7bcf8..4f9132fd387 100644 --- a/src/mongo/executor/task_executor_cursor_test.cpp +++ b/src/mongo/executor/task_executor_cursor_test.cpp @@ -31,6 +31,7 @@ #include "mongo/platform/basic.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/executor/task_executor_cursor.h" #include "mongo/executor/thread_pool_task_executor_test_fixture.h" #include "mongo/unittest/bson_test_util.h" @@ -46,6 +47,10 @@ namespace { */ class TaskExecutorCursorFixture : public ThreadPoolExecutorTest { public: + TaskExecutorCursorFixture() { + serviceCtx->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + } + void setUp() override { ThreadPoolExecutorTest::setUp(); diff --git a/src/mongo/executor/task_executor_test_common.cpp b/src/mongo/executor/task_executor_test_common.cpp index 0a4f534587e..ecdae5eb5b1 100644 --- a/src/mongo/executor/task_executor_test_common.cpp +++ b/src/mongo/executor/task_executor_test_common.cpp @@ -35,6 +35,7 @@ #include <memory> +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/operation_context.h" #include "mongo/executor/network_interface.h" #include "mongo/executor/network_interface_mock.h" @@ -361,6 +362,7 @@ COMMON_EXECUTOR_TEST(EventWaitingWithTimeoutTest) { auto serviceContext = ServiceContext::make(); + serviceContext->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); serviceContext->setFastClockSource(std::make_unique<ClockSourceMock>()); auto mockClock = static_cast<ClockSourceMock*>(serviceContext->getFastClockSource()); @@ -383,6 +385,7 @@ COMMON_EXECUTOR_TEST(EventSignalWithTimeoutTest) { auto serviceContext = ServiceContext::make(); + serviceContext->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); serviceContext->setFastClockSource(std::make_unique<ClockSourceMock>()); auto mockClock = static_cast<ClockSourceMock*>(serviceContext->getFastClockSource()); diff --git a/src/mongo/transport/service_state_machine_test.cpp b/src/mongo/transport/service_state_machine_test.cpp index cae5c81e41d..3f218bf8c9b 100644 --- a/src/mongo/transport/service_state_machine_test.cpp +++ b/src/mongo/transport/service_state_machine_test.cpp @@ -39,9 +39,9 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/client.h" #include "mongo/db/client_strand.h" +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/db/dbmessage.h" #include "mongo/db/service_context.h" -#include "mongo/db/service_context_test_fixture.h" #include "mongo/logv2/log.h" #include "mongo/platform/mutex.h" #include "mongo/rpc/op_msg.h" @@ -68,7 +68,7 @@ namespace { * ServiceStateMachine so as to provide a deterministic way to evaluate the state machine * implemenation. */ -class ServiceStateMachineTest : public ServiceContextTest { +class ServiceStateMachineTest : public LockerNoopServiceContextTest { /** * This class stores and synchronizes the shared data between the test fixture and its various * wrappers. diff --git a/src/mongo/util/fail_point_test.cpp b/src/mongo/util/fail_point_test.cpp index 7ad3ba4f0b0..5f97f341923 100644 --- a/src/mongo/util/fail_point_test.cpp +++ b/src/mongo/util/fail_point_test.cpp @@ -37,6 +37,7 @@ #include <vector> #include "mongo/db/client.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/operation_context.h" #include "mongo/logv2/log.h" #include "mongo/platform/atomic_word.h" @@ -457,6 +458,7 @@ namespace mongo { void assertFunctionInterruptible(std::function<void(Interruptible* interruptible)> f) { const auto service = ServiceContext::make(); const std::shared_ptr<ClockSourceMock> mockClock = std::make_shared<ClockSourceMock>(); + service->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); service->setFastClockSource(std::make_unique<SharedClockSourceAdapter>(mockClock)); service->setPreciseClockSource(std::make_unique<SharedClockSourceAdapter>(mockClock)); service->setTickSource(std::make_unique<TickSourceMock<>>()); diff --git a/src/mongo/util/log_with_sampling_test.cpp b/src/mongo/util/log_with_sampling_test.cpp index 61121221a80..4802b2860ce 100644 --- a/src/mongo/util/log_with_sampling_test.cpp +++ b/src/mongo/util/log_with_sampling_test.cpp @@ -31,6 +31,7 @@ #include "mongo/platform/basic.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/service_context_test_fixture.h" #include "mongo/logv2/log.h" #include "mongo/unittest/log_test.h" @@ -55,6 +56,7 @@ namespace { auto scenario(bool debugLogEnabled, bool slowOp, bool forceSample) { static const logv2::LogComponent component = logv2::LogComponent::kDefault; const auto serviceContext = ServiceContext::make(); + serviceContext->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); const auto client = serviceContext->makeClient("log_with_sampling_test"); const auto opCtx = client->makeOperationContext(); diff --git a/src/mongo/util/periodic_runner_impl_test.cpp b/src/mongo/util/periodic_runner_impl_test.cpp index 6fd5639a161..6f180269cec 100644 --- a/src/mongo/util/periodic_runner_impl_test.cpp +++ b/src/mongo/util/periodic_runner_impl_test.cpp @@ -38,7 +38,7 @@ #include "mongo/util/periodic_runner_impl.h" -#include "mongo/db/service_context_test_fixture.h" +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/platform/mutex.h" #include "mongo/stdx/condition_variable.h" #include "mongo/util/clock_source_mock.h" @@ -49,7 +49,7 @@ class Client; namespace { -class PeriodicRunnerImplTestNoSetup : public ServiceContextTest { +class PeriodicRunnerImplTestNoSetup : public LockerNoopServiceContextTest { public: void setUp() override { _clockSource = std::make_unique<ClockSourceMock>(); diff --git a/src/mongo/util/producer_consumer_queue_test.cpp b/src/mongo/util/producer_consumer_queue_test.cpp index dd9c9836816..538ee54808a 100644 --- a/src/mongo/util/producer_consumer_queue_test.cpp +++ b/src/mongo/util/producer_consumer_queue_test.cpp @@ -33,6 +33,7 @@ #include "mongo/util/producer_consumer_queue.h" +#include "mongo/db/concurrency/locker_noop_client_observer.h" #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/platform/mutex.h" @@ -135,6 +136,10 @@ std::enable_if_t<requiresMultiProducer && requiresMultiConsumer> runCallbackWith class ProducerConsumerQueueTest : public unittest::Test { public: + ProducerConsumerQueueTest() { + _serviceCtx->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + } + template <bool requiresMultiProducer, bool requiresMultiConsumer, typename Callback> void runPermutations(Callback&& callback) { runCallbackWithPerms<requiresMultiProducer, requiresMultiConsumer>([&](auto x_, auto y_) { diff --git a/src/mongo/util/read_through_cache_test.cpp b/src/mongo/util/read_through_cache_test.cpp index 8e7de5c4d2f..ae6d89a1a70 100644 --- a/src/mongo/util/read_through_cache_test.cpp +++ b/src/mongo/util/read_through_cache_test.cpp @@ -31,8 +31,8 @@ #include <string> +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/db/operation_context.h" -#include "mongo/db/service_context_test_fixture.h" #include "mongo/unittest/barrier.h" #include "mongo/unittest/unittest.h" #include "mongo/util/concurrency/thread_pool.h" @@ -101,7 +101,7 @@ private: * Fixture for tests, which do not need to exercise the multi-threading capabilities of the cache * and as such do not require control over the creation/destruction of their operation contexts. */ -class ReadThroughCacheTest : public ServiceContextTest { +class ReadThroughCacheTest : public LockerNoopServiceContextTest { protected: // Extends any of Cache/CausallyConsistentCache and automatically provides it with a thread // pool, which will be shutdown and joined before the Cache is destroyed (which is part of the @@ -366,8 +366,13 @@ TEST_F(ReadThroughCacheTest, CausalConsistency) { /** * Fixture for tests, which need to control the creation/destruction of their operation contexts. */ -class ReadThroughCacheAsyncTest : public unittest::Test, - public ScopedGlobalServiceContextForTest {}; +class ReadThroughCacheAsyncTest : public unittest::Test, public ScopedGlobalServiceContextForTest { +public: + ReadThroughCacheAsyncTest() { + auto service = getServiceContext(); + service->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); + } +}; using Barrier = unittest::Barrier; diff --git a/src/mongo/watchdog/watchdog_test.cpp b/src/mongo/watchdog/watchdog_test.cpp index fe2654aee79..178fa9a3411 100644 --- a/src/mongo/watchdog/watchdog_test.cpp +++ b/src/mongo/watchdog/watchdog_test.cpp @@ -36,8 +36,8 @@ #include <memory> #include "mongo/db/client.h" +#include "mongo/db/concurrency/locker_noop_service_context_test_fixture.h" #include "mongo/db/service_context.h" -#include "mongo/db/service_context_test_fixture.h" #include "mongo/logv2/log.h" #include "mongo/unittest/death_test.h" #include "mongo/unittest/temp_dir.h" @@ -93,7 +93,7 @@ private: std::uint32_t _wait{0}; }; -class PeriodicThreadTest : public ServiceContextTest {}; +class PeriodicThreadTest : public LockerNoopServiceContextTest {}; // Tests: // 1. Make sure it runs at least N times @@ -246,7 +246,7 @@ private: std::uint32_t _wait{0}; }; -class WatchdogCheckThreadTest : public ServiceContextTest {}; +class WatchdogCheckThreadTest : public LockerNoopServiceContextTest {}; // Positive: Make sure check thread runs at least N times and stops correctly TEST_F(WatchdogCheckThreadTest, Basic) { @@ -301,7 +301,7 @@ private: }; -class WatchdogMonitorThreadTest : public ServiceContextTest {}; +class WatchdogMonitorThreadTest : public LockerNoopServiceContextTest {}; // Positive: Make sure monitor thread signals death if the check thread never starts TEST_F(WatchdogMonitorThreadTest, Basic) { @@ -376,7 +376,7 @@ TEST_F(WatchdogMonitorThreadTest, SleepyHungCheck) { checkThread.shutdown(); } -class WatchdogMonitorTest : public ServiceContextTest {}; +class WatchdogMonitorTest : public LockerNoopServiceContextTest {}; // Positive: Make sure watchdog monitor signals death if a check is unresponsive TEST_F(WatchdogMonitorTest, SleepyHungCheck) { @@ -471,7 +471,7 @@ TEST_F(WatchdogMonitorTest, PauseAndResume) { ASSERT_EQ(lastCounter, counterCheckPtr->getCounter()); } -class DirectoryCheckTest : public ServiceContextTest {}; +class DirectoryCheckTest : public LockerNoopServiceContextTest {}; // Positive: Do a sanity check that directory check passes TEST_F(DirectoryCheckTest, Basic) { |