Some tests for log changes, commit, and rollback

This commit is contained in:
Nick Mathewson 2019-11-19 15:45:12 -05:00
parent a30d143228
commit 89c355b386
3 changed files with 104 additions and 5 deletions

View File

@ -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, static setopt_err_t options_validate_and_set(const or_options_t *old_options,
or_options_t *new_options, or_options_t *new_options,
char **msg_out); char **msg_out);
struct log_transaction_t;
static void options_rollback_log_transaction(struct log_transaction_t *xn);
struct listener_transaction_t; struct listener_transaction_t;
static void options_rollback_listener_transaction( static void options_rollback_listener_transaction(
struct listener_transaction_t *xn); 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 * On failure return NULL and write a message into a newly allocated string in
* *<b>msg_out</b>. * *<b>msg_out</b>.
**/ **/
static log_transaction_t * STATIC log_transaction_t *
options_start_log_transaction(const or_options_t *old_options, options_start_log_transaction(const or_options_t *old_options,
char **msg_out) 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>. * Finish configuring the logs that started to get configured with <b>xn</b>.
* Frees <b>xn</b>. * Frees <b>xn</b>.
**/ **/
static void STATIC void
options_commit_log_transaction(log_transaction_t *xn) options_commit_log_transaction(log_transaction_t *xn)
{ {
const or_options_t *options = get_options(); 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 * Revert the log configuration changes that that started to get configured
* with <b>xn</b>. Frees <b>xn</b>. * with <b>xn</b>. Frees <b>xn</b>.
**/ **/
static void STATIC void
options_rollback_log_transaction(log_transaction_t *xn) options_rollback_log_transaction(log_transaction_t *xn)
{ {
if (!xn) if (!xn)

View File

@ -304,6 +304,12 @@ STATIC int options_init_logs(const or_options_t *old_options,
const or_options_t *options, int validate_only); const or_options_t *options, int validate_only);
STATIC int options_create_directories(char **msg_out); 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 #ifdef TOR_UNIT_TESTS
int options_validate(const or_options_t *old_options, int options_validate(const or_options_t *old_options,

View File

@ -6,6 +6,7 @@
#define CONFIG_PRIVATE #define CONFIG_PRIVATE
#include "core/or/or.h" #include "core/or/or.h"
#include "app/config/config.h" #include "app/config/config.h"
#include "lib/encoding/confline.h"
#include "test/test.h" #include "test/test.h"
#include "test/log_test_helpers.h" #include "test/log_test_helpers.h"
@ -167,11 +168,105 @@ test_options_act_create_dirs(void *arg)
tor_free(msg); 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 #ifndef COCCI
#define T(name) { #name, test_options_act_##name, TT_FORK, NULL, NULL } #define T(name) { #name, test_options_act_##name, TT_FORK, NULL, NULL }
#endif #endif
struct testcase_t options_act_tests[] = { struct testcase_t options_act_tests[] = {
T(create_dirs), T(create_dirs),
T(log_transition),
END_OF_TESTCASES END_OF_TESTCASES
}; };