Add tests for transport
This commit is contained in:
parent
9e1f1069cc
commit
02febc7367
|
@ -8,3 +8,5 @@ endif()
|
|||
|
||||
add_library(transport ${src})
|
||||
target_include_directories(transport PUBLIC "inc" PRIVATE "privinc")
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
add_executable(test "test.c")
|
||||
target_link_libraries(test PRIVATE transport)
|
||||
add_test(NAME test COMMAND test)
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue