--- 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);
}