diff options
-rw-r--r-- | src/app/config/config.c | 8 | ||||
-rw-r--r-- | src/app/config/config.h | 6 | ||||
-rw-r--r-- | src/test/test_options_act.c | 95 |
3 files changed, 104 insertions, 5 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c index e0a334c797..8c5a53209c 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -862,8 +862,6 @@ static void options_clear_cb(const config_mgr_t *mgr, void *opts); static setopt_err_t options_validate_and_set(const or_options_t *old_options, or_options_t *new_options, char **msg_out); -struct log_transaction_t; -static void options_rollback_log_transaction(struct log_transaction_t *xn); struct listener_transaction_t; static void options_rollback_listener_transaction( struct listener_transaction_t *xn); @@ -1801,7 +1799,7 @@ typedef struct log_transaction_t { * On failure return NULL and write a message into a newly allocated string in * *<b>msg_out</b>. **/ -static log_transaction_t * +STATIC log_transaction_t * options_start_log_transaction(const or_options_t *old_options, char **msg_out) { @@ -1837,7 +1835,7 @@ options_start_log_transaction(const or_options_t *old_options, * Finish configuring the logs that started to get configured with <b>xn</b>. * Frees <b>xn</b>. **/ -static void +STATIC void options_commit_log_transaction(log_transaction_t *xn) { const or_options_t *options = get_options(); @@ -1891,7 +1889,7 @@ options_commit_log_transaction(log_transaction_t *xn) * Revert the log configuration changes that that started to get configured * with <b>xn</b>. Frees <b>xn</b>. **/ -static void +STATIC void options_rollback_log_transaction(log_transaction_t *xn) { if (!xn) diff --git a/src/app/config/config.h b/src/app/config/config.h index c6c03329bb..15c9352467 100644 --- a/src/app/config/config.h +++ b/src/app/config/config.h @@ -304,6 +304,12 @@ STATIC int options_init_logs(const or_options_t *old_options, const or_options_t *options, int validate_only); STATIC int options_create_directories(char **msg_out); +struct log_transaction_t; +STATIC struct log_transaction_t *options_start_log_transaction( + const or_options_t *old_options, + char **msg_out); +STATIC void options_commit_log_transaction(struct log_transaction_t *xn); +STATIC void options_rollback_log_transaction(struct log_transaction_t *xn); #ifdef TOR_UNIT_TESTS int options_validate(const or_options_t *old_options, diff --git a/src/test/test_options_act.c b/src/test/test_options_act.c index abc1c65481..0a9be28c54 100644 --- a/src/test/test_options_act.c +++ b/src/test/test_options_act.c @@ -6,6 +6,7 @@ #define CONFIG_PRIVATE #include "core/or/or.h" #include "app/config/config.h" +#include "lib/encoding/confline.h" #include "test/test.h" #include "test/log_test_helpers.h" @@ -167,11 +168,105 @@ test_options_act_create_dirs(void *arg) tor_free(msg); } +static void +test_options_act_log_transition(void *arg) +{ + (void)arg; + or_options_t *opts = mock_opts = options_new(); + or_options_t *old_opts = NULL; + opts->LogTimeGranularity = 1000; + opts->SafeLogging_ = SAFELOG_SCRUB_ALL; + struct log_transaction_t *lt = NULL; + char *msg = NULL; + MOCK(get_options, mock_get_options); + + tt_ptr_op(opts->Logs, OP_EQ, NULL); + config_line_append(&opts->Logs, "Log", "notice stdout"); + lt = options_start_log_transaction(NULL, &msg); + tt_assert(lt); + tt_assert(!msg); + + // commit, see that there is a change. + options_commit_log_transaction(lt); + lt=NULL; + tt_int_op(get_min_log_level(), OP_EQ, LOG_NOTICE); + + // Now drop to debug. + old_opts = opts; + opts = mock_opts = options_new(); + opts->LogTimeGranularity = 1000; + opts->SafeLogging_ = SAFELOG_SCRUB_ALL; + config_line_append(&opts->Logs, "Log", "debug stdout"); + lt = options_start_log_transaction(old_opts, &msg); + tt_assert(lt); + tt_assert(!msg); + + setup_full_capture_of_logs(LOG_NOTICE); + options_commit_log_transaction(lt); + lt=NULL; + expect_single_log_msg_containing("may contain sensitive information"); + tt_int_op(get_min_log_level(), OP_EQ, LOG_DEBUG); + + // Turn off SafeLogging + or_options_free(old_opts); + mock_clean_saved_logs(); + old_opts = opts; + opts = mock_opts = options_new(); + opts->SafeLogging_ = SAFELOG_SCRUB_NONE; + opts->LogTimeGranularity = 1000; + config_line_append(&opts->Logs, "Log", "debug stdout"); + lt = options_start_log_transaction(old_opts, &msg); + tt_assert(lt); + tt_assert(!msg); + options_commit_log_transaction(lt); + lt=NULL; + expect_single_log_msg_containing("may contain sensitive information"); + tt_int_op(get_min_log_level(), OP_EQ, LOG_DEBUG); + + // Try rolling back. + or_options_free(old_opts); + mock_clean_saved_logs(); + old_opts = opts; + opts = mock_opts = options_new(); + opts->SafeLogging_ = SAFELOG_SCRUB_NONE; + opts->LogTimeGranularity = 1000; + config_line_append(&opts->Logs, "Log", "notice stdout"); + lt = options_start_log_transaction(old_opts, &msg); + tt_assert(lt); + tt_assert(!msg); + options_rollback_log_transaction(lt); + expect_no_log_entry(); + lt = NULL; + tt_int_op(get_min_log_level(), OP_EQ, LOG_DEBUG); + + // Now try some bad options. + or_options_free(opts); + mock_clean_saved_logs(); + opts = mock_opts = options_new(); + opts->LogTimeGranularity = 1000; + config_line_append(&opts->Logs, "Log", "warn blaznert"); + lt = options_start_log_transaction(old_opts, &msg); + tt_assert(!lt); + tt_str_op(msg, OP_EQ, "Failed to init Log options. See logs for details."); + expect_single_log_msg_containing("Couldn't parse"); + tt_int_op(get_min_log_level(), OP_EQ, LOG_DEBUG); + + done: + UNMOCK(get_options); + or_options_free(opts); + or_options_free(old_opts); + tor_free(msg); + if (lt) + options_rollback_log_transaction(lt); + teardown_capture_of_logs(); +} + #ifndef COCCI #define T(name) { #name, test_options_act_##name, TT_FORK, NULL, NULL } #endif struct testcase_t options_act_tests[] = { T(create_dirs), + T(log_transition), END_OF_TESTCASES }; |