Better ClientServerTestRunner

This commit is contained in:
lganzzzo 2019-02-23 16:53:07 +02:00
parent f7ce8ea873
commit 9efb58fc02
8 changed files with 86 additions and 76 deletions

View File

@ -206,7 +206,6 @@ add_library(oatpp-test
oatpp-test/Checker.hpp
oatpp-test/UnitTest.cpp
oatpp-test/UnitTest.hpp
oatpp-test/web/ClientServerTestRunner.cpp
oatpp-test/web/ClientServerTestRunner.hpp
)

View File

@ -1,25 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "ClientServerTestRunner.hpp"

View File

@ -34,9 +34,15 @@
#include "oatpp/core/macro/component.hpp"
#include <list>
#include <chrono>
#include <mutex>
#include <condition_variable>
namespace oatpp { namespace test { namespace web {
/**
* Helper class to run Client-Server tests
*/
class ClientServerTestRunner {
public:
typedef oatpp::web::server::HttpRouter HttpRouter;
@ -52,39 +58,75 @@ public:
return m_router;
}
/**
* Add controller's endpoints to router
* @param controller
*/
void addController(const std::shared_ptr<ApiController>& controller) {
controller->addEndpointsToRouter(m_router);
m_controllers.push_back(controller);
}
/**
* Start server, execute code block passed as lambda, stop server.
* @tparam Lambda
* @param lambda
* @param timeout
*/
template<typename Lambda>
void run(const Lambda& lambda) {
void run(
const Lambda& lambda,
const std::chrono::duration<v_int64, std::micro>& timeout = std::chrono::hours(12)
) {
auto startTime = std::chrono::system_clock::now();
bool running = true;
std::mutex timeoutMutex;
std::condition_variable timeoutCondition;
oatpp::network::server::Server server(m_connectionProvider, m_connectionHandler);
OATPP_LOGD("Server", "Running on port %s...", m_connectionProvider->getProperty("port").toString()->c_str());
std::thread clientThread([this, &server, &lambda]{
lambda();
try {
server.stop();
m_connectionHandler->stop();
m_connectionProvider->close();
} catch(std::runtime_error e) {
// DO NOTHING
}
});
OATPP_LOGD("\033[1;34mClientServerTestRunner\033[0m", "\033[1;34mRunning server on port %s. Timeout %lld(micro)\033[0m",
m_connectionProvider->getProperty("port").toString()->c_str(),
timeout.count());
std::thread serverThread([&server]{
server.run();
});
clientThread.join();
serverThread.join();
std::thread clientThread([this, &server, &lambda]{
lambda();
server.stop();
m_connectionHandler->stop();
m_connectionProvider->close();
});
std::thread timerThread([&timeout, &startTime, &running, &timeoutMutex, &timeoutCondition]{
auto end = startTime + timeout;
std::unique_lock<std::mutex> lock(timeoutMutex);
while(running) {
timeoutCondition.wait_for(lock, std::chrono::seconds(1));
std::chrono::duration<double, std::milli> elapsed = std::chrono::system_clock::now() - startTime;
OATPP_ASSERT("ClientServerTestRunner: Error. Timeout." && elapsed < timeout);
}
});
serverThread.join();
clientThread.join();
std::chrono::duration<v_int64, std::micro> elapsed = std::chrono::system_clock::now() - startTime;
OATPP_LOGD("\033[1;34mClientServerTestRunner\033[0m", "\033[1;34mFinished with time %lld(micro). Stopping server...\033[0m", elapsed.count());
running = false;
timeoutCondition.notify_one();
timerThread.join();
// Wait for worker threads are finished
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

View File

@ -40,6 +40,7 @@ namespace oatpp { namespace network { namespace server {
SimpleTCPConnectionProvider::SimpleTCPConnectionProvider(v_word16 port, bool nonBlocking)
: m_port(port)
, m_nonBlocking(nonBlocking)
, m_closed(false)
{
m_serverHandle = instantiateServer();
setProperty(PROPERTY_HOST, "localhost");
@ -51,7 +52,8 @@ SimpleTCPConnectionProvider::~SimpleTCPConnectionProvider() {
}
void SimpleTCPConnectionProvider::close() {
if(m_serverHandle != 0) {
if(!m_closed) {
m_closed = true;
::close(m_serverHandle);
}
}
@ -108,7 +110,9 @@ std::shared_ptr<oatpp::data::stream::IOStream> SimpleTCPConnectionProvider::getC
if(error == EAGAIN || error == EWOULDBLOCK){
return nullptr;
} else {
OATPP_LOGD("[oatpp::network::server::SimpleTCPConnectionProvider::getConnection()]", "Error. %d", error);
if(!m_closed) { // m_serverHandle==0 if ConnectionProvider was closed. Not an error.
OATPP_LOGD("[oatpp::network::server::SimpleTCPConnectionProvider::getConnection()]", "Error. %d", error);
}
return nullptr;
}
}

View File

@ -36,6 +36,7 @@ class SimpleTCPConnectionProvider : public base::Controllable, public ServerConn
private:
v_word16 m_port;
bool m_nonBlocking;
bool m_closed;
oatpp::data::v_io_handle m_serverHandle;
private:
oatpp::data::v_io_handle instantiateServer();

View File

@ -49,6 +49,7 @@ public:
void runTests() {
/*
OATPP_RUN_TEST(oatpp::test::base::RegRuleTest);
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
OATPP_RUN_TEST(oatpp::test::memory::MemoryPoolTest);
@ -65,7 +66,7 @@ void runTests() {
OATPP_RUN_TEST(oatpp::test::network::virtual_::PipeTest);
OATPP_RUN_TEST(oatpp::test::network::virtual_::InterfaceTest);
*/
OATPP_RUN_TEST(oatpp::test::web::FullTest);
OATPP_RUN_TEST(oatpp::test::web::FullAsyncTest);

View File

@ -50,7 +50,7 @@ namespace oatpp { namespace test { namespace web {
namespace {
//#define OATPP_TEST_USE_REAL_PORT
//#define OATPP_TEST_USE_PORT 8123
class TestComponent {
public:
@ -60,14 +60,11 @@ public:
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([this] {
#ifdef OATPP_TEST_USE_REAL_PORT
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(8000, true /* nonBlocking */);
#ifdef OATPP_TEST_USE_PORT
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(OATPP_TEST_USE_PORT, true /* nonBlocking */);
#else
OATPP_COMPONENT(std::shared_ptr<oatpp::network::virtual_::Interface>, interface);
auto provider = oatpp::network::virtual_::server::ConnectionProvider::createShared(interface, true /* nonBlocking */);
//provider->setSocketMaxAvailableToReadWrtie(123, 11);
provider->setSocketMaxAvailableToReadWrtie(-1, -1);
return provider;
return oatpp::network::virtual_::server::ConnectionProvider::createShared(interface, true /* nonBlocking */);
#endif
}());
@ -85,14 +82,11 @@ public:
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ClientConnectionProvider>, clientConnectionProvider)([this] {
#ifdef OATPP_TEST_USE_REAL_PORT
return oatpp::network::client::SimpleTCPConnectionProvider::createShared("127.0.0.1", 8000);
#ifdef OATPP_TEST_USE_PORT
return oatpp::network::client::SimpleTCPConnectionProvider::createShared("127.0.0.1", OATPP_TEST_USE_PORT);
#else
OATPP_COMPONENT(std::shared_ptr<oatpp::network::virtual_::Interface>, interface);
auto provider = oatpp::network::virtual_::client::ConnectionProvider::createShared(interface);
//provider->setSocketMaxAvailableToReadWrtie(12421, 21312);
provider->setSocketMaxAvailableToReadWrtie(-1, -1);
return provider;
return oatpp::network::virtual_::client::ConnectionProvider::createShared(interface);
#endif
}());
@ -171,7 +165,7 @@ void FullAsyncTest::onRun() {
}
});
}, std::chrono::minutes(10));
}

View File

@ -50,7 +50,7 @@ namespace oatpp { namespace test { namespace web {
namespace {
//#define OATPP_TEST_USE_REAL_PORT
//#define OATPP_TEST_USE_PORT 8123
class TestComponent {
public:
@ -60,14 +60,11 @@ public:
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([this] {
#ifdef OATPP_TEST_USE_REAL_PORT
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(8000);
#ifdef OATPP_TEST_USE_PORT
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(OATPP_TEST_USE_PORT);
#else
OATPP_COMPONENT(std::shared_ptr<oatpp::network::virtual_::Interface>, interface);
auto provider = oatpp::network::virtual_::server::ConnectionProvider::createShared(interface);
//provider->setSocketMaxAvailableToReadWrtie(123, 11);
provider->setSocketMaxAvailableToReadWrtie(-1, -1);
return provider;
return oatpp::network::virtual_::server::ConnectionProvider::createShared(interface);
#endif
}());
@ -85,14 +82,11 @@ public:
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ClientConnectionProvider>, clientConnectionProvider)([this] {
#ifdef OATPP_TEST_USE_REAL_PORT
return oatpp::network::client::SimpleTCPConnectionProvider::createShared("127.0.0.1", 8000);
#ifdef OATPP_TEST_USE_PORT
return oatpp::network::client::SimpleTCPConnectionProvider::createShared("127.0.0.1", OATPP_TEST_USE_PORT);
#else
OATPP_COMPONENT(std::shared_ptr<oatpp::network::virtual_::Interface>, interface);
auto provider = oatpp::network::virtual_::client::ConnectionProvider::createShared(interface);
//provider->setSocketMaxAvailableToReadWrtie(12421, 21312);
provider->setSocketMaxAvailableToReadWrtie(-1, -1);
return provider;
return oatpp::network::virtual_::client::ConnectionProvider::createShared(interface);
#endif
}());
@ -167,7 +161,7 @@ void FullTest::onRun() {
}
});
}, std::chrono::minutes(10));
}