diff options
Diffstat (limited to 'src/mongo/executor')
-rw-r--r-- | src/mongo/executor/SConscript | 8 | ||||
-rw-r--r-- | src/mongo/executor/mock_network_fixture.cpp | 148 | ||||
-rw-r--r-- | src/mongo/executor/mock_network_fixture.h | 237 | ||||
-rw-r--r-- | src/mongo/executor/mock_network_fixture_test.cpp | 102 | ||||
-rw-r--r-- | src/mongo/executor/network_interface_mock_test.cpp | 57 | ||||
-rw-r--r-- | src/mongo/executor/network_interface_mock_test_fixture.cpp | 64 | ||||
-rw-r--r-- | src/mongo/executor/network_interface_mock_test_fixture.h | 70 |
7 files changed, 629 insertions, 57 deletions
diff --git a/src/mongo/executor/SConscript b/src/mongo/executor/SConscript index 600547a89b7..2cb463484bd 100644 --- a/src/mongo/executor/SConscript +++ b/src/mongo/executor/SConscript @@ -85,6 +85,7 @@ env.Library( env.Library( target='network_interface_mock', source=[ + 'mock_network_fixture.cpp', 'network_interface_mock.cpp', 'thread_pool_mock.cpp', ], @@ -95,7 +96,10 @@ env.Library( '$BUILD_DIR/mongo/util/net/network', 'network_interface', 'task_executor_interface', - ] + ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/matcher/expressions', + ], ) env.Library( @@ -281,7 +285,9 @@ env.CppUnitTest( source=[ 'connection_pool_test.cpp', 'connection_pool_test_fixture.cpp', + 'mock_network_fixture_test.cpp', 'network_interface_mock_test.cpp', + 'network_interface_mock_test_fixture.cpp', 'scoped_task_executor_test.cpp', 'task_executor_cursor_test.cpp', 'thread_pool_task_executor_test.cpp', diff --git a/src/mongo/executor/mock_network_fixture.cpp b/src/mongo/executor/mock_network_fixture.cpp new file mode 100644 index 00000000000..da028d8a6ba --- /dev/null +++ b/src/mongo/executor/mock_network_fixture.cpp @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2020-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. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kTest + +#include "mongo/platform/basic.h" + +#include "mongo/executor/mock_network_fixture.h" + +#include "mongo/db/matcher/matcher.h" +#include "mongo/executor/network_interface_mock.h" +#include "mongo/logv2/log.h" + +namespace mongo { +namespace test { +namespace mock { + +MockNetwork::Matcher::Matcher(const BSONObj& matcherQuery) { + auto expCtx = make_intrusive<ExpressionContext>( + nullptr /* opCtx */, nullptr /* collator */, NamespaceString{"db.coll"} /* dummy nss */); + // Expression matcher doesn't have copy constructor, so wrap it in a shared_ptr for capture. + auto m = std::make_shared<mongo::Matcher>(matcherQuery, std::move(expCtx)); + _matcherFunc = [=](const BSONObj& request) { return m->matches(request); }; +} + +bool MockNetwork::_allExpectationsSatisfied() const { + return std::all_of(_expectations.begin(), _expectations.end(), [](const auto& exp) { + return exp->isDefault() || exp->isSatisfied(); + }); +} + +void MockNetwork::_runUntilIdle() { + executor::NetworkInterfaceMock::InNetworkGuard guard(_net); + do { + // The main responsibility of the mock network is to host incoming requests and scheduled + // responses. Additionally, the mock network interface is a de facto lock-step scheduler. + // + // The executor thread and the mock/test thread run in turn. The test thread + // (1) triggers the tested behavior, e.g. by simulating a command; + // (2) responds to network requests; + // (3) advances the mock clock; and + // (4) handles some network operations implicitly (explained below). + // The executor runs the asynchronous jobs which may schedule network requests. + // + // The executor thread gets the first turn, then each of them yields at the end of their + // turns by enabling and signaling the other. The executor thread yields by calling + // waitForWork() on the mock network; the test thread yields by calling + // runReadyNetworkOperations(). + // + // runReadyNetworkOperations() also first checks for expired scheduled works (e.g. request + // timeout) and executes the expired works. This behavior is the item (4) mentioned above. + // + // After yielding to the executor thread, it's possible that new expired scheduled works + // were added by the executor. That's why we need to double check if there's any ready + // network operations before deciding the network is idle. + // + // External threads may make things more complex. For example, they can schedule new + // requests right after we thought the network was idle. However, that's always the case + // with or without the mock framework. + _net->runReadyNetworkOperations(); + if (_net->hasReadyRequests()) { + // Peek the next request. + auto noi = _net->getFrontOfUnscheduledQueue(); + auto request = noi->getRequest().cmdObj; + + // We ignore the next request if it's not expected (or already satisfied). + // Default expectations are always the oldest in the vector, so matching expectations + // in LIFO order allows us to always see the overrides first. + // (Iterating a vector backwards is much cheaper than pushing to its front.) + auto const& exp = + std::find_if(_expectations.rbegin(), _expectations.rend(), [&](const auto& exp) { + return !exp->isSatisfied() && exp->match(request); + }); + + if (exp != _expectations.rend()) { + // Consume the next request and execute the action. + noi = _net->getNextReadyRequest(); + auto response = (*exp)->run(request); + LOGV2_DEBUG(5015401, + 1, + "mock reply ", + "request"_attr = request, + "response"_attr = response); + _net->scheduleResponse(noi, _net->now(), response); + + // Continue handling network operations and process requests. + continue; + } + } + + // The executor is idle since we just ran it. Check hasReadyNetworkOperations so that no + // scheduled work is waiting for the network thread. + } while (_net->hasReadyNetworkOperations()); +} + +void MockNetwork::runUntilExpectationsSatisfied() { + // If there exist extra threads beside the executor and the mock/test thread, when the + // network is idle, the extra threads may be running and will schedule new requests. As a + // result, the current best practice is to busy-loop to prepare for that. + while (!_allExpectationsSatisfied()) { + _runUntilIdle(); + } +} + +void MockNetwork::runUntil(Date_t target) { + while (_net->now() < target) { + LOGV2_DEBUG( + 5015402, 1, "mock advances time", "from"_attr = _net->now(), "to"_attr = target); + { + executor::NetworkInterfaceMock::InNetworkGuard guard(_net); + // Even if we cannot reach target time, we are still making progress in the loop. + _net->runUntil(target); + } + // Run until idle. + _runUntilIdle(); + } + LOGV2_DEBUG(5015403, 1, "mock reached time", "target"_attr = target); +} + +} // namespace mock +} // namespace test +} // namespace mongo diff --git a/src/mongo/executor/mock_network_fixture.h b/src/mongo/executor/mock_network_fixture.h new file mode 100644 index 00000000000..a2628042097 --- /dev/null +++ b/src/mongo/executor/mock_network_fixture.h @@ -0,0 +1,237 @@ +/** + * Copyright (C) 2020-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 <limits> + +#include "mongo/executor/network_interface_mock.h" +#include "mongo/stdx/thread.h" + +namespace mongo { + +class BSONObj; +using executor::RemoteCommandResponse; + +namespace test { +namespace mock { + +// MockNetwork wraps the NetworkInterfaceMock to provide a declarative approach +// to specify expected behaviors on the network and to hide the interaction with +// the NetworkInterfaceMock. +class MockNetwork { +public: + using MatcherFunc = std::function<bool(const BSONObj&)>; + using ActionFunc = std::function<RemoteCommandResponse(const BSONObj&)>; + + class Matcher { + public: + Matcher(const char* cmdName) : Matcher(std::string(cmdName)) {} + Matcher(const std::string& cmdName) { + _matcherFunc = [=](const BSONObj& request) { + return request.firstElementFieldNameStringData() == cmdName; + }; + } + + Matcher(const BSONObj& matcherQuery); + + Matcher(MatcherFunc matcherFunc) : _matcherFunc(std::move(matcherFunc)) {} + + bool operator()(const BSONObj& request) { + return _matcherFunc(request); + } + + private: + MatcherFunc _matcherFunc; + }; + + class Action { + public: + Action(ActionFunc func) : _actionFunc(std::move(func)){}; + + Action(const BSONObj& response) { + _actionFunc = [=](const BSONObj& request) { + return RemoteCommandResponse(response, Milliseconds(0)); + }; + } + + Action(const RemoteCommandResponse& commandResponse) { + _actionFunc = [=](const BSONObj& request) { return commandResponse; }; + } + + RemoteCommandResponse operator()(const BSONObj& request) { + return _actionFunc(request); + } + + private: + ActionFunc _actionFunc; + }; + + class Expectation { + public: + Expectation(Matcher matcher, Action action) + : _matcher(std::move(matcher)), _action(std::move(action)) {} + virtual ~Expectation() {} + + bool match(const BSONObj& request) { + return _matcher(request); + } + + RemoteCommandResponse run(const BSONObj& request) { + if (!isDefault()) { + _allowedTimes--; + } + return _action(request); + } + + virtual bool isDefault() const { + return _allowedTimes == std::numeric_limits<int>::max(); + } + + bool isSatisfied() const { + return _allowedTimes == 0; + } + + // May throw. + virtual void checkSatisfied() {} + + protected: + int _allowedTimes = std::numeric_limits<int>::max(); + + private: + Matcher _matcher; + Action _action; + }; + + class UserExpectation : public Expectation { + public: + UserExpectation(Matcher matcher, Action action) : Expectation(matcher, action) { + // Default value, may be overriden by calling times(). + _allowedTimes = 1; + } + + Expectation& times(int t) { + _allowedTimes = t; + return *this; + } + + bool isDefault() const override { + return false; + } + + void checkSatisfied() override { + uassert(5015501, "UserExpectation not satisfied", isSatisfied()); + } + }; + + class DefaultExpectation : public Expectation { + public: + DefaultExpectation(Matcher matcher, Action action) : Expectation(matcher, action) {} + + bool isDefault() const override { + return true; + } + }; + + explicit MockNetwork(executor::NetworkInterfaceMock* net) : _net(net) {} + + // Accept anything that Matcher's and Action's constructors allow. + // Use expect() to mandate the exact calls each test expects. They must all be satisfied + // or the test fails. + template <typename MatcherType> + UserExpectation& expect(MatcherType&& matcher, Action action) { + auto exp = std::make_unique<UserExpectation>(Matcher(std::forward<MatcherType>(matcher)), + std::move(action)); + auto& ref = *exp; + _expectations.emplace_back(std::move(exp)); + return ref; + } + + // Accept anything that Matcher's and Action's constructors allow. + // Use defaultExpect() to specify shared behavior in test fixtures. This is best for + // uninteresting calls common to a class of tests. + // For these reasons, you are not allowed to declare further default expecations after + // having already enqueued user expectations. + template <typename MatcherType> + DefaultExpectation& defaultExpect(MatcherType&& matcher, Action action) { + auto order = std::none_of(_expectations.begin(), _expectations.end(), [](const auto& exp) { + return !exp->isDefault(); + }); + uassert( + 5015502, "All default expectations must be declared before user expectations.", order); + + auto exp = std::make_unique<DefaultExpectation>(Matcher(std::forward<MatcherType>(matcher)), + std::move(action)); + auto& ref = *exp; + _expectations.emplace_back(std::move(exp)); + return ref; + } + + void verifyExpectations() { + for (auto& exp : _expectations) { + // This expectation will throw if it has not been met. + exp->checkSatisfied(); + } + } + + // Removes user expectations only. + void clearExpectations() { + _expectations.erase(std::remove_if(_expectations.begin(), + _expectations.end(), + [&](auto& exp) { return !exp->isDefault(); }), + _expectations.end()); + } + + // Carries over default expectations but clears user expectations. Checks that the latter + // have all been satisfied in the process. + void verifyAndClearExpectations() { + // May throw. + verifyExpectations(); + clearExpectations(); + } + + + // Advance time to the target. Run network operations and process requests along the way. + void runUntil(Date_t targetTime); + + // Run until both the executor and the network are idle and all expectations are satisfied. + // Otherwise, it hangs forever. + void runUntilExpectationsSatisfied(); + +private: + void _runUntilIdle(); + bool _allExpectationsSatisfied() const; + + std::vector<std::unique_ptr<Expectation>> _expectations; + executor::NetworkInterfaceMock* _net; +}; + +} // namespace mock +} // namespace test +} // namespace mongo diff --git a/src/mongo/executor/mock_network_fixture_test.cpp b/src/mongo/executor/mock_network_fixture_test.cpp new file mode 100644 index 00000000000..f97b4e7f6eb --- /dev/null +++ b/src/mongo/executor/mock_network_fixture_test.cpp @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2020-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. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kTest + +#include "mongo/platform/basic.h" + +#include "mongo/base/status.h" +#include "mongo/executor/mock_network_fixture.h" +#include "mongo/executor/network_interface.h" +#include "mongo/executor/network_interface_mock.h" +#include "mongo/executor/network_interface_mock_test_fixture.h" +#include "mongo/executor/thread_pool_mock.h" +#include "mongo/logv2/log.h" +#include "mongo/unittest/unittest.h" + +namespace mongo { +namespace { + +using namespace executor; +using namespace test::mock; + +class MockNetworkTest : public NetworkInterfaceMockTest { +public: + MockNetworkTest() : NetworkInterfaceMockTest(), _mock(&NetworkInterfaceMockTest::net()){}; + + MockNetwork& mock() { + return _mock; + } + + void setUp() override { + NetworkInterfaceMockTest::setUp(); + NetworkInterfaceMockTest::startNetwork(); + } + + void tearDown() override { + NetworkInterfaceMockTest::tearDown(); + // Will check for unsatisfied expectations. + mock().verifyAndClearExpectations(); + } + + void evaluateResponse(const RemoteCommandOnAnyResponse& resp, BSONObj expectedResponse) { + LOGV2(5015503, "Test got command response", "resp"_attr = resp); + ASSERT(resp.isOK()); + ASSERT(SimpleBSONObjComparator::kInstance.evaluate(expectedResponse == resp.data)); + } + + std::string kExampleCmdName = "someCommandName"; + RemoteCommandRequestOnAny kExampleRequest{ + {testHost()}, "testDB", BSON(kExampleCmdName << 1), rpc::makeEmptyMetadata(), nullptr}; + BSONObj kExampleResponse = BSON("some" + << "response"); + +private: + MockNetwork _mock; +}; + +TEST_F(MockNetworkTest, MockFixtureBasicTest) { + mock().expect(kExampleCmdName, kExampleResponse); + + RemoteCommandRequestOnAny request{kExampleRequest}; + bool commandFinished = false; + + TaskExecutor::CallbackHandle cb; + auto finishFn = [&](const RemoteCommandOnAnyResponse& resp) { + evaluateResponse(resp, kExampleResponse); + commandFinished = true; + }; + ASSERT_OK(net().startCommand(cb, request, finishFn)); + + mock().runUntilExpectationsSatisfied(); + ASSERT(commandFinished); +} + +} // namespace +} // namespace mongo
\ No newline at end of file diff --git a/src/mongo/executor/network_interface_mock_test.cpp b/src/mongo/executor/network_interface_mock_test.cpp index d0575679cdd..c3f419a391f 100644 --- a/src/mongo/executor/network_interface_mock_test.cpp +++ b/src/mongo/executor/network_interface_mock_test.cpp @@ -36,68 +36,13 @@ #include "mongo/base/status.h" #include "mongo/executor/network_connection_hook.h" #include "mongo/executor/network_interface.h" -#include "mongo/executor/network_interface_mock.h" +#include "mongo/executor/network_interface_mock_test_fixture.h" #include "mongo/executor/test_network_connection_hook.h" -#include "mongo/executor/thread_pool_mock.h" -#include "mongo/unittest/unittest.h" namespace mongo { namespace executor { namespace { -class NetworkInterfaceMockTest : public mongo::unittest::Test { -public: - NetworkInterfaceMockTest() - : _net{}, _executor(&_net, 1, ThreadPoolMock::Options()), _tearDownCalled(false) {} - - NetworkInterfaceMock& net() { - return _net; - } - - ThreadPoolMock& executor() { - return _executor; - } - - HostAndPort testHost() { - return {"localHost", 27017}; - } - - // intentionally not done in setUp as some methods need to be called prior to starting - // the network. - void startNetwork() { - net().startup(); - executor().startup(); - } - - virtual void setUp() override { - _tearDownCalled = false; - } - - virtual void tearDown() override { - // We're calling tearDown() manually in some tests so - // we can check post-conditions. - if (_tearDownCalled) { - return; - } - _tearDownCalled = true; - - net().exitNetwork(); - executor().shutdown(); - // Wake up sleeping executor threads so they clean up. - net().signalWorkAvailable(); - executor().join(); - net().shutdown(); - } - - RemoteCommandRequestOnAny kUnimportantRequest{ - {testHost()}, "testDB", BSON("test" << 1), rpc::makeEmptyMetadata(), nullptr}; - -private: - NetworkInterfaceMock _net; - ThreadPoolMock _executor; - bool _tearDownCalled; -}; - TEST_F(NetworkInterfaceMockTest, ConnectionHook) { bool validateCalled = false; bool hostCorrectForValidate = false; diff --git a/src/mongo/executor/network_interface_mock_test_fixture.cpp b/src/mongo/executor/network_interface_mock_test_fixture.cpp new file mode 100644 index 00000000000..0efae253dc8 --- /dev/null +++ b/src/mongo/executor/network_interface_mock_test_fixture.cpp @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2020-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. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/executor/network_interface_mock_test_fixture.h" + +namespace mongo { +namespace executor { + +// Intentionally not done in setUp in case there are methods that need to be called prior to +// starting the network. +void NetworkInterfaceMockTest::startNetwork() { + net().startup(); + executor().startup(); +} + +void NetworkInterfaceMockTest::setUp() { + _tearDownCalled = false; +} + +void NetworkInterfaceMockTest::tearDown() { + // We're calling tearDown() manually in some tests so + // we can check post-conditions. + if (_tearDownCalled) { + return; + } + _tearDownCalled = true; + + net().exitNetwork(); + executor().shutdown(); + // Wake up sleeping executor threads so they clean up. + net().signalWorkAvailable(); + executor().join(); + net().shutdown(); +} +} // namespace executor +} // namespace mongo
\ No newline at end of file diff --git a/src/mongo/executor/network_interface_mock_test_fixture.h b/src/mongo/executor/network_interface_mock_test_fixture.h new file mode 100644 index 00000000000..a19d2be80e4 --- /dev/null +++ b/src/mongo/executor/network_interface_mock_test_fixture.h @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2020-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/executor/network_interface_mock.h" +#include "mongo/executor/thread_pool_mock.h" +#include "mongo/unittest/unittest.h" + +namespace mongo { +namespace executor { + +class NetworkInterfaceMockTest : public mongo::unittest::Test { +public: + NetworkInterfaceMockTest() + : _net{}, _executor(&_net, 1, ThreadPoolMock::Options()), _tearDownCalled(false) {} + + NetworkInterfaceMock& net() { + return _net; + } + + ThreadPoolMock& executor() { + return _executor; + } + + HostAndPort testHost() { + return {"localHost", 27017}; + } + + void startNetwork(); + virtual void setUp() override; + virtual void tearDown() override; + + RemoteCommandRequestOnAny kUnimportantRequest{ + {testHost()}, "testDB", BSON("test" << 1), rpc::makeEmptyMetadata(), nullptr}; + +private: + NetworkInterfaceMock _net; + ThreadPoolMock _executor; + bool _tearDownCalled; +}; + +} // namespace executor +} // namespace mongo
\ No newline at end of file |