diff --git a/producer/api/CMakeLists.txt b/producer/api/CMakeLists.txt index 610dcba3d1c773d214ced99477b0cc4ca9303d8d..55d2aac8667286031b004546bbb2b481adc2dce7 100644 --- a/producer/api/CMakeLists.txt +++ b/producer/api/CMakeLists.txt @@ -5,9 +5,8 @@ set(SOURCE_FILES src/producer_logger.cpp src/request_handler_tcp.cpp src/request_pool.cpp src/receiver_discovery_service.cpp - src/request_handler.cpp src/request_handler_factory.cpp - src/request.cpp src/request.h unittests/mocking.h) + src/request.cpp) ################################ diff --git a/producer/api/src/producer_impl.cpp b/producer/api/src/producer_impl.cpp index b89fbafd4caba8ca13ecf46c7b47fe2acc1af36e..c24fa2ec693bdeeaa82ba66817cf46d19894f40d 100644 --- a/producer/api/src/producer_impl.cpp +++ b/producer/api/src/producer_impl.cpp @@ -8,14 +8,13 @@ namespace asapo { const size_t ProducerImpl::kMaxChunkSize = size_t(1024) * size_t(1024) * size_t(1024) * size_t(2); //2GiByte -const size_t ProducerImpl::kMaxPoolVolume = size_t(1024) * size_t(1024) * size_t(1024) * size_t(2); //2GiByte const size_t ProducerImpl::kDiscoveryServiceUpdateFrequencyMs = 10000; // 10s ProducerImpl::ProducerImpl(std::string endpoint, uint8_t n_processing_threads): log__{GetDefaultProducerLogger()} { discovery_service_.reset(new ReceiverDiscoveryService{endpoint, ProducerImpl::kDiscoveryServiceUpdateFrequencyMs}); request_handler_factory_.reset(new RequestHandlerFactory{RequestHandlerType::kTcp,discovery_service_.get()}); - request_pool__.reset(new RequestPool{n_processing_threads, ProducerImpl::kMaxPoolVolume, request_handler_factory_.get()}); + request_pool__.reset(new RequestPool{n_processing_threads, request_handler_factory_.get()}); } GenericNetworkRequestHeader ProducerImpl::GenerateNextSendRequest(uint64_t file_id, size_t file_size) { diff --git a/producer/api/src/producer_impl.h b/producer/api/src/producer_impl.h index f5c60c3fb22edfe55f4d3612e635e711999f69c8..7c48dc2f7813e328aa23b03bb06520d2fb1bf776 100644 --- a/producer/api/src/producer_impl.h +++ b/producer/api/src/producer_impl.h @@ -19,7 +19,6 @@ class ProducerImpl : public Producer { std::unique_ptr<RequestHandlerFactory> request_handler_factory_; public: static const size_t kMaxChunkSize; - static const size_t kMaxPoolVolume; static const size_t kDiscoveryServiceUpdateFrequencyMs; explicit ProducerImpl(std::string endpoint, uint8_t n_processing_threads); diff --git a/producer/api/src/request.h b/producer/api/src/request.h index e3d14316fe76b029b834dbe18c51323e1a50c0dc..0e9e29b27198864e47df4202d455d302e992e7ff 100644 --- a/producer/api/src/request.h +++ b/producer/api/src/request.h @@ -10,10 +10,6 @@ struct Request { GenericNetworkRequestHeader header; const void* data; RequestCallback callback; - uint64_t GetMemoryRequitements() { - return header.data_size + sizeof(Request); - } - }; } diff --git a/producer/api/src/request_handler.cpp b/producer/api/src/request_handler.cpp deleted file mode 100644 index 5e54c4d31071ca8c854005a52ef120ac0d2a304a..0000000000000000000000000000000000000000 --- a/producer/api/src/request_handler.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "request_handler.h" - - -namespace asapo { - - - -} diff --git a/producer/api/src/request_handler_tcp.cpp b/producer/api/src/request_handler_tcp.cpp index daf29846414443e9cca647ce7e2b1389a4eebaf8..3f7faa34da920113daed52c27e70c513210ea00f 100644 --- a/producer/api/src/request_handler_tcp.cpp +++ b/producer/api/src/request_handler_tcp.cpp @@ -75,12 +75,12 @@ Error RequestHandlerTcp::TrySendToReceiver(const Request* request,const std::str } -void RequestHandlerTcp::UpdateIfNewConnection() { +void RequestHandlerTcp::UpdateReceiversUriIfNewConnection() { if (sd_ != kDisconnectedSocketDescriptor) return; receivers_list_ = discovery_service__->RotatedUriList(thread_id_); - last_rebalance_ = high_resolution_clock::now(); + last_receivers_uri_update_ = high_resolution_clock::now(); ncurrent_connections_++; } @@ -90,11 +90,11 @@ bool RequestHandlerTcp::CheckForRebalance() { auto now = high_resolution_clock::now(); uint64_t elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>( now - - last_rebalance_).count(); + last_receivers_uri_update_).count(); bool rebalance = false; if (elapsed_ms > discovery_service__->UpdateFrequency()) { auto thread_receivers_new = discovery_service__->RotatedUriList(thread_id_); - last_rebalance_ = now; + last_receivers_uri_update_ = now; if (thread_receivers_new != receivers_list_) { receivers_list_ = thread_receivers_new; rebalance = true; @@ -146,7 +146,7 @@ bool RequestHandlerTcp::ReadyProcessRequest() { } void RequestHandlerTcp::PrepareProcessingRequestLocked() { - UpdateIfNewConnection(); + UpdateReceiversUriIfNewConnection(); } void RequestHandlerTcp::TearDownProcessingRequestLocked(const Error &error_from_process) { diff --git a/producer/api/src/request_handler_tcp.h b/producer/api/src/request_handler_tcp.h index aad47152bcb11247fb7020d2faec949833a4afc7..27f25e35648716e86a00dc9297b23ad88040cec1 100644 --- a/producer/api/src/request_handler_tcp.h +++ b/producer/api/src/request_handler_tcp.h @@ -34,10 +34,10 @@ class RequestHandlerTcp: public RequestHandler { Error ReceiveResponse(const std::string& receiver_address); Error TrySendToReceiver(const Request* request,const std::string& receiver_address); SocketDescriptor sd_{kDisconnectedSocketDescriptor}; - void UpdateIfNewConnection(); + void UpdateReceiversUriIfNewConnection(); bool CheckForRebalance(); ReceiversList receivers_list_; - high_resolution_clock::time_point last_rebalance_; + high_resolution_clock::time_point last_receivers_uri_update_; uint64_t ncurrent_connections_{0}; bool IsConnected(); bool CanCreateNewConnections(); diff --git a/producer/api/src/request_pool.cpp b/producer/api/src/request_pool.cpp index 0f1d86eb557a81ce2c8fa2a56af74b312fb954bc..eba0be22f1284b5e6a08cc30d0515d621569ed62 100644 --- a/producer/api/src/request_pool.cpp +++ b/producer/api/src/request_pool.cpp @@ -4,10 +4,10 @@ namespace asapo { -RequestPool:: RequestPool(uint8_t n_threads, uint64_t max_pool_volume, +RequestPool:: RequestPool(uint8_t n_threads, RequestHandlerFactory* request_handler_factory): log__{GetDefaultProducerLogger()}, request_handler_factory__{request_handler_factory}, - threads_{n_threads}, max_pool_volume_{max_pool_volume} { + threads_{n_threads} { for(size_t i = 0; i < threads_.size(); i++) { log__->Debug("starting thread " + std::to_string(i)); threads_[i] = std::thread( @@ -16,15 +16,7 @@ RequestPool:: RequestPool(uint8_t n_threads, uint64_t max_pool_volume, } -bool RequestPool::RequestWouldFit(const std::unique_ptr<Request>& request) { - return request->GetMemoryRequitements() + current_pool_volume_ < max_pool_volume_; -} - Error RequestPool::AddRequest(std::unique_ptr<Request> request) { - if (!RequestWouldFit(request)) { - return ProducerErrorTemplates::kRequestPoolIsFull.Generate(); - } - std::unique_lock<std::mutex> lock(mutex_); request_queue_.emplace_back(std::move(request)); lock.unlock(); diff --git a/producer/api/src/request_pool.h b/producer/api/src/request_pool.h index b3aaef6aacf3d4eed51201881edf81907676e2f5..b4b0d4fd52a05c4a903c0c9b3098213da66a2e22 100644 --- a/producer/api/src/request_pool.h +++ b/producer/api/src/request_pool.h @@ -26,7 +26,7 @@ class RequestPool { std::unique_lock<std::mutex> lock; }; public: - explicit RequestPool(uint8_t n_threads, uint64_t max_pool_volume, RequestHandlerFactory* request_handler_factory); + explicit RequestPool(uint8_t n_threads, RequestHandlerFactory* request_handler_factory); VIRTUAL Error AddRequest(std::unique_ptr<Request> request); ~RequestPool(); AbstractLogger* log__; @@ -39,9 +39,6 @@ class RequestPool { std::condition_variable condition_; std::mutex mutex_; std::deque<std::unique_ptr<Request>> request_queue_; - uint64_t max_pool_volume_; - uint64_t current_pool_volume_{0}; - bool RequestWouldFit(const std::unique_ptr<Request>& request); bool CanProcessRequest(const std::unique_ptr<RequestHandler>& request_handler); void ProcessRequest(const std::unique_ptr<RequestHandler>& request_handler,ThreadInformation* thread_info); std::unique_ptr<Request> GetRequestFromQueue(); diff --git a/producer/api/unittests/mocking.h b/producer/api/unittests/mocking.h index 6a6aaf46c7fcb998092078f60b4868f457b8172f..13d14da91f0e5a6864fd51a2e936ae29fead9230 100644 --- a/producer/api/unittests/mocking.h +++ b/producer/api/unittests/mocking.h @@ -26,7 +26,7 @@ class MockDiscoveryService : public asapo::ReceiverDiscoveryService { class MockRequestPull : public RequestPool { public: MockRequestPull(RequestHandlerFactory* request_handler_factory) : - RequestPool{1, 1, request_handler_factory} {}; + RequestPool{1, request_handler_factory} {}; asapo::Error AddRequest(std::unique_ptr<asapo::Request> request) override { if (request == nullptr) { return asapo::Error{AddRequest_t(nullptr)}; diff --git a/producer/api/unittests/test_producer_impl.cpp b/producer/api/unittests/test_producer_impl.cpp index 8885325eca79122962737574efb7f12b05e6f645..777c7779af2f8ef227c4e06342846adc52e91bdd 100644 --- a/producer/api/unittests/test_producer_impl.cpp +++ b/producer/api/unittests/test_producer_impl.cpp @@ -63,16 +63,10 @@ TEST_F(ProducerImplTests, ErrorIfSizeTooLarge) { } -MATCHER_P(M_CheckSendDataRequest, request_size, - "Checks if a valid request was send (check size only)") { - return ((Request*)arg)->GetMemoryRequitements() == request_size; -} - - TEST_F(ProducerImplTests, OKSendingRequest) { uint64_t expected_size = 100; Request request{asapo::GenericNetworkRequestHeader{}, nullptr, nullptr}; - EXPECT_CALL(mock_pull, AddRequest_t(M_CheckSendDataRequest(expected_size + sizeof(Request)))).WillOnce(Return( + EXPECT_CALL(mock_pull, AddRequest_t(_)).WillOnce(Return( nullptr)); auto err = producer.Send(1, nullptr, expected_size, nullptr); diff --git a/producer/api/unittests/test_request_handler_tcp.cpp b/producer/api/unittests/test_request_handler_tcp.cpp index f873c8f4a36fbf2b73a25578ccc77fba1f765d2d..f923a3b52cbfa9aca5dbed6a2aab65bc63ddcd02 100644 --- a/producer/api/unittests/test_request_handler_tcp.cpp +++ b/producer/api/unittests/test_request_handler_tcp.cpp @@ -13,6 +13,8 @@ #include <common/networking.h> #include "io/io_factory.h" +#include "mocking.h" + namespace { using ::testing::Return; @@ -24,48 +26,55 @@ using ::testing::Eq; using ::testing::Ne; using ::testing::Mock; using ::testing::AllOf; - +using testing::NiceMock; using ::testing::InSequence; using ::testing::HasSubstr; -TEST(Request, Constructor) { - asapo::GenericNetworkRequestHeader header; - asapo::RequestHandlerTcp request{header, nullptr, [](asapo::GenericNetworkRequestHeader, asapo::Error) {}}; +TEST(RequestHandlerTcp, Constructor) { + MockDiscoveryService ds; + asapo::RequestHandlerTcp request{&ds,1}; ASSERT_THAT(dynamic_cast<const asapo::IO*>(request.io__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(request.log__), Ne(nullptr)); + ASSERT_THAT(request.discovery_service__, Eq(&ds)); } -class RequestTests : public testing::Test { +class RequestHandlerTcpTests : public testing::Test { public: - testing::NiceMock<asapo::MockIO> mock_io; - uint64_t expected_file_id = 4224; + NiceMock<asapo::MockIO> mock_io; + NiceMock<MockDiscoveryService> mock_discovery_service; + + uint64_t expected_file_id = 42k; uint64_t expected_file_size = 1337; - asapo::Opcode expected_op_code = asapo::kNetOpcodeSendData; + uint64_t expected_thread_id = 2; + + asapo::Opcode expected_op_code = asapo::kNetOpcodeSendData; void* expected_file_pointer = (void*)0xC00FE; asapo::Error callback_err; - asapo::GenericNetworkRequestHeader header{expected_op_code, expected_file_id, expected_file_size}; bool called = false; asapo::GenericNetworkRequestHeader callback_header; - asapo::RequestHandlerTcp request{header, expected_file_pointer, [this](asapo::GenericNetworkRequestHeader header, asapo::Error err) { + asapo::Request request{header, expected_file_pointer, [this](asapo::GenericNetworkRequestHeader header, asapo::Error err) { called = true; callback_err = std::move(err); callback_header = header; }}; - asapo::RequestHandlerTcp request_nocallback{header, expected_file_pointer, nullptr}; - + asapo::Request request_nocallback{header, expected_file_pointer, nullptr}; testing::NiceMock<asapo::MockLogger> mock_logger; + asapo::RequestHandlerTcp request_handler{&mock_discovery_service,expected_thread_id}; + asapo::SocketDescriptor sd = asapo::kDisconnectedSocketDescriptor; std::string expected_address1 = {"127.0.0.1:9090"}; std::string expected_address2 = {"127.0.0.1:9091"}; asapo::ReceiversList receivers_list{expected_address1, expected_address2}; - std::vector<asapo::SocketDescriptor> expected_sds{83942, 83943}; + asapo::ReceiversList receivers_list_single{expected_address1}; + + std::vector<asapo::SocketDescriptor> expected_sds{83942, 83943}; void ExpectFailConnect(bool only_once = false); void ExpectFailSendHeader(bool only_once = false); @@ -75,16 +84,14 @@ class RequestTests : public testing::Test { void ExpectOKSendData(bool only_once = false); void ExpectFailReceive(bool only_once = false); void ExpectOKReceive(bool only_once = true); + void DoSingleSend(bool success = true); void SetUp() override { - request.log__ = &mock_logger; - request.io__.reset(&mock_io); - request_nocallback.log__ = &mock_logger; - request_nocallback.io__.reset(&mock_io); + request_handler.log__ = &mock_logger; + request_handler.io__.reset(&mock_io); } void TearDown() override { - request.io__.release(); - request_nocallback.io__.release(); + request_handler.io__.release(); } }; @@ -100,7 +107,8 @@ MATCHER_P2(M_CheckSendDataRequest, file_id, file_size, && ((asapo::GenericNetworkRequestHeader*)arg)->data_size == file_size; } -void RequestTests::ExpectFailConnect(bool only_once) { + +void RequestHandlerTcpTests::ExpectFailConnect(bool only_once) { for (auto expected_address : receivers_list) { EXPECT_CALL(mock_io, CreateAndConnectIPTCPSocket_t(expected_address, _)) .WillOnce( @@ -113,7 +121,7 @@ void RequestTests::ExpectFailConnect(bool only_once) { } -void RequestTests::ExpectFailSendHeader(bool only_once) { +void RequestHandlerTcpTests::ExpectFailSendHeader(bool only_once) { int i = 0; for (auto expected_sd : expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, M_CheckSendDataRequest(expected_file_id, @@ -136,7 +144,7 @@ void RequestTests::ExpectFailSendHeader(bool only_once) { } -void RequestTests::ExpectFailSendData(bool only_once) { +void RequestHandlerTcpTests::ExpectFailSendData(bool only_once) { int i = 0; for (auto expected_sd : expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, expected_file_pointer, expected_file_size, _)) @@ -159,7 +167,7 @@ void RequestTests::ExpectFailSendData(bool only_once) { } -void RequestTests::ExpectFailReceive(bool only_once) { +void RequestHandlerTcpTests::ExpectFailReceive(bool only_once) { int i = 0; for (auto expected_sd : expected_sds) { EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendDataResponse), _)) @@ -182,7 +190,7 @@ void RequestTests::ExpectFailReceive(bool only_once) { } -void RequestTests::ExpectOKSendData(bool only_once) { +void RequestHandlerTcpTests::ExpectOKSendData(bool only_once) { for (auto expected_sd : expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, expected_file_pointer, expected_file_size, _)) .Times(1) @@ -198,7 +206,7 @@ void RequestTests::ExpectOKSendData(bool only_once) { -void RequestTests::ExpectOKSendHeader(bool only_once) { +void RequestHandlerTcpTests::ExpectOKSendHeader(bool only_once) { for (auto expected_sd : expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, M_CheckSendDataRequest(expected_file_id, expected_file_size), @@ -214,7 +222,7 @@ void RequestTests::ExpectOKSendHeader(bool only_once) { } -void RequestTests::ExpectOKConnect(bool only_once) { +void RequestHandlerTcpTests::ExpectOKConnect(bool only_once) { int i = 0; for (auto expected_address : receivers_list) { EXPECT_CALL(mock_io, CreateAndConnectIPTCPSocket_t(expected_address, _)) @@ -234,7 +242,7 @@ void RequestTests::ExpectOKConnect(bool only_once) { } -void RequestTests::ExpectOKReceive(bool only_once) { +void RequestHandlerTcpTests::ExpectOKReceive(bool only_once) { int i = 0; for (auto expected_sd : expected_sds) { EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendDataResponse), _)) @@ -254,6 +262,89 @@ void RequestTests::ExpectOKReceive(bool only_once) { } } +TEST_F(RequestHandlerTcpTests, CannotProcessRequestIfNotEnoughConnections) { + EXPECT_CALL(mock_discovery_service, MaxConnections()).WillOnce(Return(0)); + auto res = request_handler.ReadyProcessRequest(); + ASSERT_THAT(res, Eq(false)); +} + +void RequestHandlerTcpTests::DoSingleSend(bool success) { + if (success) ExpectOKConnect(true); + ExpectOKSendHeader(true); + ExpectOKSendData(true); + if (success) { + ExpectOKReceive(true); + }else { + ExpectFailReceive(true); + } + + + EXPECT_CALL(mock_discovery_service, RotatedUriList(_)). + WillOnce(Return(receivers_list_single)); + + request_handler.PrepareProcessingRequestLocked(); + request_handler.ProcessRequestUnlocked(&request); + + Mock::VerifyAndClearExpectations(&mock_io); + Mock::VerifyAndClearExpectations(&mock_logger); + Mock::VerifyAndClearExpectations(&mock_discovery_service); + +} + +TEST_F(RequestHandlerTcpTests, CanProcessRequestIfAlreadyConnected) { + DoSingleSend(); + EXPECT_CALL(mock_discovery_service, MaxConnections()).Times(0); + + auto res = request_handler.ReadyProcessRequest(); + + ASSERT_THAT(res, Eq(true)); +} + +TEST_F(RequestHandlerTcpTests, GetsUriListINotConnected) { + EXPECT_CALL(mock_discovery_service, RotatedUriList(_)); + request_handler.PrepareProcessingRequestLocked(); +} + +TEST_F(RequestHandlerTcpTests, DoesNotGetsUriIfAlreadyConnected) { + DoSingleSend(); + request_handler.PrepareProcessingRequestLocked(); +} + +TEST_F(RequestHandlerTcpTests, ReduceConnectionNumberAtTearDownIfError) { + DoSingleSend(false); + + auto err = asapo::TextError("error"); + + request_handler.TearDownProcessingRequestLocked(err); + + + EXPECT_CALL(mock_discovery_service, MaxConnections()).WillOnce(Return(1)); + auto res = request_handler.ReadyProcessRequest(); + ASSERT_THAT(res, Eq(true)); + +} + + +TEST_F(RequestHandlerTcpTests, DoNotReduceConnectionNumberAtTearDownIfNoError) { + DoSingleSend(true); + DoSingleSend(false); + + auto err = asapo::TextError("error"); + request_handler.TearDownProcessingRequestLocked(err); + +// EXPECT_CALL(mock_discovery_service, MaxConnections()).WillOnce(Return(1)); + auto res = request_handler.ReadyProcessRequest(); + ASSERT_THAT(res, Eq(false)); + +} + + +/* +//Error ProcessRequestUnlocked(const Request* request) override; + +//void TearDownProcessingRequestLocked(const Error &error_from_process) override; + + TEST_F(RequestTests, MemoryRequirements) { @@ -406,5 +497,5 @@ TEST_F(RequestTests, SendOK) { } - +*/ } diff --git a/producer/api/unittests/test_request_pool.cpp b/producer/api/unittests/test_request_pool.cpp index 9202d0d5b466560ce7f74032d8ff2e41c1a08723..a665ffcdcd833ff5213554eccb298f4402062121 100644 --- a/producer/api/unittests/test_request_pool.cpp +++ b/producer/api/unittests/test_request_pool.cpp @@ -62,8 +62,7 @@ class RequestPoolTests : public testing::Test { NiceMock<asapo::MockLogger> mock_logger; MockRequestHandlerFactory request_handler_factory{mock_request_handler}; const uint8_t nthreads = 1; - const uint64_t max_size = 1024 * 1024 * 1024; - asapo::RequestPool pool {nthreads, max_size, &request_handler_factory}; + asapo::RequestPool pool {nthreads, &request_handler_factory}; std::unique_ptr<Request> request{new Request{GenericNetworkRequestHeader{}, nullptr, nullptr}}; void SetUp() override { pool.log__ = &mock_logger; @@ -77,26 +76,11 @@ TEST(RequestPool, Constructor) { NiceMock<MockDiscoveryService> ds; NiceMock<asapo::RequestHandlerFactory> request_handler_factory{asapo::RequestHandlerType::kTcp,&ds}; - asapo::RequestPool pool{4, 4, &request_handler_factory}; + asapo::RequestPool pool{4, &request_handler_factory}; ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(pool.log__), Ne(nullptr)); } - - -TEST(RequestPool, AddRequestFailsDueToSize) { - asapo::ReceiverDiscoveryService discovery{asapo::expected_endpoint, 1000}; - NiceMock<asapo::RequestHandlerFactory> request_handler_factory{asapo::RequestHandlerType::kTcp,&discovery}; - - RequestPool pool{4, 0, &request_handler_factory}; - std::unique_ptr<Request> request{new Request{GenericNetworkRequestHeader{}, nullptr, nullptr}}; - - auto err = pool.AddRequest(std::move(request)); - - ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kRequestPoolIsFull)); - -} - TEST_F(RequestPoolTests, AddRequestDoesGoFurtherWhenNotReady) { EXPECT_CALL(*mock_request_handler, ReadyProcessRequest()).Times(AtLeast(1)).WillRepeatedly(Return(false)); diff --git a/receiver/unittests/test_request.cpp b/receiver/unittests/test_request.cpp index a22fec1ed520b2b4d15c616616b47e78deb7589e..539f07228b075da3a9a598876b37efa1b4f15b92 100644 --- a/receiver/unittests/test_request.cpp +++ b/receiver/unittests/test_request.cpp @@ -61,7 +61,7 @@ class MockReqestHandler : public asapo::RequestHandler { }; -class RequestTests : public Test { +class RequestHandlerTcpTests : public Test { public: GenericNetworkRequestHeader generic_request_header; asapo::SocketDescriptor socket_fd_{1};