From de3532bd6b685c66015202a48d53e1b8fa4900f5 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Fri, 11 Nov 2022 00:37:37 +0100 Subject: Add tests for transport --- src/transport/CMakeLists.txt | 2 + src/transport/test/CMakeLists.txt | 3 + src/transport/test/test.c | 216 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 src/transport/test/CMakeLists.txt create mode 100644 src/transport/test/test.c (limited to 'src') diff --git a/src/transport/CMakeLists.txt b/src/transport/CMakeLists.txt index 8f05c31..b903a81 100644 --- a/src/transport/CMakeLists.txt +++ b/src/transport/CMakeLists.txt @@ -8,3 +8,5 @@ endif() add_library(transport ${src}) target_include_directories(transport PUBLIC "inc" PRIVATE "privinc") +enable_testing() +add_subdirectory(test) diff --git a/src/transport/test/CMakeLists.txt b/src/transport/test/CMakeLists.txt new file mode 100644 index 0000000..17923dc --- /dev/null +++ b/src/transport/test/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(test "test.c") +target_link_libraries(test PRIVATE transport) +add_test(NAME test COMMAND test) diff --git a/src/transport/test/test.c b/src/transport/test/test.c new file mode 100644 index 0000000..2bb8e7f --- /dev/null +++ b/src/transport/test/test.c @@ -0,0 +1,216 @@ +#include +#include +#include +#include +#include +#include + +struct client +{ + bool connected, received; + const char *expected; + struct transport_handle h; + + struct io + { + FILE *in, *out; + } io; +}; + +struct server +{ + struct transport_handle h; + struct io io; + const char *expected; + bool received; +}; + +static int io_write(const void *const buf, const size_t n, + const struct io *const io) +{ + FILE *const f = io->out; + const size_t w = fwrite(buf, 1, n, f); + + return ferror(f) ? -1 : w; +} + +static int io_read(void *const buf, const size_t n, + const struct io *const io) +{ + FILE *const f = io->in; + const size_t w = fread(buf, 1, n, f); + + return ferror(f) ? -1 : w; +} + +static int client_write(const void *const buf, const size_t n, void *const arg) +{ + struct client *const c = arg; + + return io_write(buf, n, &c->io); +} + +static int client_read(void *const buf, const size_t n, void *const arg) +{ + struct client *const c = arg; + + return io_read(buf, n, &c->io); +} + +static void client_received(const struct transport_event *const ev, + void *const arg) +{ + struct client *const c = arg; + + if (ev->common.type == TRANSPORT_EVENT_TYPE_CONNECT) + c->connected = true; + else if (ev->common.type == TRANSPORT_EVENT_TYPE_DATA) + { + const struct transport_event_data *const d = &ev->u.data; + + if (!strncmp(d->buf, c->expected, d->n)) + c->received = true; + } +} + +static int server_write(const void *const buf, const size_t n, void *const arg) +{ + struct server *const s = arg; + + return io_write(buf, n, &s->io); +} + +static int server_read(void *const buf, const size_t n, void *const arg) +{ + struct server *const s = arg; + + return io_read(buf, n, &s->io); +} + +static void server_received(const struct transport_event *const ev, + void *const arg) +{ + struct server *const s = arg; + + if (ev->common.type == TRANSPORT_EVENT_TYPE_DATA) + { + const struct transport_event_data *const d = &ev->u.data; + + if (!strncmp(d->buf, s->expected, d->n)) + s->received = true; + } +} + +static int loop(struct server *const s, struct client *const c) +{ + if (transport_update(&s->h)) + return -1; + + if (!freopen("client", "w+b", s->io.in)) + return -1; + + rewind(s->io.out); + + if (transport_update(&c->h)) + return -1; + + if (!freopen("server", "w+b", c->io.in)) + return -1; + + rewind(c->io.out); + + return 0; +} + +int main(void) +{ + int ret = EXIT_FAILURE; + FILE *const cf = fopen("client", "w+b"), *sf = fopen("server", "w+b"); + + if (!cf) + { + perror("fopen(3) client"); + goto end; + } + else if (!sf) + { + perror("fopen(3) server"); + goto end; + } + + struct client c = + { + .h = + { + .cfg = + { + .arg = &c, + .read = client_read, + .write = client_write, + .received = client_received + } + }, + + .io = + { + .in = sf, + .out = cf + }, + + .expected = "hi there!" + }; + + struct server s = + { + .h = + { + .cfg = + { + .arg = &s, + .read = server_read, + .write = server_write, + .received = server_received, + } + }, + + .io = + { + .in = cf, + .out = sf + }, + + .expected = "hello" + }; + + if (transport_connect(&c.h)) + goto end; + + while (!c.connected) + if (loop(&s, &c)) + goto end; + + if (transport_send(&c.h, s.expected, strlen(s.expected))) + goto end; + + while (!s.received) + if (loop(&s, &c)) + goto end; + + if (transport_send(&s.h, c.expected, strlen(c.expected))) + goto end; + + while (!c.received) + if (loop(&s, &c)) + goto end; + + ret = EXIT_SUCCESS; + +end: + if (cf) + fclose(cf); + + if (sf) + fclose(sf); + + return ret; +} -- cgit v1.2.3