summaryrefslogtreecommitdiff
path: root/src/mongo/executor/network_interface_asio_integration_test.cpp
diff options
context:
space:
mode:
authorAdam Midvidy <amidvidy@gmail.com>2015-09-17 16:15:45 -0400
committerAdam Midvidy <amidvidy@gmail.com>2015-09-18 11:16:23 -0400
commit3d28184925872318f66c88a4c74abad690ceba88 (patch)
treeee8d9960fe08e9588eaa3b40b2de0628fec801e4 /src/mongo/executor/network_interface_asio_integration_test.cpp
parent12aec7d9637e35749c70b544b8b4173158f17337 (diff)
downloadmongo-3d28184925872318f66c88a4c74abad690ceba88.tar.gz
SERVER-20457 add integration test for NetworkInterfaceASIO timeouts
Diffstat (limited to 'src/mongo/executor/network_interface_asio_integration_test.cpp')
-rw-r--r--src/mongo/executor/network_interface_asio_integration_test.cpp142
1 files changed, 119 insertions, 23 deletions
diff --git a/src/mongo/executor/network_interface_asio_integration_test.cpp b/src/mongo/executor/network_interface_asio_integration_test.cpp
index 92c7731d619..b2b7ecae6ce 100644
--- a/src/mongo/executor/network_interface_asio_integration_test.cpp
+++ b/src/mongo/executor/network_interface_asio_integration_test.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kExecutor
+
#include "mongo/platform/basic.h"
#include <exception>
@@ -42,42 +44,136 @@
#include "mongo/unittest/integration_test.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/assert_util.h"
+#include "mongo/util/log.h"
#include "mongo/util/scopeguard.h"
namespace mongo {
namespace executor {
namespace {
-TEST(NetworkInterfaceASIO, TestPing) {
- auto fixture = unittest::getFixtureConnectionString();
+class NetworkInterfaceASIOIntegrationTest : public mongo::unittest::Test {
+public:
+ void setUp() override {
+ NetworkInterfaceASIO::Options options{};
+ options.streamFactory = stdx::make_unique<AsyncStreamFactory>();
+ options.timerFactory = stdx::make_unique<AsyncTimerFactoryASIO>();
+ _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();
+ }
+
+ StatusWith<RemoteCommandResponse> runCommand(const RemoteCommandRequest& request) {
+ TaskExecutor::CallbackHandle cb{};
+ stdx::promise<RemoteCommandResponse> result;
- NetworkInterfaceASIO::Options options{};
- options.streamFactory = stdx::make_unique<AsyncStreamFactory>();
- options.timerFactory = stdx::make_unique<AsyncTimerFactoryASIO>();
- NetworkInterfaceASIO net{std::move(options)};
+ log() << "running command: " << request.toString();
- net.startup();
- auto guard = MakeGuard([&] { net.shutdown(); });
+ net().startCommand(cb,
+ request,
+ [&result](StatusWith<RemoteCommandResponse> resp) {
+ try {
+ result.set_value(uassertStatusOK(resp));
+ } catch (...) {
+ result.set_exception(std::current_exception());
+ }
+ });
+ try {
+ // We can't construct a stdx::promise<StatusWith<RemoteCommandResponse>> because
+ // StatusWith is not default constructible. So we do the status -> exception -> status
+ // dance instead.
+ auto res = result.get_future().get();
+ log() << "got command result: " << res.toString();
+ return res;
+ } catch (...) {
+ auto status = exceptionToStatus();
+ log() << "command failed with status: " << status;
+ return status;
+ }
+ }
- TaskExecutor::CallbackHandle cb{};
+ void assertCommandOK(StringData db,
+ const BSONObj& cmd,
+ Milliseconds timeoutMillis = Milliseconds(-1)) {
+ auto res = unittest::assertGet(
+ runCommand({fixture().getServers()[0], db.toString(), cmd, BSONObj(), timeoutMillis}));
+ ASSERT_OK(getStatusFromCommandResult(res.data));
+ }
+
+ void assertCommandFailsOnClient(StringData db,
+ const BSONObj& cmd,
+ Milliseconds timeoutMillis,
+ ErrorCodes::Error reason) {
+ auto clientStatus =
+ runCommand({fixture().getServers()[0], db.toString(), cmd, BSONObj(), timeoutMillis});
+ ASSERT_TRUE(clientStatus == reason);
+ }
+
+ void assertCommandFailsOnServer(StringData db,
+ const BSONObj& cmd,
+ Milliseconds timeoutMillis,
+ ErrorCodes::Error reason) {
+ auto res = unittest::assertGet(
+ runCommand({fixture().getServers()[0], db.toString(), cmd, BSONObj(), timeoutMillis}));
+ auto serverStatus = getStatusFromCommandResult(res.data);
+ ASSERT_TRUE(serverStatus == reason);
+ }
+
+private:
+ std::unique_ptr<NetworkInterfaceASIO> _net;
+};
+
+TEST_F(NetworkInterfaceASIOIntegrationTest, Ping) {
+ assertCommandOK("admin", BSON("ping" << 1));
+}
- stdx::promise<RemoteCommandResponse> result;
+TEST_F(NetworkInterfaceASIOIntegrationTest, Timeouts) {
+ // Insert 1 document in collection foo.bar. If we don't do this our queries will return
+ // immediately.
+ assertCommandOK("foo",
+ BSON("insert"
+ << "bar"
+ << "documents" << BSON_ARRAY(BSON("foo" << 1))));
- net.startCommand(
- cb,
- RemoteCommandRequest{fixture.getServers()[0], "admin", BSON("ping" << 1), BSONObj()},
- [&result](StatusWith<RemoteCommandResponse> resp) {
- try {
- result.set_value(uassertStatusOK(resp));
- } catch (...) {
- result.set_exception(std::current_exception());
- }
- });
+ // Run a find command with a $where with an infinite loop. The remote server should time this
+ // out in 30 seconds, so we should time out client side first given our timeout of 100
+ // milliseconds.
+ assertCommandFailsOnClient("foo",
+ BSON("find"
+ << "bar"
+ << "filter" << BSON("$where"
+ << "while(true) { sleep(1); }")),
+ Milliseconds(100),
+ ErrorCodes::ExceededTimeLimit);
- auto fut = result.get_future();
- auto commandReply = fut.get();
+ // Run a find command with a $where with an infinite loop. The server should time out the
+ // command.
+ assertCommandFailsOnServer("foo",
+ BSON("find"
+ << "bar"
+ << "filter" << BSON("$where"
+ << "while(true) { sleep(1); };")),
+ Milliseconds(10000000000), // big, big timeout.
+ ErrorCodes::JSInterpreterFailure);
- ASSERT_OK(getStatusFromCommandResult(commandReply.data));
+ // Run a find command with a big timeout. It should return before we hit the ASIO timeout.
+ assertCommandOK("foo",
+ BSON("find"
+ << "bar"
+ << "limit" << 1),
+ Milliseconds(10000000));
}
} // namespace