Skip to content

Commit

Permalink
test: removed static lib dependency between tests and snail, used src…
Browse files Browse the repository at this point in the history
… level dependency instead
  • Loading branch information
scokmen committed Jul 29, 2024
1 parent 676e0ef commit c479320
Show file tree
Hide file tree
Showing 17 changed files with 161 additions and 218 deletions.
56 changes: 32 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
cmake_minimum_required(VERSION 3.16.3)
cmake_minimum_required(VERSION 3.28.1)
project(snail LANGUAGES C)

# Variables
set(CMAKE_C_STANDARD 11)
set(LIBRARY_PATH "src")
set(VENDORS_PATH "vendors")
set(TEST_PATH "test")
set(SAMPLES_PATH "samples")
set(BENCHMARKS_PATH "benchmark")
set(TEST_CASES_SOURCE "CTestCases.txt")
set(LIBRARY_PATH "src")
set(VENDORS_PATH "vendors")
set(TEST_PATH "test")
set(SAMPLES_PATH "samples")
set(BENCHMARKS_PATH "benchmark")
set(TEST_CASES_SOURCE "CTestCases.txt")

# CTEST
include(CTest)
Expand Down Expand Up @@ -39,6 +39,20 @@ target_include_directories(pico
########################################################################


########################################################################
# SHARED #
# Shared functions & utilities #
########################################################################
function(prepare_artifact project)
target_include_directories("${project}"
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
target_link_libraries("${project}" pico uv)
endfunction()

########################################################################
# SNAIL #
# https://github.com/scokmen/snail #
Expand All @@ -56,27 +70,21 @@ set(snail_resources

add_library(snail STATIC ${snail_resources})

target_include_directories(snail
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)

target_link_libraries(snail pico uv)
prepare_artifact(snail)
########################################################################


########################################################################
# SAMPLES #
# /samples/* #
########################################################################
set(sample_applications
"simple_server")
# Discover the bench files using glob "sample_*.c"
file(GLOB SAMPLE_FILES "${SAMPLES_PATH}/sample_*.c")

foreach (sample_application IN LISTS sample_applications)
add_executable("${sample_application}_sample" "${SAMPLES_PATH}/${sample_application}.c")
target_link_libraries("${sample_application}_sample" snail)
foreach (SAMPLE_FILE IN LISTS SAMPLE_FILES)
get_filename_component(SAMPLE_FILE_NAME "${SAMPLE_FILE}" NAME_WLE)
add_executable("${SAMPLE_FILE_NAME}" "${SAMPLES_PATH}/${SAMPLE_FILE_NAME}.c")
target_link_libraries("${SAMPLE_FILE_NAME}" snail)
endforeach()
########################################################################

Expand All @@ -101,8 +109,8 @@ file(STRINGS "${TEST_CASES_SOURCE}" TEST_FILE_AND_CASES)
foreach(TEST_FILE_PATH IN LISTS TEST_FILES)
get_filename_component(TEST_FILE_WITH_SUFFIX "${TEST_FILE_PATH}" NAME_WLE)
string(REPLACE "_test" "" TEST_FILE "${TEST_FILE_WITH_SUFFIX}")
add_executable("${TEST_FILE_WITH_SUFFIX}" ${test_resources} "${TEST_FILE_PATH}")
target_link_libraries("${TEST_FILE_WITH_SUFFIX}" snail)
add_executable("${TEST_FILE_WITH_SUFFIX}" ${test_resources} ${snail_resources} "${TEST_FILE_PATH}")
prepare_artifact("${TEST_FILE_WITH_SUFFIX}")
foreach(TEST_FILE_AND_CASE IN LISTS TEST_FILE_AND_CASES)
if (TEST_FILE_AND_CASE MATCHES "^#.*")
continue()
Expand All @@ -125,7 +133,7 @@ file(GLOB BENCHMARKS_FILES "${BENCHMARKS_PATH}/*_bench.c")

foreach (BENCHMARKS_FILE IN LISTS BENCHMARKS_FILES)
get_filename_component(BENCHMARKS_FILE_NAME "${BENCHMARKS_FILE}" NAME_WLE)
add_executable("${BENCHMARKS_FILE_NAME}" "${BENCHMARKS_PATH}/${BENCHMARKS_FILE_NAME}.c")
target_link_libraries("${BENCHMARKS_FILE_NAME}" snail)
add_executable("${BENCHMARKS_FILE_NAME}" ${snail_resources} "${BENCHMARKS_PATH}/${BENCHMARKS_FILE_NAME}.c")
prepare_artifact("${BENCHMARKS_FILE_NAME}")
endforeach()
########################################################################
2 changes: 1 addition & 1 deletion benchmark/dlist_bench.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <snail.h>
#include <stdlib.h>
#include <time.h>
#include "snail.h"

typedef struct {
int val;
Expand Down
9 changes: 6 additions & 3 deletions benchmark/map_bench.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <snail.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include "snail.h"

typedef struct {
int val;
Expand All @@ -13,7 +13,10 @@ static map_data *new_map_data() {
return data;
}

static void key_value_destructor(const char* key, void *data) {
static void map_destructor(const char* key, void *data) {
if (key == NULL) {
exit(EXIT_FAILURE);
}
free(data);
}

Expand Down Expand Up @@ -46,7 +49,7 @@ static void run_map_bench(int16_t bucket_size, int count, int key_length, int nu
}
}

if (sn_map_init(&map, bucket_size, key_value_destructor) != 0) {
if (sn_map_init(&map, bucket_size, map_destructor) != 0) {
exit(EXIT_FAILURE);
}

Expand Down
43 changes: 19 additions & 24 deletions include/headers/router.h
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
#ifndef SNAIL_ROUTER_H
#define SNAIL_ROUTER_H

#define MIDDLEWARE_LIMIT (4)
#define HANDLER_PROPS const char *path; \
sn_handler_type type; \
sn_dlist_t middlewares; \

typedef enum {
SN_UNKNOWN_HANDLER = 0,
SN_ROUTER,
SN_ROUTER_GROUP
SN_ROUTE_HANDLER,
SN_ROUTE_GROUP
} sn_handler_type;

#define HANDLER_PROPS const char *path; \
sn_handler_type type; \
struct { \
int size; \
int capacity; \
sn_route_handler_cb *handlers; \
} middlewares; \

typedef struct {
sn_map_t *context;
sn_map_t context;
} sn_route_ctx_t;

typedef struct {
const char *path;
sn_map_t *headers;
sn_map_t *queries;
sn_map_t headers;
sn_map_t queries;
sn_map_t params;
} sn_http_req_t;

typedef struct {
sn_map_t *headers;
sn_map_t headers;
} sn_http_res_t;

typedef sn_http_res_t *(*sn_route_handler_cb)(sn_http_req_t *req, sn_route_ctx_t *ctx);
typedef sn_http_res_t *(*sn_req_handler)(sn_http_req_t *req, sn_route_ctx_t *ctx);

typedef struct {
HANDLER_PROPS
Expand All @@ -40,27 +35,27 @@ typedef struct {
typedef struct {
HANDLER_PROPS
sn_http_method_t method;
sn_route_handler_cb action;
} sn_router_t;
sn_req_handler action;
} sn_route_handler_t;

typedef struct {
HANDLER_PROPS
sn_map_t *routes;
sn_dlist_t routes;
} sn_route_group_t;

SN_NONNULL(1, 3, 4)
int sn_routing_init(sn_router_t **router, sn_http_method_t method, const char *path, sn_route_handler_cb action);
void sn_route_handler_init(sn_route_handler_t *route_handler, sn_http_method_t method, const char *path, sn_req_handler handler);

SN_NONNULL(1, 2)
int sn_routing_init_group(sn_route_group_t **route_group, const char *path);
void sn_route_group_init(sn_route_group_t *route_group, const char *path);

SN_NONNULL(1, 2)
int sn_routing_add_group(sn_route_group_t *route_group, sn_handler_t *handler);
int sn_route_add_subgroup(sn_route_group_t *route_group, sn_handler_t *handler);

SN_NONNULL(1, 2)
int sn_routing_add_middleware(sn_handler_t *handler, sn_route_handler_cb middleware);
int sn_route_add_middleware(sn_handler_t *handler, sn_req_handler middleware);

SN_NONNULL(1)
void sn_routing_destroy(sn_handler_t *handler);
void sn_route_destroy(sn_handler_t *handler);

#endif //SNAIL_ROUTER_H
3 changes: 2 additions & 1 deletion include/snail.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "headers/http.h"
#include "headers/router.h"

int sn_listen(int port);
SN_NONNULL(2)
int sn_listen(int port, sn_route_group_t *route_group);

#endif //SNAIL_SNAIL_H
3 changes: 0 additions & 3 deletions reports/valgrind_reports.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ valgrind --leak-check=yes ./map_bench
==2403== total heap usage: 194,468 allocs, 194,468 frees, 2,519,072 bytes allocated
==2403==
==2403== All heap blocks were freed -- no leaks are possible
==2403==
==2403== For lists of detected and suppressed errors, rerun with: -s
==2403== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

valgrind --leak-check=yes ./dlist_bench

Expand Down
5 changes: 5 additions & 0 deletions samples/sample_server.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <snail.h>

int main() {
return sn_listen(3000, NULL);
}
5 changes: 0 additions & 5 deletions samples/simple_server.c

This file was deleted.

2 changes: 1 addition & 1 deletion src/server/event_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static void on_connection_callback(uv_stream_t *server, int status) {
}
}

int sn_listen(int port) {
int sn_listen(int port, sn_route_group_t *route_group) {
uv_tcp_t server;
struct sockaddr_in addr;

Expand Down
84 changes: 19 additions & 65 deletions src/server/router.c
Original file line number Diff line number Diff line change
@@ -1,82 +1,36 @@
#include <stdlib.h>
#include <string.h>
#include "../sn_common.h"
#include "snail.h"

#define MIDDLEWARE_CAP 4
#define MIDDLEWARE_EXT 4

int sn_routing_init(sn_router_t **router, sn_http_method_t method, const char *path, sn_route_handler_cb action) {
sn_router_t *new_router;
MALLOC_OR_RETURN_ERR(new_router, sn_router_t, 1)
new_router->middlewares.handlers = malloc(sizeof (sn_route_handler_cb) * MIDDLEWARE_CAP);
if (new_router->middlewares.handlers == NULL) {
free(router);
return SN_ENOMEM;
}
new_router->middlewares.size = 0;
new_router->middlewares.capacity = MIDDLEWARE_CAP;
new_router->path = path;
new_router->method = method;
new_router->action = action;
new_router->type = SN_ROUTER;
*router = new_router;
return 0;
void sn_route_handler_init(sn_route_handler_t *route_handler, sn_http_method_t method, const char *path, sn_req_handler handler) {
sn_dlist_init(&route_handler->middlewares, NULL);
route_handler->path = path;
route_handler->method = method;
route_handler->action = handler;
route_handler->type = SN_ROUTE_HANDLER;
}

int sn_routing_init_group(sn_route_group_t **route_group, const char *path) {
int error;
sn_map_t *routes;
sn_route_group_t *new_route_group;
MALLOC_OR_RETURN_ERR(new_route_group, sn_route_group_t, 1)
new_route_group->middlewares.handlers = malloc(sizeof (sn_route_handler_cb) * MIDDLEWARE_CAP);
if (new_route_group->middlewares.handlers == NULL) {
free(new_route_group);
return SN_ENOMEM;
}
error = sn_map_init(&routes, 8, NULL);
if (error != 0) {
free(new_route_group->middlewares.handlers);
free(new_route_group);
return error;
}
new_route_group->path = path;
new_route_group->middlewares.size = 0;
new_route_group->middlewares.capacity = MIDDLEWARE_CAP;
new_route_group->type = SN_ROUTER_GROUP;
*route_group = new_route_group;
return 0;
void sn_route_group_init(sn_route_group_t *route_group, const char *path) {
sn_dlist_init(&route_group->middlewares, NULL);
sn_dlist_init(&route_group->routes, (sn_data_destructor) sn_route_destroy);
route_group->path = path;
route_group->type = SN_ROUTE_GROUP;
}

int sn_routing_add_group(sn_route_group_t *route_group, sn_handler_t *handler) {
return sn_map_set(route_group->routes, handler->path, handler);
int sn_route_add_subgroup(sn_route_group_t *route_group, sn_handler_t *handler) {
return sn_dlist_push(&route_group->routes, handler);
}

int sn_routing_add_middleware(sn_handler_t *handler, sn_route_handler_cb middleware) {
if (handler->middlewares.size < handler->middlewares.capacity) {
handler->middlewares.handlers[handler->middlewares.size++] = middleware;
return 0;
}
void *ext = realloc(handler->middlewares.handlers, (sizeof (sn_route_handler_cb) * (handler->middlewares.capacity + MIDDLEWARE_EXT)));
if (ext == NULL) {
return SN_ENOMEM;
}
handler->middlewares.capacity += MIDDLEWARE_EXT;
handler->middlewares.handlers = ext;
handler->middlewares.handlers[handler->middlewares.size++] = middleware;
return 0;
int sn_route_add_middleware(sn_handler_t *handler, sn_req_handler middleware) {
return sn_dlist_push(&handler->middlewares, middleware);
}

void sn_routing_destroy(sn_handler_t *handler) {
void sn_route_destroy(sn_handler_t *handler) {
if (handler->type == SN_UNKNOWN_HANDLER) {
return;
}
if (handler->type == SN_ROUTER) {
free(handler);
return;
}
if (handler->type == SN_ROUTER_GROUP) {
sn_map_destroy(((sn_route_group_t*)handler)->routes);
sn_dlist_destroy(&handler->middlewares);
if (handler->type == SN_ROUTE_GROUP) {
sn_dlist_destroy(&((sn_route_group_t*)handler)->routes);
free(handler);
}
}
7 changes: 7 additions & 0 deletions src/sn_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
return SN_ENOMEM; \
} \

#define DELEGATE_IF_ERR(EXP) ({ \
int __err = EXP; \
if (__err != 0) { \
return __err; \
} \
}); \

SN_CONST_FN
unsigned long djb2_hash(unsigned char *str);

Expand Down
4 changes: 2 additions & 2 deletions src/sn_logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ static int min_log_level = LOG_LEVEL_DEBUG;
va_start(args, FMT); \
vfprintf(GET_OUTPUT_DEV(LEVEL), fmt, args); \
va_end(args); \
}
} \

void sn_log_set_level(int level) {
void sn_log_level(int level) {
if (level <= LOG_LEVEL_DEBUG) {
min_log_level = LOG_LEVEL_DEBUG;
return;
Expand Down
Loading

0 comments on commit c479320

Please sign in to comment.