#include "cs_config.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include "util/neo_misc.h"
#include "util/neo_err.h"
#include "util/neo_net.h"
#include "util/ulist.h"
#include "util/neo_rand.h"
#define TEST_PORT 46032
#define COUNT 10000
typedef struct _rand_thing {
int is_num;
int n;
char *s;
} RAND_THING;
NEOERR *client_proc(int port, ULIST *stuff)
{
NEOERR *err;
NSOCK *nsock;
int x;
RAND_THING *thing;
sleep(1);
ne_warn("[c] Connecting to port %d", port);
err = ne_net_connect(&nsock, "localhost", port, 10, 10);
if (err) return nerr_pass(err);
ne_warn("[c] Connected.");
do
{
err = ne_net_write_int(nsock, uListLength(stuff));
if (err) break;
for (x = 0; x < uListLength(stuff); x++)
{
err = uListGet(stuff, x, (void *)&thing);
if (err) break;
if (thing->is_num)
{
err = ne_net_write_int(nsock, thing->n);
/* ne_warn("[c] Sending %d", thing->n); */
}
else
{
err = ne_net_write_str(nsock, thing->s);
/* ne_warn("[c] Sending %s", thing->s); */
}
if (err) break;
}
} while (0);
ne_net_close(&nsock);
return nerr_pass(err);
}
NEOERR *server_proc(int port, ULIST *stuff)
{
NEOERR *err;
int server;
NSOCK *nsock;
int x, i;
RAND_THING *thing;
char *s;
ne_warn("[s] Listening on port %d", port);
err = ne_net_listen(port, &server);
if (err) return nerr_pass(err);
err = ne_net_accept(&nsock, server, 10);
if (err) return nerr_pass(err);
ne_warn("[s] Connection.");
do {
err = ne_net_read_int(nsock, &x);
if (err) break;
if (x != uListLength(stuff))
{
err = nerr_raise(NERR_ASSERT, "Incoming length is not equal to expected length: %d != %d", x, uListLength(stuff));
break;
}
for (x = 0; x < uListLength(stuff); x++)
{
err = uListGet(stuff, x, (void *)&thing);
if (err) break;
if (thing->is_num)
{
err = ne_net_read_int(nsock, &i);
if (err) break;
/* ne_warn("[s] Received %d", i); */
if (thing->n != i)
{
err = nerr_raise(NERR_ASSERT, "Incoming %d number is not equal to expected: %d != %d", x, i, thing->n);
break;
}
}
else
{
err = ne_net_read_str_alloc(nsock, &s, NULL);
if (err) break;
/* ne_warn("[s] Received %s", s); */
if (strcmp(s, thing->s))
{
err = nerr_raise(NERR_ASSERT, "Incoming %d string is not equal to expected: '%s' != '%s'", x, s, thing->s);
break;
}
free(s);
}
printf("\rs");
}
} while (0);
ne_net_close(&nsock);
return nerr_pass(err);
}
NEOERR *run_test(void)
{
NEOERR *err;
ULIST *stuff;
char word[64000];
RAND_THING *thing;
pid_t child;
int x;
ne_warn("starting net_test");
ne_warn("generating random list");
err = uListInit(&stuff, COUNT, 0);
if (err) return nerr_pass(err);
for (x = 0; x < COUNT; x++)
{
thing = (RAND_THING *) calloc(1, sizeof(RAND_THING));
if (neo_rand(100) > 50)
{
thing->is_num = 1;
thing->n = neo_rand(1000000);
}
else
{
neo_rand_word(word, sizeof(word));
thing->s = strdup(word);
}
err = uListAppend(stuff, thing);
if (err) return nerr_pass(err);
}
child = fork();
if (!child)
{
/* child */
return nerr_pass(client_proc(TEST_PORT, stuff));
}
/* parent */
err = server_proc(TEST_PORT, stuff);
if (!err) waitpid(child, NULL, 0);
return nerr_pass(err);
}
int main(int argc, char **argv)
{
NEOERR *err;
nerr_init();
err = run_test();
if (err)
{
nerr_log_error(err);
return -1;
}
return 0;
}