Add tests for transport

This commit is contained in:
Xavier Del Campo Romero 2022-11-11 00:37:37 +01:00
parent 9808581861
commit de3532bd6b
3 changed files with 221 additions and 0 deletions

View File

@ -8,3 +8,5 @@ endif()
add_library(transport ${src})
target_include_directories(transport PUBLIC "inc" PRIVATE "privinc")
enable_testing()
add_subdirectory(test)

View File

@ -0,0 +1,3 @@
add_executable(test "test.c")
target_link_libraries(test PRIVATE transport)
add_test(NAME test COMMAND test)

216
src/transport/test/test.c Normal file
View File

@ -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;
}