memgraph/tests/unit/network_timeouts.cpp
Matej Ferencevic 017e8004e8 Refactor network stack
Summary:
Previously, the network stack `communication::Server` accepted connections and
assigned them statically in a round-robin fashion to `communication::Worker`.
That meant that if two compute intensive connections were assigned to the same
worker they would block each other while the other workers would do nothing.

This implementation replaces `communication::Worker` with
`communication::Listener` which holds all accepted connections in one pool and
ensures that all workers execute all connections.

Reviewers: buda, florijan, teon.banek

Reviewed By: buda

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1220
2018-02-22 16:29:17 +01:00

100 lines
2.7 KiB
C++

#include <chrono>
#include <experimental/filesystem>
#include <iostream>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include "gtest/gtest.h"
#include "communication/bolt/client.hpp"
#include "communication/bolt/v1/session.hpp"
#include "communication/server.hpp"
#include "io/network/endpoint.hpp"
#include "io/network/socket.hpp"
DECLARE_int32(query_execution_time_sec);
DECLARE_int32(session_inactivity_timeout);
using namespace std::chrono_literals;
class TestClientSocket;
using communication::bolt::ClientException;
using communication::bolt::SessionData;
using io::network::Endpoint;
using io::network::Socket;
using SessionT = communication::bolt::Session<Socket>;
using ResultStreamT = SessionT::ResultStreamT;
using ServerT = communication::Server<SessionT, SessionData>;
using ClientT = communication::bolt::Client<Socket>;
class RunningServer {
public:
database::SingleNode db_;
SessionData session_data_{db_};
Endpoint endpoint_{"127.0.0.1", 0};
ServerT server_{endpoint_, session_data_, true, 1};
};
class TestClient : public ClientT {
public:
TestClient(Endpoint endpoint)
: ClientT(
[&] {
Socket socket;
socket.Connect(endpoint);
return socket;
}(),
"", "") {}
};
TEST(NetworkTimeouts, InactiveSession) {
FLAGS_query_execution_time_sec = 60;
FLAGS_session_inactivity_timeout = 2;
RunningServer rs;
TestClient client(rs.server_.endpoint());
// Check that we can execute first query.
client.Execute("RETURN 1", {});
// After sleep, session should still be alive.
std::this_thread::sleep_for(500ms);
client.Execute("RETURN 1", {});
// After sleep, session should still be alive.
std::this_thread::sleep_for(500ms);
client.Execute("RETURN 1", {});
// After sleep, session should still be alive.
std::this_thread::sleep_for(500ms);
client.Execute("RETURN 1", {});
// After sleep, session should have timed out.
std::this_thread::sleep_for(3500ms);
EXPECT_THROW(client.Execute("RETURN 1", {}), ClientException);
}
TEST(NetworkTimeouts, TimeoutInMultiCommandTransaction) {
FLAGS_query_execution_time_sec = 2;
FLAGS_session_inactivity_timeout = 60;
RunningServer rs;
TestClient client(rs.server_.endpoint());
// Start explicit multicommand transaction.
client.Execute("BEGIN", {});
client.Execute("RETURN 1", {});
// Session should still be alive.
std::this_thread::sleep_for(500ms);
client.Execute("RETURN 1", {});
// Session shouldn't be alive anymore.
std::this_thread::sleep_for(4s);
EXPECT_THROW(client.Execute("RETURN 1", {}), ClientException);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
google::InitGoogleLogging(argv[0]);
return RUN_ALL_TESTS();
}