X-Git-Url: http://git.silc.fi/gitweb/?p=runtime.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Ftests%2Ftest_silclocalnetstream.c;fp=lib%2Fsilcutil%2Ftests%2Ftest_silclocalnetstream.c;h=010936e4606e2b1f5412fb4836937cb1ba9014df;hp=0000000000000000000000000000000000000000;hb=6643cc5ddd6c1835acffed13ffdf83c41078f8d0;hpb=7ec4fcdab215d619ab28156144a0dde26161bc62 diff --git a/lib/silcutil/tests/test_silclocalnetstream.c b/lib/silcutil/tests/test_silclocalnetstream.c new file mode 100644 index 00000000..010936e4 --- /dev/null +++ b/lib/silcutil/tests/test_silclocalnetstream.c @@ -0,0 +1,205 @@ +/* SILC Local Net Stream API tests */ + +#include "silcruntime.h" + +SilcSchedule schedule; + +typedef struct { + SilcFSM fsm; + SilcFSMEventStruct sema; + SilcFSMThreadStruct thread; + SilcNetListener server; + SilcStream client_stream; + SilcResult client_status; + SilcStream server_stream; + SilcResult server_status; + SilcBool success; +} *Foo; + +SILC_FSM_STATE(test_st_start); +SILC_FSM_STATE(test_st_second); +SILC_FSM_STATE(test_st_finish); + +SILC_FSM_STATE(test_st_connect); +SILC_FSM_STATE(test_st_connected); + +static void test_accept_connection(SilcResult status, SilcStream stream, + void *context) +{ + Foo f = context; + SILC_LOG_DEBUG(("Accepted new connection")); + f->client_status = status; + f->client_stream = stream; + SILC_FSM_EVENT_SIGNAL(&f->sema); +} + +static void test_connected(SilcResult status, SilcStream stream, + void *context) +{ + Foo f = context; + SILC_LOG_DEBUG(("Connected to server")); + f->server_status = status; + f->server_stream = stream; + SILC_FSM_CALL_CONTINUE(&f->thread); +} + +SILC_FSM_STATE(test_st_connect) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("test_st_connect")); + SILC_LOG_DEBUG(("Connecting to server")); + + silc_fsm_next(fsm, test_st_connected); + SILC_FSM_CALL(silc_local_net_connect("local_net", + silc_fsm_get_schedule(fsm), + test_connected, f)); +} + +SILC_FSM_STATE(test_st_connected) +{ + Foo f = fsm_context; + const char *host, *ip; + SilcUInt16 port; + + SILC_LOG_DEBUG(("test_st_connected")); + + if (f->server_status != SILC_OK) { + SILC_LOG_DEBUG(("Creating connection failed")); + return SILC_FSM_FINISH; + } + + silc_socket_stream_get_info(f->server_stream, NULL, &host, &ip, &port); + SILC_LOG_DEBUG(("Connected to server %s, %s:%d", host, ip, port)); + + return SILC_FSM_FINISH; +} + +SILC_FSM_STATE(test_st_start) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("test_st_start")); + + SILC_LOG_DEBUG(("Creating local network listener")); + f->server = silc_local_net_create_listener("local_net", + silc_fsm_get_schedule(fsm), + test_accept_connection, f); + if (!f->server) { + /** Creating network listener failed */ + SILC_LOG_DEBUG(("Listener creation failed")); + silc_fsm_next(fsm, test_st_finish); + return SILC_FSM_CONTINUE; + } + + /* Create thread to connect to the listener */ + silc_fsm_thread_init(&f->thread, fsm, f, NULL, NULL, FALSE); + silc_fsm_start(&f->thread, test_st_connect); + + /** Start waiting connection */ + SILC_LOG_DEBUG(("Start waiting for incoming connections")); + silc_fsm_event_init(&f->sema, fsm); + silc_fsm_next(fsm, test_st_second); + return SILC_FSM_CONTINUE; +} + +SILC_FSM_STATE(test_st_second) +{ + Foo f = fsm_context; + const char *ip, *host; + SilcUInt16 port; + + SILC_LOG_DEBUG(("test_st_second")); + + SILC_FSM_EVENT_WAIT(&f->sema); + + if (f->client_status != SILC_OK) { + /** Accepting new connection failed */ + SILC_LOG_DEBUG(("Accepting failed %d", f->client_status)); + silc_fsm_next(fsm, test_st_finish); + return SILC_FSM_CONTINUE; + } + + silc_socket_stream_get_info(f->client_stream, NULL, &host, &ip, &port); + SILC_LOG_DEBUG(("Accepted new connection %s, %s:%d", host, ip, port)); + + /** Wait thread to terminate */ + f->success = TRUE; + silc_fsm_next(fsm, test_st_finish); + SILC_FSM_THREAD_WAIT(&f->thread); +} + +SILC_FSM_STATE(test_st_finish) +{ + Foo f = fsm_context; + + SILC_LOG_DEBUG(("test_st_finish")); + + if (f->server_stream) { + silc_stream_close(f->server_stream); + silc_stream_destroy(f->server_stream); + } + if (f->client_stream) { + silc_stream_close(f->client_stream); + silc_stream_destroy(f->client_stream); + } + + SILC_LOG_DEBUG(("Closing network listener")); + if (f->server) + silc_local_net_close_listener(f->server); + + SILC_LOG_DEBUG(("Finish machine")); + return SILC_FSM_FINISH; +} + +static void destructor(SilcFSM fsm, void *fsm_context, + void *destructor_context) +{ + SILC_LOG_DEBUG(("FSM destructor, stopping scheduler")); + silc_fsm_free(fsm); + silc_schedule_stop(schedule); +} + +int main(int argc, char **argv) +{ + SilcBool success = FALSE; + SilcFSM fsm; + Foo f; + + if (argc > 1 && !strcmp(argv[1], "-d")) { + silc_log_debug(TRUE); + silc_log_debug_hexdump(TRUE); + silc_log_set_debug_string("*net*,*stream*,*errno*"); + } + + SILC_LOG_DEBUG(("Allocating scheduler")); + schedule = silc_schedule_init(0, NULL, NULL, NULL); + + f = silc_calloc(1, sizeof(*f)); + if (!f) + goto err; + + SILC_LOG_DEBUG(("Allocating FSM context")); + fsm = silc_fsm_alloc(f, destructor, NULL, schedule); + if (!fsm) + goto err; + silc_fsm_start(fsm, test_st_start); + f->fsm = fsm; + + SILC_LOG_DEBUG(("Running scheduler")); + silc_schedule(schedule); + + if (!f->success) + goto err; + + silc_schedule_uninit(schedule); + silc_free(f); + + success = TRUE; + + err: + SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE")); + fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE"); + + return !success; +}