add set_log_level function, and add --debug/--quiet options to test
authorTero Marttila <terom@fixme.fi>
Thu, 26 Mar 2009 22:03:20 +0200
changeset 73 2780a73c71f3
parent 72 43084f103c2a
child 74 11ec458d1cbf
add set_log_level function, and add --debug/--quiet options to test
src/irc_chan.c
src/irc_net.c
src/log.c
src/log.h
src/test.c
--- a/src/irc_chan.c	Thu Mar 26 21:46:10 2009 +0200
+++ b/src/irc_chan.c	Thu Mar 26 22:03:20 2009 +0200
@@ -61,8 +61,6 @@
         chan->joining = false;
         chan->joined = true;
 
-        log_info("joined channel: %s", chan->info.channel);
-        
         // invoke callback
         IRC_CHAN_INVOKE_CALLBACK(chan, on_self_join);
 
--- a/src/irc_net.c	Thu Mar 26 21:46:10 2009 +0200
+++ b/src/irc_net.c	Thu Mar 26 22:03:20 2009 +0200
@@ -189,19 +189,19 @@
     LIST_INIT(&net->users);
 
     if (info->raw_sock) {
-        log_info("connected using raw socket: %p", info->raw_sock);
+        log_debug("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);
+        log_debug("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);
+        log_debug("connecting to [%s]:%s", info->hostname, info->service);
 
         // XXX: over-simplified blocking connect
         if (sock_tcp_connect(&sock, info->hostname, info->service, err))
@@ -218,7 +218,7 @@
         goto error;
 
     // register
-    log_info("connected, registering");
+    log_debug("connected, registering");
 
     if ((ERROR_CODE(err) = irc_conn_register(net->conn, &info->register_info)))
         goto error;
--- a/src/log.c	Thu Mar 26 21:46:10 2009 +0200
+++ b/src/log.c	Thu Mar 26 22:03:20 2009 +0200
@@ -4,6 +4,11 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+/**
+ * The global log level
+ */
+static enum log_level _log_level = LOG_LEVEL_DEFAULT;
+
 #define _LOG_LEVEL_NAME(ll) case LOG_ ## ll: return #ll;
 const char *log_level_name (enum log_level level)
 {
@@ -17,7 +22,7 @@
     }
 }
 
-/*
+/**
  * Output the "[TYPE] FUNC: " header
  */
 void _log_header (enum log_level level, const char *func)
@@ -28,6 +33,10 @@
 void log_msg (enum log_level level, const char *func, const char *format, ...)
 {
     va_list vargs;
+
+    // filter out?
+    if (level < _log_level)
+        return;
     
     _log_header(level, func);
     
@@ -40,10 +49,20 @@
     printf("\n");
 }
 
+void set_log_level (enum log_level level)
+{
+    // meep meep
+    _log_level = level;
+}
+
 void _log_err (enum log_level level, err_t err, const char *func, const char *format, ...)
 {
     va_list vargs;
 
+    // filter out?
+    if (level < _log_level)
+        return;
+ 
     // header
     _log_header(level, func);
     
@@ -60,6 +79,10 @@
 {
     va_list vargs;
 
+    // filter out?
+    if (level < _log_level)
+        return;
+ 
     // header
     _log_header(level, func);
     
--- a/src/log.h	Thu Mar 26 21:46:10 2009 +0200
+++ b/src/log.h	Thu Mar 26 22:03:20 2009 +0200
@@ -21,12 +21,22 @@
 };
 
 /**
+ * The default log level
+ */
+#define LOG_LEVEL_DEFAULT LOG_INFO
+
+/**
  * Log a message with the given level
  */
 void log_msg (enum log_level level, const char *func, const char *format, ...)
     __attribute__ ((format (printf, 3, 4)));
 
 /**
+ * Set the current log level to filter out messages below the given level
+ */
+void set_log_level (enum log_level level);
+
+/**
  * Shorthand for log_msg
  */
 #define log_debug(...) log_msg(LOG_DEBUG, __func__, __VA_ARGS__)
--- a/src/test.c	Thu Mar 26 21:46:10 2009 +0200
+++ b/src/test.c	Thu Mar 26 22:03:20 2009 +0200
@@ -10,6 +10,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <getopt.h>
 #include <assert.h>
 #include <ctype.h>
 
@@ -514,8 +515,9 @@
     /** The channel we're supposed to be testing */
     struct irc_chan *chan;
     
-    /** on_self_join callback called */
-    bool on_chan_self_join;
+    /** Flags for callbacks called*/
+    bool on_chan_self_join, on_chan_join;
+
 };
 
 void _on_chan_self_join (struct irc_chan *chan, void *arg)
@@ -529,8 +531,22 @@
     log_debug("on_self_join");
 }
 
+void _on_chan_join (struct irc_chan *chan, const struct irc_nm *source, void *arg)
+{
+    struct test_chan_ctx *ctx = arg;
+
+    assert(chan == ctx->chan);
+
+    // XXX: verify source
+
+    ctx->on_chan_join = true;
+
+    log_debug("on_join");
+}
+
 struct irc_chan_callbacks _chan_callbacks = {
     .on_self_join       = &_on_chan_self_join,
+    .on_join            = &_on_chan_join,
 };
 
 /**
@@ -727,6 +743,31 @@
     irc_net_destroy(net);
 }
 
+void test_irc_chan_user_join (void)
+{
+    struct test_chan_ctx ctx;
+    struct sock_test *sock = setup_sock_test();
+    struct irc_net *net = setup_irc_net(sock);
+    struct irc_chan *chan = setup_irc_chan(sock, net, &ctx);
+
+    // RPL_NAMREPLY
+    test_sock_push(sock, "353 mynick = #test :mynick userA +userB @userC\r\n");
+
+    check_chan_user(chan, "mynick");
+    check_chan_user(chan, "userA");
+    check_chan_user(chan, "userB");
+    check_chan_user(chan, "userC");
+
+    // have a user join
+    log_info("test irc_chan_on_JOIN");
+    test_sock_push(sock, ":newuser!someone@somewhere JOIN #test\r\n");
+    assert(ctx.on_chan_join);
+    check_chan_user(chan, "newuser");
+
+    // cleanup
+    irc_net_destroy(net);
+}
+
 /**
  * Test definition
  */
@@ -745,26 +786,83 @@
     {   "irc_net",              &test_irc_net               },
     {   "irc_chan_add_offline", &test_irc_chan_add_offline  },
     {   "irc_chan_namreply",    &test_irc_chan_namreply     },
+    {   "irc_chan_user_join",   &test_irc_chan_user_join    },
     {   NULL,                   NULL                        }
 };
 
