diff options
Diffstat (limited to 'src/test/test_options.c')
-rw-r--r-- | src/test/test_options.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/test/test_options.c b/src/test/test_options.c new file mode 100644 index 0000000000..737f658e2c --- /dev/null +++ b/src/test/test_options.c @@ -0,0 +1,170 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2013, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#define CONFIG_PRIVATE +#include "or.h" +#include "confparse.h" +#include "config.h" +#include "test.h" + +typedef struct { + int severity; + uint32_t domain; + char *msg; +} logmsg_t; + +static smartlist_t *messages = NULL; + +static void +log_cback(int severity, uint32_t domain, const char *msg) +{ + logmsg_t *x = tor_malloc(sizeof(*x)); + x->severity = severity; + x->domain = domain; + x->msg = tor_strdup(msg); + if (!messages) + messages = smartlist_new(); + smartlist_add(messages, x); +} + +static void +setup_log_callback(void) +{ + log_severity_list_t lst; + memset(&lst, 0, sizeof(lst)); + lst.masks[LOG_ERR - LOG_ERR] = ~0; + lst.masks[LOG_WARN - LOG_ERR] = ~0; + lst.masks[LOG_NOTICE - LOG_ERR] = ~0; + add_callback_log(&lst, log_cback); +} + +static char * +dump_logs(void) +{ + smartlist_t *msgs; + char *out; + if (! messages) + return tor_strdup(""); + msgs = smartlist_new(); + SMARTLIST_FOREACH_BEGIN(messages, logmsg_t *, x) { + smartlist_add_asprintf(msgs, "[%s] %s", + log_level_to_string(x->severity), x->msg); + } SMARTLIST_FOREACH_END(x); + out = smartlist_join_strings(msgs, "", 0, NULL); + SMARTLIST_FOREACH(msgs, char *, cp, tor_free(cp)); + smartlist_free(msgs); + return out; +} + +static void +clear_log_messages(void) +{ + if (!messages) + return; + SMARTLIST_FOREACH(messages, logmsg_t *, m, + { tor_free(m->msg); tor_free(m); }); + smartlist_free(messages); + messages = NULL; +} + +static void +test_options_validate_impl(const char *configuration, + const char *expect_errmsg, + int expect_log_severity, + const char *expect_log) +{ + or_options_t *opt = options_new(); + or_options_t *dflt; + config_line_t *cl=NULL; + char *msg=NULL; + int r; + opt->command = CMD_RUN_TOR; + options_init(opt); + + dflt = config_dup(&options_format, opt); + clear_log_messages(); + + r = config_get_lines(configuration, &cl, 1); + tt_int_op(r, ==, 0); + + r = config_assign(&options_format, opt, cl, 0, 0, &msg); + tt_int_op(r, ==, 0); + + r = options_validate(NULL, opt, dflt, 0, &msg); + if (expect_errmsg && !msg) { + TT_DIE(("Expected error message <%s> from <%s>, but got none.", + expect_errmsg, configuration)); + } else if (expect_errmsg && !strstr(msg, expect_errmsg)) { + TT_DIE(("Expected error message <%s> from <%s>, but got <%s>.", + expect_errmsg, configuration, msg)); + } else if (!expect_errmsg && msg) { + TT_DIE(("Expected no error message from <%s> but got <%s>.", + configuration, msg)); + } + tt_int_op((r == 0), ==, (msg == NULL)); + + if (expect_log) { + int found = 0; + if (messages) { + SMARTLIST_FOREACH_BEGIN(messages, logmsg_t *, m) { + if (m->severity == expect_log_severity && + strstr(m->msg, expect_log)) { + found = 1; + break; + } + } SMARTLIST_FOREACH_END(m); + } + if (!found) { + tor_free(msg); + msg = dump_logs(); + TT_DIE(("Expected log message [%s] %s from <%s>, but got <%s>.", + log_level_to_string(expect_log_severity), expect_log, + configuration, msg)); + } + } + + done: + config_free_lines(cl); + or_options_free(opt); + or_options_free(dflt); + tor_free(msg); + clear_log_messages(); +} + +#define WANT_ERR(config, msg) \ + test_options_validate_impl((config), (msg), 0, NULL) +#define WANT_LOG(config, severity, msg) \ + test_options_validate_impl((config), NULL, (severity), (msg)) +#define WANT_ERR_LOG(config, msg, severity, logmsg) \ + test_options_validate_impl((config), (msg), (severity), (logmsg)) +#define OK(config) \ + test_options_validate_impl((config), NULL, 0, NULL) + +static void +test_options_validate(void *arg) +{ + (void)arg; + setup_log_callback(); + + WANT_ERR("ExtORPort 500000", "Invalid ExtORPort"); + + WANT_ERR_LOG("ServerTransportOptions trebuchet", + "ServerTransportOptions did not parse", + LOG_WARN, "Too few arguments"); + OK("ServerTransportOptions trebuchet sling=snappy"); + OK("ServerTransportOptions trebuchet sling="); + WANT_ERR_LOG("ServerTransportOptions trebuchet slingsnappy", + "ServerTransportOptions did not parse", + LOG_WARN, "\"slingsnappy\" is not a k=v"); + + clear_log_messages(); + return; +} + +struct testcase_t options_tests[] = { + { "validate", test_options_validate, TT_FORK, NULL, NULL }, + END_OF_TESTCASES +}; + |