summaryrefslogtreecommitdiff
path: root/src/mongo/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/executor')
-rw-r--r--src/mongo/executor/SConscript20
-rw-r--r--src/mongo/executor/network_interface_asio_integration_fixture.cpp142
-rw-r--r--src/mongo/executor/network_interface_asio_integration_fixture.h87
-rw-r--r--src/mongo/executor/network_interface_asio_integration_test.cpp131
-rw-r--r--src/mongo/executor/network_interface_asio_test_utils.h1
5 files changed, 257 insertions, 124 deletions
diff --git a/src/mongo/executor/SConscript b/src/mongo/executor/SConscript
index 7b2707464d2..de73d0ba464 100644
--- a/src/mongo/executor/SConscript
+++ b/src/mongo/executor/SConscript
@@ -200,20 +200,30 @@ env.CppUnitTest(
'$BUILD_DIR/mongo/util/version_impl',
],
)
-
-env.CppIntegrationTest(
- target='network_interface_asio_integration_test',
+env.Library(
+ target='network_interface_asio_fixture',
source=[
- 'network_interface_asio_integration_test.cpp',
+ 'network_interface_asio_integration_fixture.cpp'
],
LIBDEPS=[
+ 'network_interface_asio',
+ '$BUILD_DIR/mongo/unittest/integration_test_main',
'$BUILD_DIR/mongo/executor/thread_pool_task_executor',
'$BUILD_DIR/mongo/executor/network_interface_thread_pool',
'$BUILD_DIR/mongo/executor/network_interface_factory',
'$BUILD_DIR/mongo/rpc/command_status',
'$BUILD_DIR/mongo/util/concurrency/thread_pool',
'$BUILD_DIR/mongo/util/version_impl',
- 'network_interface_asio',
+ ]
+)
+
+env.CppIntegrationTest(
+ target='network_interface_asio_integration_test',
+ source=[
+ 'network_interface_asio_integration_test.cpp',
+ ],
+ LIBDEPS=[
+ 'network_interface_asio_fixture',
],
)
diff --git a/src/mongo/executor/network_interface_asio_integration_fixture.cpp b/src/mongo/executor/network_interface_asio_integration_fixture.cpp
new file mode 100644
index 00000000000..388de25f543
--- /dev/null
+++ b/src/mongo/executor/network_interface_asio_integration_fixture.cpp
@@ -0,0 +1,142 @@
+/**
+ * Copyright (C) 2017 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::kASIO
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/client/connection_string.h"
+#include "mongo/executor/async_stream_factory.h"
+#include "mongo/executor/async_stream_interface.h"
+#include "mongo/executor/async_timer_asio.h"
+#include "mongo/executor/network_interface_asio.h"
+#include "mongo/executor/network_interface_asio_integration_fixture.h"
+#include "mongo/executor/remote_command_response.h"
+#include "mongo/executor/task_executor.h"
+#include "mongo/rpc/get_status_from_command_result.h"
+#include "mongo/stdx/future.h"
+#include "mongo/stdx/memory.h"
+#include "mongo/unittest/integration_test.h"
+#include "mongo/util/assert_util.h"
+#include "mongo/util/log.h"
+
+namespace mongo {
+namespace executor {
+void NetworkInterfaceASIOIntegrationFixture::startNet(NetworkInterfaceASIO::Options options) {
+ options.streamFactory = stdx::make_unique<AsyncStreamFactory>();
+ options.timerFactory = stdx::make_unique<AsyncTimerFactoryASIO>();
+#ifdef _WIN32
+ // Connections won't queue on widnows, so attempting to open too many connections
+ // concurrently will result in refused connections and test failure.
+ options.connectionPoolOptions.maxConnections = 16u;
+#else
+ options.connectionPoolOptions.maxConnections = 256u;
+#endif
+ _net = stdx::make_unique<NetworkInterfaceASIO>(std::move(options));
+ _net->startup();
+}
+
+void NetworkInterfaceASIOIntegrationFixture::tearDown() {
+ if (!_net->inShutdown()) {
+ _net->shutdown();
+ }
+}
+
+NetworkInterfaceASIO& NetworkInterfaceASIOIntegrationFixture::net() {
+ return *_net;
+}
+
+ConnectionString NetworkInterfaceASIOIntegrationFixture::fixture() {
+ return unittest::getFixtureConnectionString();
+}
+
+void NetworkInterfaceASIOIntegrationFixture::setRandomNumberGenerator(PseudoRandom* generator) {
+ _rng = generator;
+}
+
+PseudoRandom* NetworkInterfaceASIOIntegrationFixture::getRandomNumberGenerator() {
+ return _rng;
+}
+
+void NetworkInterfaceASIOIntegrationFixture::startCommand(
+ const TaskExecutor::CallbackHandle& cbHandle,
+ RemoteCommandRequest& request,
+ StartCommandCB onFinish) {
+ net().startCommand(cbHandle, request, onFinish);
+}
+
+Deferred<RemoteCommandResponse> NetworkInterfaceASIOIntegrationFixture::runCommand(
+ const TaskExecutor::CallbackHandle& cbHandle, RemoteCommandRequest& request) {
+ Deferred<RemoteCommandResponse> deferred;
+ net().startCommand(cbHandle, request, [deferred](RemoteCommandResponse resp) mutable {
+ deferred.emplace(std::move(resp));
+ });
+ return deferred;
+}
+
+RemoteCommandResponse NetworkInterfaceASIOIntegrationFixture::runCommandSync(
+ RemoteCommandRequest& request) {
+ auto deferred = runCommand(makeCallbackHandle(), request);
+ auto& res = deferred.get();
+ if (res.isOK()) {
+ log() << "got command result: " << res.toString();
+ } else {
+ log() << "command failed: " << res.status;
+ }
+ return res;
+}
+
+void NetworkInterfaceASIOIntegrationFixture::assertCommandOK(StringData db,
+ const BSONObj& cmd,
+ Milliseconds timeoutMillis) {
+ RemoteCommandRequest request{
+ fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis};
+ auto res = runCommandSync(request);
+ ASSERT_OK(res.status);
+ ASSERT_OK(getStatusFromCommandResult(res.data));
+}
+
+void NetworkInterfaceASIOIntegrationFixture::assertCommandFailsOnClient(
+ StringData db, const BSONObj& cmd, ErrorCodes::Error reason, Milliseconds timeoutMillis) {
+ RemoteCommandRequest request{
+ fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis};
+ auto res = runCommandSync(request);
+ ASSERT_EQ(reason, res.status.code());
+}
+
+void NetworkInterfaceASIOIntegrationFixture::assertCommandFailsOnServer(
+ StringData db, const BSONObj& cmd, ErrorCodes::Error reason, Milliseconds timeoutMillis) {
+ RemoteCommandRequest request{
+ fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis};
+ auto res = runCommandSync(request);
+ ASSERT_OK(res.status);
+ auto serverStatus = getStatusFromCommandResult(res.data);
+ ASSERT_EQ(reason, serverStatus);
+}
+}
+}
diff --git a/src/mongo/executor/network_interface_asio_integration_fixture.h b/src/mongo/executor/network_interface_asio_integration_fixture.h
new file mode 100644
index 00000000000..3e62932b153
--- /dev/null
+++ b/src/mongo/executor/network_interface_asio_integration_fixture.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (C) 2017 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/unittest/unittest.h"
+
+#include "mongo/executor/network_interface_asio.h"
+#include "mongo/executor/network_interface_asio_test_utils.h"
+#include "mongo/executor/task_executor.h"
+
+namespace mongo {
+
+class PseudoRandom;
+
+namespace executor {
+
+using StartCommandCB = stdx::function<void(const RemoteCommandResponse&)>;
+
+class NetworkInterfaceASIOIntegrationFixture : public mongo::unittest::Test {
+public:
+ void startNet(NetworkInterfaceASIO::Options options = NetworkInterfaceASIO::Options());
+ void tearDown() override;
+
+ NetworkInterfaceASIO& net();
+
+ ConnectionString fixture();
+
+ void setRandomNumberGenerator(PseudoRandom* generator);
+
+ PseudoRandom* getRandomNumberGenerator();
+
+ void startCommand(const TaskExecutor::CallbackHandle& cbHandle,
+ RemoteCommandRequest& request,
+ StartCommandCB onFinish);
+
+ Deferred<RemoteCommandResponse> runCommand(const TaskExecutor::CallbackHandle& cbHandle,
+ RemoteCommandRequest& request);
+
+ RemoteCommandResponse runCommandSync(RemoteCommandRequest& request);
+
+ void assertCommandOK(StringData db,
+ const BSONObj& cmd,
+ Milliseconds timeoutMillis = Minutes(5));
+ void assertCommandFailsOnClient(StringData db,
+ const BSONObj& cmd,
+ ErrorCodes::Error reason,
+ Milliseconds timeoutMillis = Minutes(5));
+
+ void assertCommandFailsOnServer(StringData db,
+ const BSONObj& cmd,
+ ErrorCodes::Error reason,
+ Milliseconds timeoutMillis = Minutes(5));
+
+private:
+ std::unique_ptr<NetworkInterfaceASIO> _net;
+ PseudoRandom* _rng = nullptr;
+};
+
+} // namespace executor
+} // namespace mongo
diff --git a/src/mongo/executor/network_interface_asio_integration_test.cpp b/src/mongo/executor/network_interface_asio_integration_test.cpp
index 654d5c60687..39282fb7fcd 100644
--- a/src/mongo/executor/network_interface_asio_integration_test.cpp
+++ b/src/mongo/executor/network_interface_asio_integration_test.cpp
@@ -34,12 +34,8 @@
#include <exception>
#include "mongo/client/connection_string.h"
-#include "mongo/executor/async_stream_factory.h"
-#include "mongo/executor/async_stream_interface.h"
-#include "mongo/executor/async_timer_asio.h"
-#include "mongo/executor/network_interface_asio.h"
+#include "mongo/executor/network_interface_asio_integration_fixture.h"
#include "mongo/executor/network_interface_asio_test_utils.h"
-#include "mongo/executor/task_executor.h"
#include "mongo/platform/random.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/stdx/future.h"
@@ -55,115 +51,12 @@ namespace mongo {
namespace executor {
namespace {
-using StartCommandCB = stdx::function<void(const RemoteCommandResponse&)>;
-
-class NetworkInterfaceASIOIntegrationTest : public mongo::unittest::Test {
-public:
- void startNet(NetworkInterfaceASIO::Options options = NetworkInterfaceASIO::Options()) {
- options.streamFactory = stdx::make_unique<AsyncStreamFactory>();
- options.timerFactory = stdx::make_unique<AsyncTimerFactoryASIO>();
-#ifdef _WIN32
- // Connections won't queue on windows, so attempting to open too many connections
- // concurrently will result in refused connections and test failure.
- options.connectionPoolOptions.maxConnections = 16u;
-#else
- options.connectionPoolOptions.maxConnections = 256u;
-#endif
- _net = stdx::make_unique<NetworkInterfaceASIO>(std::move(options));
- _net->startup();
- }
-
- void tearDown() override {
- if (!_net->inShutdown()) {
- _net->shutdown();
- }
- }
-
- NetworkInterfaceASIO& net() {
- return *_net;
- }
-
- ConnectionString fixture() {
- return unittest::getFixtureConnectionString();
- }
-
- void randomNumberGenerator(PseudoRandom* generator) {
- _rng = generator;
- }
-
- PseudoRandom* randomNumberGenerator() {
- return _rng;
- }
-
- void startCommand(const TaskExecutor::CallbackHandle& cbHandle,
- RemoteCommandRequest& request,
- StartCommandCB onFinish) {
- net().startCommand(cbHandle, request, onFinish);
- }
-
- Deferred<RemoteCommandResponse> runCommand(const TaskExecutor::CallbackHandle& cbHandle,
- RemoteCommandRequest& request) {
- Deferred<RemoteCommandResponse> deferred;
- net().startCommand(cbHandle, request, [deferred](RemoteCommandResponse resp) mutable {
- deferred.emplace(std::move(resp));
- });
- return deferred;
- }
-
- RemoteCommandResponse runCommandSync(RemoteCommandRequest& request) {
- auto deferred = runCommand(makeCallbackHandle(), request);
- auto& res = deferred.get();
- if (res.isOK()) {
- log() << "got command result: " << res.toString();
- } else {
- log() << "command failed: " << res.status;
- }
- return res;
- }
-
- void assertCommandOK(StringData db,
- const BSONObj& cmd,
- Milliseconds timeoutMillis = Milliseconds(-1)) {
- RemoteCommandRequest request{
- fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis};
- auto res = runCommandSync(request);
- ASSERT_OK(res.status);
- ASSERT_OK(getStatusFromCommandResult(res.data));
- }
-
- void assertCommandFailsOnClient(StringData db,
- const BSONObj& cmd,
- Milliseconds timeoutMillis,
- ErrorCodes::Error reason) {
- RemoteCommandRequest request{
- fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis};
- auto res = runCommandSync(request);
- ASSERT_EQ(reason, res.status.code());
- }
-
- void assertCommandFailsOnServer(StringData db,
- const BSONObj& cmd,
- Milliseconds timeoutMillis,
- ErrorCodes::Error reason) {
- RemoteCommandRequest request{
- fixture().getServers()[0], db.toString(), cmd, BSONObj(), nullptr, timeoutMillis};
- auto res = runCommandSync(request);
- ASSERT_OK(res.status);
- auto serverStatus = getStatusFromCommandResult(res.data);
- ASSERT_EQ(reason, serverStatus);
- }
-
-private:
- std::unique_ptr<NetworkInterfaceASIO> _net;
- PseudoRandom* _rng = nullptr;
-};
-
-TEST_F(NetworkInterfaceASIOIntegrationTest, Ping) {
+TEST_F(NetworkInterfaceASIOIntegrationFixture, Ping) {
startNet();
assertCommandOK("admin", BSON("ping" << 1));
}
-TEST_F(NetworkInterfaceASIOIntegrationTest, Timeouts) {
+TEST_F(NetworkInterfaceASIOIntegrationFixture, Timeouts) {
startNet();
// This sleep command will take 10 seconds, so we should time out client side first given
// our timeout of 100 milliseconds.
@@ -172,8 +65,8 @@ TEST_F(NetworkInterfaceASIOIntegrationTest, Timeouts) {
<< "none"
<< "secs"
<< 10),
- Milliseconds(100),
- ErrorCodes::ExceededTimeLimit);
+ ErrorCodes::ExceededTimeLimit,
+ Milliseconds(100));
// Run a sleep command that should return before we hit the ASIO timeout.
assertCommandOK("admin",
@@ -186,7 +79,7 @@ TEST_F(NetworkInterfaceASIOIntegrationTest, Timeouts) {
class StressTestOp {
public:
- using Fixture = NetworkInterfaceASIOIntegrationTest;
+ using Fixture = NetworkInterfaceASIOIntegrationFixture;
using Pool = ThreadPoolInterface;
void run(Fixture* fixture,
@@ -203,8 +96,8 @@ public:
fixture->startCommand(cb, request, onFinish);
if (_cancel) {
- invariant(fixture->randomNumberGenerator());
- sleepmillis(fixture->randomNumberGenerator()->nextInt32(10));
+ invariant(fixture->getRandomNumberGenerator());
+ sleepmillis(fixture->getRandomNumberGenerator()->nextInt32(10));
fixture->net().cancelCommand(cb);
}
}
@@ -252,7 +145,7 @@ private:
bool _cancel;
};
-TEST_F(NetworkInterfaceASIOIntegrationTest, StressTest) {
+TEST_F(NetworkInterfaceASIOIntegrationFixture, StressTest) {
constexpr std::size_t numOps = 500;
RemoteCommandResponse testResults[numOps];
ErrorCodes::Error expectedResults[numOps];
@@ -265,7 +158,7 @@ TEST_F(NetworkInterfaceASIOIntegrationTest, StressTest) {
log() << "Random seed is " << seed;
auto rng = PseudoRandom(seed); // TODO: read from command line
- randomNumberGenerator(&rng);
+ setRandomNumberGenerator(&rng);
log() << "Starting stress test...";
for (std::size_t i = 0; i < numOps; ++i) {
@@ -329,13 +222,13 @@ class HangingHook : public executor::NetworkConnectionHook {
// Test that we time out a command if the connection hook hangs.
-TEST_F(NetworkInterfaceASIOIntegrationTest, HookHangs) {
+TEST_F(NetworkInterfaceASIOIntegrationFixture, HookHangs) {
NetworkInterfaceASIO::Options options;
options.networkConnectionHook = stdx::make_unique<HangingHook>();
startNet(std::move(options));
assertCommandFailsOnClient(
- "admin", BSON("ping" << 1), Seconds(1), ErrorCodes::ExceededTimeLimit);
+ "admin", BSON("ping" << 1), ErrorCodes::ExceededTimeLimit, Seconds(1));
}
} // namespace
diff --git a/src/mongo/executor/network_interface_asio_test_utils.h b/src/mongo/executor/network_interface_asio_test_utils.h
index b65d7eaa11e..54424735b9b 100644
--- a/src/mongo/executor/network_interface_asio_test_utils.h
+++ b/src/mongo/executor/network_interface_asio_test_utils.h
@@ -25,6 +25,7 @@
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
+#pragma once
#include <memory>