+/**
+ * Command-line option codes
+ */
+enum option_code {
+    OPT_HELP            = 'h',
+    OPT_DEBUG           = 'd',
+    OPT_QUIET           = 'q',
+    
+    /** Options without short names */
+    _OPT_EXT_BEGIN      = 0x00ff,
+
+};
+
+/**
+ * Command-line option definitions
+ */
+static struct option options[] = {
+    {"help",            0,  NULL,   OPT_HELP        },
+    {"debug",           0,  NULL,   OPT_DEBUG       },
+    {"quiet",           0,  NULL,   OPT_QUIET       },
+    {0,                 0,  0,      0               },
+};
+
+/**
+ * Display --help output on stdout
+ */
+static void usage (const char *exe) 
+{
+    printf("Usage: %s [OPTIONS]\n", exe);
+    printf("\n");
+    printf(" --help / -h            display this message\n");
+    printf(" --debug / -d           display DEBUG log messages\n");
+    printf(" --quiet / -q           supress INFO log messages\n");
+}
+
 int main (int argc, char **argv)
 {
-    const char *filter;
     struct test *test;
+    size_t test_count = 0;
     
-    if (argc == 1) {
-        // no arguments
-        filter = NULL;
+    int opt, option_index;
+    const char *filter = NULL;
 
-    } else if (argc == 2) {
-        // filter
-        filter = argv[1];
-        
-        log_info("only running tests: %s", filter);
+    // parse options
+    while ((opt = getopt_long(argc, argv, "hdq", options, &option_index)) != -1) {
+        switch (opt) {
+            case OPT_HELP:
+                usage(argv[0]);
+                exit(EXIT_SUCCESS);
+            
+            case OPT_DEBUG:
+                set_log_level(LOG_DEBUG);
+                break;
 
-    } else {
-        FATAL("too many arguments");
+            case OPT_QUIET:
+                set_log_level(LOG_WARN);
+                break;
+            
+            case '?':
+                usage(argv[0]);
+                exit(EXIT_FAILURE);
+        }
+    }
+
+    if (optind < argc) {
+        if (optind == argc - 1) {
+            // filter
+            filter = argv[optind];
+            
+            log_info("only running tests: %s", filter);
+        } else {
+            FATAL("too many arguments");
+        }
     }
 
     // run tests
@@ -773,9 +871,14 @@
             continue;
 
         log_info("Running test: %s", test->name);
-
+        
+        test_count++;
         test->func();
     }
 
-    log_info("done");
+    // no tests run?
+    if (test_count == 0)
+        FATAL("no tests run");
+
+    log_info("done, ran %zu tests", test_count);
 }