add irc_net_error, and improve test_irc_net to cover it as well
authorTero Marttila <terom@fixme.fi>
Thu, 12 Mar 2009 23:05:54 +0200
changeset 46 0c13bca53ae1
parent 45 71e65564afd2
child 47 7d4094eb3117
add irc_net_error, and improve test_irc_net to cover it as well
src/irc_net.c
src/sock_test.c
src/sock_test.h
src/test.c
--- a/src/irc_net.c	Thu Mar 12 22:50:08 2009 +0200
+++ b/src/irc_net.c	Thu Mar 12 23:05:54 2009 +0200
@@ -4,34 +4,57 @@
 #include <stdlib.h>
 #include <string.h>
 
+/**
+ * Something happaned which caused our irc_conn to fail. Destroy it, and recover. XXX: somehow
+ */
+static void irc_net_error (struct irc_net *net, struct error_info *err)
+{
+    struct irc_chan *chan = NULL;
+
+    // log an error
+    log_err_info(err, "irc_conn failed");
+
+    // destroy connection and set NULL
+    irc_conn_destroy(net->conn);
+    net->conn = NULL;
+
+    // update channel state
+    TAILQ_FOREACH(chan, &net->channels, node) {
+        // XXX: notify channel somehow
+    }
+
+    // XXX: reconnect?
+}
+
+/**
+ * Our irc_conn has registered. Join our channels
+ */
 static void irc_net_conn_registered (struct irc_conn *conn, void *arg)
 {
     struct irc_net *net = arg;
     struct irc_chan *chan = NULL;
-    err_t err;
+    struct error_info err;
 
     (void) conn;
 
     // join our channels
     TAILQ_FOREACH(chan, &net->channels, node) {
-        if ((err = irc_chan_join(chan)))
-            // XXX: fuck...
-            FATAL_ERR(err, "irc_chan_join failed");
+        if ((ERROR_CODE(&err) = irc_chan_join(chan)))
+            // XXX: this should be some kind of irc_chan_error instead
+            irc_net_error(net, &err);
     }
 }
 
+/**
+ * Our irc_conn has spontaneously failed, destroy it
+ */
 static void irc_net_conn_error (struct irc_conn *conn, struct error_info *err, void *arg)
 {
     struct irc_net *net = arg;
-    
-    // log an error
-    log_err_info(err, "irc_conn failed");
 
-    // destroy and set NULL
-    irc_conn_destroy(conn);
-    net->conn = NULL;
-
-    // XXX: reconnect?
+    (void) conn;
+    
+    irc_net_error(net, err);
 }
 
 /**
@@ -204,6 +227,5 @@
 
     // no such channel
     return NULL;
-
 }
 
--- a/src/sock_test.c	Thu Mar 12 22:50:08 2009 +0200
+++ b/src/sock_test.c	Thu Mar 12 23:05:54 2009 +0200
@@ -206,6 +206,18 @@
         sock->eof = true;
 }
 
+void sock_test_notify_events (struct sock_test *sock)
+{
+    // notify if events are enabled
+    if (sock->ev_mask) {
+        // zero mask
+        int mask = sock->ev_mask;
+        sock->ev_mask = 0;
+
+        sock_stream_invoke_callbacks(SOCK_TEST_BASE(sock), mask);
+    }
+}
+
 void sock_test_add_recv_vec (struct sock_test *sock, struct io_vec new_vec)
 {
     struct io_buf *buf = &sock->recv_buf;
@@ -215,14 +227,9 @@
     
     // copy    
     *(buf->write_vec++) = new_vec;
-
-    // notify events?
-    if (sock->ev_mask) {
-        int mask = sock->ev_mask;
-        sock->ev_mask = 0;
-
-        sock_stream_invoke_callbacks(SOCK_TEST_BASE(sock), mask);
-    }
+    
+    // notify
+    sock_test_notify_events(sock);
 }
 
 void sock_test_add_recv_str (struct sock_test *sock, const char *str)
@@ -234,6 +241,13 @@
     sock_test_add_recv_vec(sock, vec);
 }
 
+void sock_test_set_recv_eof (struct sock_test *sock)
+{
+    sock->eof = true;
+
+    sock_test_notify_events(sock);
+}
+
 void sock_test_get_send_data (struct sock_test *sock, char **buf_ptr, size_t *len_ptr)
 {
     struct io_buf *buf = &sock->send_buf;
--- a/src/sock_test.h	Thu Mar 12 22:50:08 2009 +0200
+++ b/src/sock_test.h	Thu Mar 12 23:05:54 2009 +0200
@@ -99,6 +99,11 @@
 void sock_test_add_recv_str (struct sock_test *sock, const char *str);
 
 /**
+ * Set EOF on recv, and trigger events.
+ */
+void sock_test_set_recv_eof (struct sock_test *sock);
+
+/**
  * Get the send buffer contents as a single string, free() after use if you care about that.
  *
  * Clears the send buffer, so this doesn't return the same data twice.
--- a/src/test.c	Thu Mar 12 22:50:08 2009 +0200
+++ b/src/test.c	Thu Mar 12 23:05:54 2009 +0200
@@ -378,6 +378,7 @@
     assert_success(irc_net_create(&net, &net_info, &err));
 
     // add a channel
+    log_info("test offline irc_net_add_chan");
     assert((chan = irc_net_add_chan(net, &chan_info)));
     assert(!chan->joining && !chan->joined);
     assert_success(irc_chan_add_callbacks(chan, &_chan_callbacks, &ctx));
@@ -387,18 +388,26 @@
     assert_sock_data(sock, "NICK nick\r\nUSER user 0 * realname\r\n");
     
     // registration reply
+    log_info("test irc_conn_on_RPL_WELCOME");
     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
+    log_info("test irc_net_conn_registered -> irc_chan_join");
     assert(chan->joining);
     assert_sock_data(sock, "JOIN #test\r\n");
 
     // JOIN reply
+    log_info("test irc_chan_on_JOIN");
     sock_test_add_recv_str(sock, ":mynick!user@host JOIN #test\r\n");
     assert(!chan->joining && chan->joined);
     assert(ctx.on_chan_self_join);
+
+    // test errors by setting EOF
+    log_info("test irc_net_error");
+    sock_test_set_recv_eof(sock);
+    assert(net->conn == NULL);
 }
 
 /**
@@ -434,4 +443,6 @@
 
         test->func();
     }
+
+    log_info("done");
 }