aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-11-11 00:37:37 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-11-11 00:37:37 +0100
commitde3532bd6b685c66015202a48d53e1b8fa4900f5 (patch)
treecbea21d0504d25bb7df454768fa3ff6e8ff81db2
parent980858186149651df5543b6fc99a4f7db0cdd089 (diff)
Add tests for transport
-rw-r--r--src/transport/CMakeLists.txt2
-rw-r--r--src/transport/test/CMakeLists.txt3
-rw-r--r--src/transport/test/test.c216
3 files changed, 221 insertions, 0 deletions
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 <transport.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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;
+}