Skip to content

Commit

Permalink
split unittest into multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-schlecker committed Jun 24, 2022
1 parent 6f1baed commit 25a828a
Show file tree
Hide file tree
Showing 23 changed files with 3,191 additions and 46 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
*.app

example
unittest
Testing/*
include/crow/tags

Expand Down
19 changes: 1 addition & 18 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
cmake_minimum_required(VERSION 3.15)
project(crow_test)

include(${CMAKE_SOURCE_DIR}/cmake/compiler_options.cmake)

set(TEST_SRCS
unittest.cpp
)

add_executable(unittest ${TEST_SRCS})
target_link_libraries(unittest Crow::Crow)
add_warnings_optimizations(unittest)

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set_target_properties(unittest PROPERTIES COMPILE_FLAGS "--coverage -fprofile-arcs -ftest-coverage")
target_link_libraries(unittest gcov)
endif()

add_subdirectory(unittest)
add_subdirectory(template)
add_subdirectory(multi_file)
if ("ssl" IN_LIST CROW_FEATURES)
add_subdirectory(ssl)
endif()
add_subdirectory(img)
18 changes: 0 additions & 18 deletions tests/ssl/CMakeLists.txt

This file was deleted.

39 changes: 39 additions & 0 deletions tests/unittest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.15)
project(crow_test)

include(${CMAKE_SOURCE_DIR}/cmake/compiler_options.cmake)

set(TEST_SRCS
src/app.cpp
src/black_magic.cpp
src/blueprints.cpp
src/json.cpp
src/middlewares.cpp
src/query_string.cpp
src/requests.cpp
src/responses.cpp
src/routing.cpp
src/task_timer.cpp
src/templates.cpp
src/utility.cpp
src/websocket.cpp

src/catch.cpp
)

if("ssl" IN_LIST CROW_FEATURES)
list(APPEND TEST_SRCS "src/ssl.cpp")
endif()
if("compression" IN_LIST CROW_FEATURES)
list(APPEND TEST_SRCS "src/compression.cpp")
endif()

add_executable(unittest ${TEST_SRCS})
target_include_directories(unittest PRIVATE include)
target_link_libraries(unittest Crow::Crow)
add_warnings_optimizations(unittest)

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set_target_properties(unittest PROPERTIES COMPILE_FLAGS "--coverage -fprofile-arcs -ftest-coverage")
target_link_libraries(unittest gcov)
endif()
127 changes: 127 additions & 0 deletions tests/unittest/include/Middlewares.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#pragma once
#include "crow.h"
#include <vector>

using namespace crow;

struct NullMiddleware
{
struct context
{};

template<typename AllContext>
void before_handle(request&, response&, context&, AllContext&)
{}

template<typename AllContext>
void after_handle(request&, response&, context&, AllContext&)
{}
};

struct NullSimpleMiddleware
{
struct context
{};

void before_handle(request& /*req*/, response& /*res*/, context& /*ctx*/) {}

void after_handle(request& /*req*/, response& /*res*/, context& /*ctx*/) {}
};

struct IntSettingMiddleware
{
struct context
{
int val;
};

template<typename AllContext>
void before_handle(request&, response&, context& ctx, AllContext&)
{
ctx.val = 1;
}

template<typename AllContext>
void after_handle(request&, response&, context& ctx, AllContext&)
{
ctx.val = 2;
}
};

static std::vector<std::string> test_middleware_context_vector;

struct empty_type
{};

template<bool Local>
struct FirstMW : public std::conditional<Local, crow::ILocalMiddleware, empty_type>::type
{
struct context
{
std::vector<string> v;
};

void before_handle(request& /*req*/, response& /*res*/, context& ctx)
{
ctx.v.push_back("1 before");
}

void after_handle(request& /*req*/, response& /*res*/, context& ctx)
{
ctx.v.push_back("1 after");
test_middleware_context_vector = ctx.v;
}
};

template<bool Local>
struct SecondMW : public std::conditional<Local, crow::ILocalMiddleware, empty_type>::type
{
struct context
{};
template<typename AllContext>
void before_handle(request& req, response& res, context&, AllContext& all_ctx)
{
all_ctx.template get<FirstMW<Local>>().v.push_back("2 before");
if (req.url.find("/break") != std::string::npos) res.end();
}

template<typename AllContext>
void after_handle(request&, response&, context&, AllContext& all_ctx)
{
all_ctx.template get<FirstMW<Local>>().v.push_back("2 after");
}
};

