add irc_net test
authorTero Marttila <terom@fixme.fi>
Thu, 12 Mar 2009 22:06:01 +0200
changeset 44 6bd70113e1ed
parent 43 42f5dc680930
child 45 71e65564afd2
add irc_net test
src/irc_net.c
src/irc_net.h
src/test.c
--- a/src/irc_net.c	Thu Mar 12 21:44:34 2009 +0200
+++ b/src/irc_net.c	Thu Mar 12 22:06:01 2009 +0200
@@ -95,16 +95,22 @@
     // initialize
     TAILQ_INIT(&net->channels);
 
-    // XXX: over-simplified blocking connect
-    if (info->use_ssl) {
+    if (info->raw_sock) {
+        log_info("connected using raw socket: %p", info->raw_sock);
+
+        sock = info->raw_sock;
+
+    } else if (info->use_ssl) {
         log_info("connecting to [%s]:%s using SSL", info->hostname, info->service);
 
+        // XXX: over-simplified blocking connect
         if (sock_ssl_connect(&sock, info->hostname, info->service, err))
             goto error;
 
     } else {
         log_info("connecting to [%s]:%s", info->hostname, info->service);
 
+        // XXX: over-simplified blocking connect
         if (sock_tcp_connect(&sock, info->hostname, info->service, err))
             goto error;
 
--- a/src/irc_net.h	Thu Mar 12 21:44:34 2009 +0200
+++ b/src/irc_net.h	Thu Mar 12 22:06:01 2009 +0200
@@ -30,6 +30,9 @@
 
     /** Protocol registration info */
     struct irc_conn_register_info register_info;
+
+    /** Raw socket to use, mainly for testing purposes */
+    struct sock_stream *raw_sock;
 };
 
 /**
--- a/src/test.c	Thu Mar 12 21:44:34 2009 +0200
+++ b/src/test.c	Thu Mar 12 22:06:01 2009 +0200
@@ -4,6 +4,7 @@
 #include "sock_test.h"
 #include "line_proto.h"
 #include "irc_conn.h"
+#include "irc_net.h"
 #include "log.h"
 #include "error.h"
 
@@ -20,13 +21,13 @@
 void assert_strncmp (const char *is, const char *should_be, size_t n)
 {
     if (strncmp(is, should_be, n))
-        FATAL("'%s':%d != '%s'", is, n, should_be);
+        FATAL("'%s':%u != '%s'", is, (unsigned) n, should_be);
 }
 
 void assert_strlen (const char *str, size_t n)
 {
     if (strlen(str) != n)
-        FATAL("strlen('%s') != %u", str, n);
+        FATAL("strlen('%s') != %u", str, (unsigned) n);
 }
 
 void assert_strnull (const char *str)
@@ -84,7 +85,7 @@
     assert_err(-sock_stream_read(sock, &buf, 1), ERR_READ_EOF);
 }
 
-void assert_sock_send_data (struct sock_test *sock, const char *data)
+void assert_sock_data (struct sock_test *sock, const char *data)
 {
     // get the data out
     char *buf;
@@ -130,10 +131,10 @@
     assert_sock_write(SOCK_TEST_BASE(sock), "data");
     
     // check output
-    assert_sock_send_data(sock, _write_data);
+    assert_sock_data(sock, _write_data);
 
     // check output
-    assert_sock_send_data(sock, "");
+    assert_sock_data(sock, "");
 
     // cleanup
     sock_test_destroy(sock);
@@ -231,7 +232,7 @@
     log_info("test line_proto_send");
     assert_success(-line_proto_send(lp, "foobar\r\n"));
     assert_success(-line_proto_send(lp, "quux\r\n"));
-    assert_sock_send_data(sock, "foobar\r\nquux\r\n");
+    assert_sock_data(sock, "foobar\r\nquux\r\n");
 
     // XXX: test partial writes
 
@@ -249,7 +250,7 @@
 
     (void) conn;
 
-    ctx->on_registered = true;
+    if (ctx) ctx->on_registered = true;
 
     log_debug("registered");
 }
@@ -263,7 +264,7 @@
     assert_strcmp(line->args[0], "arg0");
     assert_strnull(line->args[1]);
 
-    ctx->on_TEST = true;
+    if (ctx) ctx->on_TEST = true;
 
     log_debug("on_TEST");
 }
@@ -277,43 +278,129 @@
     {   NULL,           NULL            }
 };
 
-void test_irc_conn (void)
+struct irc_conn* setup_irc_conn (struct sock_test *sock, bool noisy, struct _test_irc_conn_ctx *ctx)
 {
-    struct sock_test *sock;
     struct irc_conn *conn;
     struct error_info err;
     struct irc_conn_register_info register_info = {
         "nick", "user", "realname"
     };
+
+    // create the irc_conn
+    assert_success(irc_conn_create(&conn, SOCK_TEST_BASE(sock), &_conn_callbacks, ctx, &err));
+
+    // test register
+    if (noisy) log_info("test irc_conn_register");
+    assert_success(irc_conn_register(conn, &register_info));
+    assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
+ 
+    // test on_register callback    
+    if (noisy) log_info("test irc_conn_callbacks.on_register");
+    sock_test_add_recv_str(sock, "001 mynick :Blaa blaa blaa\r\n");
+    if (ctx) assert(ctx->on_registered);
+    assert_strcmp(conn->nickname, "mynick");
+   
+    // ok
+    return conn;
+}
+
+void test_irc_conn (void)
+{
+    struct sock_test *sock;
+    struct irc_conn *conn;
     struct _test_irc_conn_ctx ctx = { false, false };
 
     // create the test socket
     assert((sock = sock_test_create()));
-    
-    // create the irc_conn
-    assert_success(irc_conn_create(&conn, SOCK_TEST_BASE(sock), &_conn_callbacks, &ctx, &err));
-    assert_success(irc_conn_add_cmd_handlers(conn, _conn_handlers, &ctx));
 
-    // test register
-    log_info("test irc_conn_register");
-    assert_success(irc_conn_register(conn, &register_info));
-    assert_sock_send_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
+    // setup the basic irc_conn
+    conn = setup_irc_conn(sock, true, &ctx);
     
-    // test on_register callback    
-    log_info("test irc_conn_callbacks.on_register");
-    sock_test_add_recv_str(sock, "001 mynick :Blaa blaa blaa\r\n");
-    assert(ctx.on_registered);
-    assert_strcmp(conn->nickname, "mynick");
+    // add our test handlers
+    assert_success(irc_conn_add_cmd_handlers(conn, _conn_handlers, &ctx));
 
     // test on_TEST handler
     log_info("test irc_conn.handlers");
     sock_test_add_recv_str(sock, ":foobar-prefix TEST arg0\r\n");
     assert(ctx.on_TEST);
 
+    // test PING/PONG
+    log_info("test PING/PONG");
+    sock_test_add_recv_str(sock, "PING foo\r\n");
+    assert_sock_data(sock, "PONG foo\r\n");
+
     // destroy it
     irc_conn_destroy(conn);
 }
 
+struct _test_net_ctx {
+    struct irc_chan *chan;
+
+    bool on_chan_self_join;
+};
+
+void _on_chan_self_join (struct irc_chan *chan, void *arg)
+{
+    struct _test_net_ctx *ctx = arg;
+
+    assert(chan == ctx->chan);
+    
+    ctx->on_chan_self_join = true;
+
+    log_debug("on_self_join");
+}
+
+struct irc_chan_callbacks _chan_callbacks = {
+    .on_self_join       = &_on_chan_self_join,
+};
+
+void test_irc_net (void)
+{
+    struct sock_test *sock;
+    struct irc_net *net;
+    struct irc_net_info net_info = {
+        .register_info = {
+            "nick", "user", "realname"
+        },
+    };
+    struct irc_chan *chan;
+    struct irc_chan_info chan_info = {
+        .channel        = "#test",
+    };
+    struct error_info err;
+    struct _test_net_ctx ctx = { NULL, false };
+
+    // create the test socket
+    assert((sock = sock_test_create()));
+    
+    // create the irc_net
+    net_info.raw_sock = SOCK_TEST_BASE(sock);
+    assert_success(irc_net_create(&net, &net_info, &err));
+
+    // add a channel
+    assert((chan = irc_net_add_chan(net, &chan_info)));
+    assert(!chan->state.joining && !chan->state.joined);
+    assert_success(irc_chan_add_callbacks(chan, &_chan_callbacks, &ctx));
+    ctx.chan = chan;
+    
+    // test register output
+    assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
+    
+    // registration reply
+    sock_test_add_recv_str(sock, "001 mynick :Blaa blaa blaa\r\n");
+    assert(net->conn->registered);
+    assert_strcmp(net->conn->nickname, "mynick");
+    
+    // JOIN request
+    assert(chan->state.joining);
+    assert_sock_data(sock, "JOIN #test\r\n");
+
+    // JOIN reply
+    sock_test_add_recv_str(sock, ":mynick!user@host JOIN #test\r\n");
+    assert(!chan->state.joining && chan->state.joined);
+    assert(ctx.on_chan_self_join);
+}
+
 /**
  * Test definition
  */
@@ -328,6 +415,7 @@
     {   "sock_test",    &test_sock_test     },
     {   "line_proto",   &test_line_proto    },
     {   "irc_conn",     &test_irc_conn      },
+    {   "irc_net",      &test_irc_net       },
     {   NULL,           NULL                }
 };