memgraph/tests/concurrent/network_read_hang.cpp
Matej Ferencevic fc20ddcd25 RPC refactor
Summary:
Start removal of old logic
Remove more obsolete classes
Move Message class to RPC
Remove client logic from system
Remove messaging namespace
Move protocol from messaging to rpc
Move System from messaging to rpc
Remove unnecessary namespace
Remove System from RPC Client
Split Client and Server into separate files
Start implementing new client logic
First semi-working state
Changed network protocol layout
Rewrite client
Fix client receive bug
Cleanup code of debug lines
Migrate to accessors
Migrate back to binary boost archives
Remove debug logging from server
Disable timeout test
Reduce message_id from uint64_t to uint32_t
Add multiple workers to server
Fix compiler warnings
Apply clang-format

Reviewers: teon.banek, florijan, dgleich, buda, mtomic

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1129
2018-01-24 15:27:40 +01:00

110 lines
2.8 KiB
C++

#ifndef NDEBUG
#define NDEBUG
#endif
#include <array>
#include <chrono>
#include <cstring>
#include <iostream>
#include <thread>
#include <vector>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include "communication/bolt/v1/decoder/buffer.hpp"
#include "communication/server.hpp"
#include "database/graph_db_accessor.hpp"
#include "io/network/epoll.hpp"
#include "io/network/socket.hpp"
static constexpr const char interface[] = "127.0.0.1";
using io::network::Endpoint;
using io::network::Socket;
class TestData {};
class TestSession {
public:
TestSession(Socket &&socket, TestData &) : socket_(std::move(socket)) {
event_.data.ptr = this;
}
bool Alive() const { return socket_.IsOpen(); }
bool TimedOut() const { return false; }
int Id() const { return socket_.fd(); }
void Execute() { this->socket_.Write(buffer_.data(), buffer_.size()); }
io::network::StreamBuffer Allocate() { return buffer_.Allocate(); }
void Written(size_t len) { buffer_.Written(len); }
void Close() { this->socket_.Close(); }
Socket &socket() { return socket_; }
void RefreshLastEventTime(
const std::chrono::time_point<std::chrono::steady_clock>
&last_event_time) {
last_event_time_ = last_event_time;
}
Socket socket_;
communication::bolt::Buffer<> buffer_;
io::network::Epoll::Event event_;
std::chrono::time_point<std::chrono::steady_clock> last_event_time_;
};
std::atomic<bool> run{true};
void client_run(int num, const char *interface, uint16_t port) {
Endpoint endpoint(interface, port);
Socket socket;
uint8_t data = 0x00;
ASSERT_TRUE(socket.Connect(endpoint));
socket.SetTimeout(1, 0);
// set socket timeout to 1s
ASSERT_TRUE(socket.Write((uint8_t *)"\xAA", 1));
ASSERT_TRUE(socket.Read(&data, 1));
fprintf(stderr, "CLIENT %d READ 0x%02X!\n", num, data);
ASSERT_EQ(data, 0xAA);
while (run) std::this_thread::sleep_for(std::chrono::milliseconds(100));
socket.Close();
}
TEST(Network, SocketReadHangOnConcurrentConnections) {
// initialize listen socket
Endpoint endpoint(interface, 0);
std::cout << endpoint << std::endl;
// initialize server
TestData data;
int N = (std::thread::hardware_concurrency() + 1) / 2;
int Nc = N * 3;
communication::Server<TestSession, TestData> server(endpoint, data, N);
const auto &ep = server.endpoint();
// start clients
std::vector<std::thread> clients;
for (int i = 0; i < Nc; ++i)
clients.push_back(std::thread(client_run, i, interface, ep.port()));
// wait for 2s and stop clients
std::this_thread::sleep_for(std::chrono::seconds(2));
run = false;
// cleanup clients
for (int i = 0; i < Nc; ++i) clients[i].join();
}
int main(int argc, char **argv) {
google::InitGoogleLogging(argv[0]);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}