template<bool Local>
struct ThirdMW : public std::conditional<Local, crow::ILocalMiddleware, empty_type>::type
{
struct context
{};
template<typename AllContext>
void before_handle(request&, response&, context&, AllContext& all_ctx)
{
all_ctx.template get<FirstMW<Local>>().v.push_back("3 before");
}

template<typename AllContext>
void after_handle(request&, response&, context&, AllContext& all_ctx)
{
all_ctx.template get<FirstMW<Local>>().v.push_back("3 after");
}
};


struct LocalSecretMiddleware : crow::ILocalMiddleware
{
struct context
{};

void before_handle(request& /*req*/, response& res, context& /*ctx*/)
{
res.code = 403;
res.end();
}

void after_handle(request& /*req*/, response& /*res*/, context& /*ctx*/)
{}
};
File renamed without changes.
10 changes: 10 additions & 0 deletions tests/unittest/include/unittest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#define CROW_LOG_LEVEL 0
#define LOCALHOST_ADDRESS "127.0.0.1"

#include "catch.hpp"
#include "crow.h"

using namespace std;
using namespace crow;
152 changes: 152 additions & 0 deletions tests/unittest/src/app.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include "unittest.h"
#include "Middlewares.h"

struct OnlyMoveConstructor
{
OnlyMoveConstructor(int) {}
OnlyMoveConstructor(const OnlyMoveConstructor&) = delete;
OnlyMoveConstructor(OnlyMoveConstructor&&) = default;
};

TEST_CASE("app_constructor")
{
App<NullMiddleware, OnlyMoveConstructor, FirstMW<false>, SecondMW<false>>
app1(OnlyMoveConstructor(1), SecondMW<false>{});
App<NullMiddleware, OnlyMoveConstructor, FirstMW<false>, SecondMW<false>>
app2(FirstMW<false>{}, OnlyMoveConstructor(1));
} // app_constructor

TEST_CASE("multi_server")
{
static char buf[2048];
SimpleApp app1, app2;
CROW_ROUTE(app1, "/").methods("GET"_method,
"POST"_method)([] {
return "A";
});
CROW_ROUTE(app2, "/").methods("GET"_method,
"POST"_method)([] {
return "B";
});

auto _ = app1.bindaddr(LOCALHOST_ADDRESS).port(45451).run_async();
auto _2 = app2.bindaddr(LOCALHOST_ADDRESS).port(45452).run_async();
app1.wait_for_server_start();
app2.wait_for_server_start();

std::string sendmsg =
"POST / HTTP/1.0\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n";
{
asio::io_service is;
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));

c.send(asio::buffer(sendmsg));

size_t recved = c.receive(asio::buffer(buf, 2048));
CHECK('A' == buf[recved - 1]);
}

{
asio::io_service is;
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452));

for (auto ch : sendmsg)
{
char buf[1] = {ch};
c.send(asio::buffer(buf));
}

size_t recved = c.receive(asio::buffer(buf, 2048));
CHECK('B' == buf[recved - 1]);
}

app1.stop();
app2.stop();
} // multi_server

TEST_CASE("get_port")
{
SimpleApp app;

const std::uint16_t port = 12345;

auto _ = app.port(port).run_async();

app.wait_for_server_start();
CHECK(app.port() == port);
app.stop();

} // get_port

TEST_CASE("timeout")
{
auto test_timeout = [](const std::uint8_t timeout) {
static char buf[2048];

SimpleApp app;

CROW_ROUTE(app, "/")
([]() {
return "hello";
});

auto _ = app.bindaddr(LOCALHOST_ADDRESS).timeout(timeout).port(45451).run_async();

app.wait_for_server_start();
asio::io_service is;
std::string sendmsg = "GET /\r\n\r\n";
future_status status;

{
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));

auto receive_future = async(launch::async, [&]() {
asio::error_code ec;
c.receive(asio::buffer(buf, 2048), 0, ec);
return ec;
});
status = receive_future.wait_for(std::chrono::seconds(timeout - 1));
CHECK(status == future_status::timeout);

status = receive_future.wait_for(chrono::seconds(3));
CHECK(status == future_status::ready);
CHECK(receive_future.get() == asio::error::eof);

c.close();
}
{
asio::ip::tcp::socket c(is);
c.connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));

size_t received;
auto receive_future = async(launch::async, [&]() {
asio::error_code ec;
received = c.receive(asio::buffer(buf, 2048), 0, ec);
return ec;
});
status = receive_future.wait_for(std::chrono::seconds(timeout - 1));
CHECK(status == future_status::timeout);

c.send(asio::buffer(sendmsg));

status = receive_future.wait_for(chrono::seconds(3));
CHECK(status == future_status::ready);
CHECK(!receive_future.get());
CHECK("hello" == std::string(buf + received - 5, buf + received));

c.close();
}

app.stop();
};

test_timeout(3);
test_timeout(5);
} // timeout
Loading

0 comments on commit 25a828a

Please sign in to comment.