diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/fuzzing_common.c | 5 | ||||
-rw-r--r-- | src/test/include.am | 1 | ||||
-rw-r--r-- | src/test/test.c | 1 | ||||
-rw-r--r-- | src/test/test.h | 1 | ||||
-rw-r--r-- | src/test/test_config.c | 92 | ||||
-rw-r--r-- | src/test/test_confmgr.c | 325 | ||||
-rw-r--r-- | src/test/test_confparse.c | 381 | ||||
-rw-r--r-- | src/test/test_dir_handle_get.c | 3 | ||||
-rw-r--r-- | src/test/test_entrynodes.c | 30 | ||||
-rw-r--r-- | src/test/test_helpers.c | 2 | ||||
-rw-r--r-- | src/test/test_hs_service.c | 10 | ||||
-rw-r--r-- | src/test/test_options.c | 14 | ||||
-rw-r--r-- | src/test/test_pt.c | 2 |
13 files changed, 682 insertions, 185 deletions
diff --git a/src/test/fuzz/fuzzing_common.c b/src/test/fuzz/fuzzing_common.c index 6d0f9d7d60..862acb2b35 100644 --- a/src/test/fuzz/fuzzing_common.c +++ b/src/test/fuzz/fuzzing_common.c @@ -1,6 +1,7 @@ /* Copyright (c) 2016-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #define CRYPTO_ED25519_PRIVATE +#define CONFIG_PRIVATE #include "orconfig.h" #include "core/or/or.h" #include "app/main/subsysmgr.h" @@ -111,7 +112,7 @@ global_init(void) } /* set up the options. */ - mock_options = tor_malloc_zero(sizeof(or_options_t)); + mock_options = options_new(); MOCK(get_options, mock_get_options); /* Make BUG() and nonfatal asserts crash */ @@ -189,7 +190,7 @@ main(int argc, char **argv) if (fuzz_cleanup() < 0) abort(); - tor_free(mock_options); + or_options_free(mock_options); UNMOCK(get_options); return 0; } diff --git a/src/test/include.am b/src/test/include.am index 1e20f3f53f..1ec54a286f 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -124,6 +124,7 @@ src_test_test_SOURCES += \ src/test/test_circuitstats.c \ src/test/test_compat_libevent.c \ src/test/test_config.c \ + src/test/test_confmgr.c \ src/test/test_confparse.c \ src/test/test_connection.c \ src/test/test_conscache.c \ diff --git a/src/test/test.c b/src/test/test.c index b9a1da06f0..65e169b38e 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -840,6 +840,7 @@ struct testgroup_t testgroups[] = { { "circuituse/", circuituse_tests }, { "compat/libevent/", compat_libevent_tests }, { "config/", config_tests }, + { "config/mgr/", confmgr_tests }, { "config/parse/", confparse_tests }, { "connection/", connection_tests }, { "conscache/", conscache_tests }, diff --git a/src/test/test.h b/src/test/test.h index f5c21bfe88..d6a1d19ea1 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -197,6 +197,7 @@ extern struct testcase_t circuitstats_tests[]; extern struct testcase_t circuituse_tests[]; extern struct testcase_t compat_libevent_tests[]; extern struct testcase_t config_tests[]; +extern struct testcase_t confmgr_tests[]; extern struct testcase_t confparse_tests[]; extern struct testcase_t connection_tests[]; extern struct testcase_t conscache_tests[]; diff --git a/src/test/test_config.c b/src/test/test_config.c index a415ca4480..58e05e5094 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1755,6 +1755,18 @@ add_default_fallback_dir_servers_known_default(void) n_add_default_fallback_dir_servers_known_default++; } +/* Helper for test_config_adding_dir_servers(), which should be + * refactored: clear the fields in the options which the options object + * does not really own. */ +static void +ads_clear_helper(or_options_t *options) +{ + options->DirAuthorities = NULL; + options->AlternateBridgeAuthority = NULL; + options->AlternateDirAuthority = NULL; + options->FallbackDir = NULL; +} + /* Test all the different combinations of adding dir servers */ static void test_config_adding_dir_servers(void *arg) @@ -1762,7 +1774,7 @@ test_config_adding_dir_servers(void *arg) (void)arg; /* allocate options */ - or_options_t *options = tor_malloc_zero(sizeof(or_options_t)); + or_options_t *options = options_new(); /* Allocate and populate configuration lines: * @@ -1885,7 +1897,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -1967,7 +1981,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -2108,7 +2124,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -2249,7 +2267,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -2391,7 +2411,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -2543,7 +2565,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -2697,7 +2721,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -2860,7 +2886,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -3017,7 +3045,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -3183,7 +3213,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -3346,7 +3378,9 @@ test_config_adding_dir_servers(void *arg) n_add_default_fallback_dir_servers_known_default = 0; /* clear options*/ - memset(options, 0, sizeof(or_options_t)); + ads_clear_helper(options); + or_options_free(options); + options = options_new(); /* clear any previous dir servers: consider_adding_dir_servers() should do this anyway */ @@ -3515,10 +3549,7 @@ test_config_adding_dir_servers(void *arg) tor_free(test_fallback_directory->value); tor_free(test_fallback_directory); - options->DirAuthorities = NULL; - options->AlternateBridgeAuthority = NULL; - options->AlternateDirAuthority = NULL; - options->FallbackDir = NULL; + ads_clear_helper(options); or_options_free(options); UNMOCK(add_default_fallback_dir_servers); @@ -3533,7 +3564,7 @@ test_config_default_dir_servers(void *arg) int fallback_count = 0; /* new set of options should stop fallback parsing */ - opts = tor_malloc_zero(sizeof(or_options_t)); + opts = options_new(); opts->UseDefaultFallbackDirs = 0; /* set old_options to NULL to force dir update */ consider_adding_dir_servers(opts, NULL); @@ -3547,7 +3578,7 @@ test_config_default_dir_servers(void *arg) /* if we disable the default fallbacks, there must not be any extra */ tt_assert(fallback_count == trusted_count); - opts = tor_malloc_zero(sizeof(or_options_t)); + opts = options_new(); opts->UseDefaultFallbackDirs = 1; consider_adding_dir_servers(opts, opts); trusted_count = smartlist_len(router_get_trusted_dir_servers()); @@ -3607,7 +3638,7 @@ test_config_directory_fetch(void *arg) (void)arg; /* Test Setup */ - or_options_t *options = tor_malloc_zero(sizeof(or_options_t)); + or_options_t *options = options_new(); routerinfo_t routerinfo; memset(&routerinfo, 0, sizeof(routerinfo)); mock_router_pick_published_address_result = -1; @@ -3619,9 +3650,10 @@ test_config_directory_fetch(void *arg) mock_router_my_exit_policy_is_reject_star); MOCK(advertised_server_mode, mock_advertised_server_mode); MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo); + or_options_free(options); + options = options_new(); /* Clients can use multiple directory mirrors for bootstrap */ - memset(options, 0, sizeof(or_options_t)); options->ClientOnly = 1; tt_assert(server_mode(options) == 0); tt_assert(public_server_mode(options) == 0); @@ -3630,7 +3662,8 @@ test_config_directory_fetch(void *arg) OP_EQ, 1); /* Bridge Clients can use multiple directory mirrors for bootstrap */ - memset(options, 0, sizeof(or_options_t)); + or_options_free(options); + options = options_new(); options->UseBridges = 1; tt_assert(server_mode(options) == 0); tt_assert(public_server_mode(options) == 0); @@ -3640,7 +3673,8 @@ test_config_directory_fetch(void *arg) /* Bridge Relays (Bridges) must act like clients, and use multiple * directory mirrors for bootstrap */ - memset(options, 0, sizeof(or_options_t)); + or_options_free(options); + options = options_new(); options->BridgeRelay = 1; options->ORPort_set = 1; tt_assert(server_mode(options) == 1); @@ -3651,7 +3685,8 @@ test_config_directory_fetch(void *arg) /* Clients set to FetchDirInfoEarly must fetch it from the authorities, * but can use multiple authorities for bootstrap */ - memset(options, 0, sizeof(or_options_t)); + or_options_free(options); + options = options_new(); options->FetchDirInfoEarly = 1; tt_assert(server_mode(options) == 0); tt_assert(public_server_mode(options) == 0); @@ -3662,7 +3697,8 @@ test_config_directory_fetch(void *arg) /* OR servers only fetch the consensus from the authorities when they don't * know their own address, but never use multiple directories for bootstrap */ - memset(options, 0, sizeof(or_options_t)); + or_options_free(options); + options = options_new(); options->ORPort_set = 1; mock_router_pick_published_address_result = -1; @@ -3682,7 +3718,8 @@ test_config_directory_fetch(void *arg) /* Exit OR servers only fetch the consensus from the authorities when they * refuse unknown exits, but never use multiple directories for bootstrap */ - memset(options, 0, sizeof(or_options_t)); + or_options_free(options); + options = options_new(); options->ORPort_set = 1; options->ExitRelay = 1; mock_router_pick_published_address_result = 0; @@ -3712,7 +3749,8 @@ test_config_directory_fetch(void *arg) * advertising their dirport, and never use multiple directories for * bootstrap. This only applies if they are also OR servers. * (We don't care much about the behaviour of non-OR directory servers.) */ - memset(options, 0, sizeof(or_options_t)); + or_options_free(options); + options = options_new(); options->DirPort_set = 1; options->ORPort_set = 1; options->DirCache = 1; @@ -3766,7 +3804,7 @@ test_config_directory_fetch(void *arg) OP_EQ, 0); done: - tor_free(options); + or_options_free(options); UNMOCK(router_pick_published_address); UNMOCK(router_get_my_routerinfo); UNMOCK(advertised_server_mode); diff --git a/src/test/test_confmgr.c b/src/test/test_confmgr.c new file mode 100644 index 0000000000..5f73d9754b --- /dev/null +++ b/src/test/test_confmgr.c @@ -0,0 +1,325 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/* + * Tests for confparse.c's features that support multiple configuration + * formats and configuration objects. + */ + +#define CONFPARSE_PRIVATE +#include "orconfig.h" + +#include "core/or/or.h" +#include "lib/encoding/confline.h" +#include "app/config/confparse.h" +#include "test/test.h" +#include "test/log_test_helpers.h" + +/* + * Set up a few objects: a pasture_cfg is toplevel; it has a llama_cfg and an + * alpaca_cfg. + */ + +typedef struct { + uint32_t magic; + char *address; + int opentopublic; + config_suite_t *subobjs; +} pasture_cfg_t; + +typedef struct { + char *llamaname; + int cuteness; + uint32_t magic; + int eats_meat; /* deprecated; llamas are never carnivorous. */ + + char *description; // derived from other fields. +} llama_cfg_t; + +typedef struct { + uint32_t magic; + int fuzziness; + char *alpacaname; + int n_wings; /* deprecated; alpacas don't have wings. */ +} alpaca_cfg_t; + +/* + * Make the above into configuration objects. + */ + +static pasture_cfg_t pasture_cfg_t_dummy; +static llama_cfg_t llama_cfg_t_dummy; +static alpaca_cfg_t alpaca_cfg_t_dummy; + +#define PV(name, type, dflt) \ + CONFIG_VAR_ETYPE(pasture_cfg_t, #name, type, name, 0, dflt) +#define LV(name, type, dflt) \ + CONFIG_VAR_ETYPE(llama_cfg_t, #name, type, name, 0, dflt) +#define AV(name, type, dflt) \ + CONFIG_VAR_ETYPE(alpaca_cfg_t, #name, type, name, 0, dflt) +static const config_var_t pasture_vars[] = { + PV(address, STRING, NULL), + PV(opentopublic, BOOL, "1"), + END_OF_CONFIG_VARS +}; +static const config_var_t llama_vars[] = +{ + LV(llamaname, STRING, NULL), + LV(eats_meat, BOOL, NULL), + LV(cuteness, POSINT, "100"), + END_OF_CONFIG_VARS +}; +static const config_var_t alpaca_vars[] = +{ + AV(alpacaname, STRING, NULL), + AV(fuzziness, POSINT, "50"), + AV(n_wings, POSINT, "0"), + END_OF_CONFIG_VARS +}; + +static config_deprecation_t llama_deprecations[] = { + { "eats_meat", "Llamas are herbivores." }, + {NULL,NULL} +}; + +static config_deprecation_t alpaca_deprecations[] = { + { "n_wings", "Alpacas are quadrupeds." }, + {NULL,NULL} +}; + +static int clear_llama_cfg_called = 0; +static void +clear_llama_cfg(const config_mgr_t *mgr, void *llamacfg) +{ + (void)mgr; + llama_cfg_t *lc = llamacfg; + tor_free(lc->description); + ++clear_llama_cfg_called; +} + +static config_abbrev_t llama_abbrevs[] = { + { "gracia", "cuteness", 0, 0 }, + { "gentillesse", "cuteness", 0, 0 }, + { NULL, NULL, 0, 0 }, +}; + +static const config_format_t pasture_fmt = { + sizeof(pasture_cfg_t), + { + "pasture_cfg_t", + 8989, + offsetof(pasture_cfg_t, magic) + }, + .vars = pasture_vars, + .config_suite_offset = offsetof(pasture_cfg_t, subobjs), +}; + +static const config_format_t llama_fmt = { + sizeof(llama_cfg_t), + { + "llama_cfg_t", + 0x11aa11, + offsetof(llama_cfg_t, magic) + }, + .vars = llama_vars, + .config_suite_offset = -1, + .deprecations = llama_deprecations, + .abbrevs = llama_abbrevs, + .clear_fn = clear_llama_cfg, +}; + +static const config_format_t alpaca_fmt = { + sizeof(alpaca_cfg_t), + { + "alpaca_cfg_t", + 0xa15aca, + offsetof(alpaca_cfg_t, magic) + }, + .vars = alpaca_vars, + .config_suite_offset = -1, + .deprecations = alpaca_deprecations, +}; + +#define LLAMA_IDX 0 +#define ALPACA_IDX 1 + +static config_mgr_t * +get_mgr(bool freeze) +{ + config_mgr_t *mgr = config_mgr_new(&pasture_fmt); + tt_int_op(LLAMA_IDX, OP_EQ, config_mgr_add_format(mgr, &llama_fmt)); + tt_int_op(ALPACA_IDX, OP_EQ, config_mgr_add_format(mgr, &alpaca_fmt)); + if (freeze) + config_mgr_freeze(mgr); + return mgr; + + done: + config_mgr_free(mgr); + return NULL; +} + +static void +test_confmgr_init(void *arg) +{ + (void)arg; + config_mgr_t *mgr = get_mgr(true); + smartlist_t *vars = NULL; + tt_ptr_op(mgr, OP_NE, NULL); + + vars = config_mgr_list_vars(mgr); + tt_int_op(smartlist_len(vars), OP_EQ, 8); // 8 vars total. + + tt_str_op("cuteness", OP_EQ, config_find_option_name(mgr, "CUTENESS")); + tt_str_op("cuteness", OP_EQ, config_find_option_name(mgr, "GRACIA")); + smartlist_free(vars); + + vars = config_mgr_list_deprecated_vars(mgr); // 2 deprecated vars. + tt_int_op(smartlist_len(vars), OP_EQ, 2); + tt_assert(smartlist_contains_string(vars, "eats_meat")); + tt_assert(smartlist_contains_string(vars, "n_wings")); + + tt_str_op("Llamas are herbivores.", OP_EQ, + config_find_deprecation(mgr, "EATS_MEAT")); + tt_str_op("Alpacas are quadrupeds.", OP_EQ, + config_find_deprecation(mgr, "N_WINGS")); + + done: + smartlist_free(vars); + config_mgr_free(mgr); +} + +static void +test_confmgr_magic(void *args) +{ + (void)args; + // Every time we build a manager, it is supposed to get a different magic + // number. Let's test that. + config_mgr_t *mgr1 = get_mgr(true); + config_mgr_t *mgr2 = get_mgr(true); + config_mgr_t *mgr3 = get_mgr(true); + + pasture_cfg_t *p1 = NULL, *p2 = NULL, *p3 = NULL; + + tt_assert(mgr1); + tt_assert(mgr2); + tt_assert(mgr3); + + p1 = config_new(mgr1); + p2 = config_new(mgr2); + p3 = config_new(mgr3); + + tt_assert(p1); + tt_assert(p2); + tt_assert(p3); + + // By chance, two managers get the same magic with P=2^-32. Let's + // make sure that at least two of them are different, so that our + // odds of a false positive are 1/2^-64. + tt_assert((p1->magic != p2->magic) || (p2->magic != p3->magic)); + + done: + config_free(mgr1, p1); + config_free(mgr2, p2); + config_free(mgr3, p3); + + config_mgr_free(mgr1); + config_mgr_free(mgr2); + config_mgr_free(mgr3); +} + +static const char *simple_pasture = + "LLamaname hugo\n" + "Alpacaname daphne\n" + "gentillesse 42\n" + "address 123 Camelid ave\n"; + +static void +test_confmgr_parse(void *arg) +{ + (void)arg; + config_mgr_t *mgr = get_mgr(true); + pasture_cfg_t *p = config_new(mgr); + config_line_t *lines = NULL; + char *msg = NULL; + + config_init(mgr, p); // set defaults. + + int r = config_get_lines(simple_pasture, &lines, 0); + tt_int_op(r, OP_EQ, 0); + r = config_assign(mgr, p, lines, 0, &msg); + tt_int_op(r, OP_EQ, 0); + + tt_int_op(p->opentopublic, OP_EQ, 1); + tt_str_op(p->address, OP_EQ, "123 Camelid ave"); + + // We are using this API directly; modules outside confparse will, in the + // future, not. + const alpaca_cfg_t *ac = config_mgr_get_obj(mgr, p, ALPACA_IDX); + const llama_cfg_t *lc = config_mgr_get_obj(mgr, p, LLAMA_IDX); + tt_str_op(lc->llamaname, OP_EQ, "hugo"); + tt_str_op(ac->alpacaname, OP_EQ, "daphne"); + tt_int_op(lc->cuteness, OP_EQ, 42); + tt_int_op(ac->fuzziness, OP_EQ, 50); + + // We set the description for the llama here, so that the clear function + // can clear it. (Later we can do this in a verification function.) + clear_llama_cfg_called = 0; + llama_cfg_t *mut_lc = config_mgr_get_obj_mutable(mgr, p, LLAMA_IDX); + mut_lc->description = tor_strdup("A llama named Hugo."); + config_free(mgr, p); + tt_int_op(clear_llama_cfg_called, OP_EQ, 1); + + done: + config_free_lines(lines); + config_free(mgr, p); + config_mgr_free(mgr); + tor_free(msg); +} + +static void +test_confmgr_dump(void *arg) +{ + (void)arg; + config_mgr_t *mgr = get_mgr(true); + pasture_cfg_t *p = config_new(mgr); + pasture_cfg_t *defaults = config_new(mgr); + config_line_t *lines = NULL; + char *msg = NULL; + char *s = NULL; + + config_init(mgr, p); // set defaults. + config_init(mgr, defaults); // set defaults. + + int r = config_get_lines(simple_pasture, &lines, 0); + tt_int_op(r, OP_EQ, 0); + r = config_assign(mgr, p, lines, 0, &msg); + tt_int_op(r, OP_EQ, 0); + + s = config_dump(mgr, defaults, p, 1, 0); + tt_str_op("address 123 Camelid ave\n" + "alpacaname daphne\n" + "cuteness 42\n" + "llamaname hugo\n", OP_EQ, s); + + done: + config_free_lines(lines); + config_free(mgr, p); + config_free(mgr, defaults); + config_mgr_free(mgr); + + tor_free(msg); + tor_free(s); +} + +#define CONFMGR_TEST(name, flags) \ + { #name, test_confmgr_ ## name, flags, NULL, NULL } + +struct testcase_t confmgr_tests[] = { + CONFMGR_TEST(init, 0), + CONFMGR_TEST(magic, 0), + CONFMGR_TEST(parse, 0), + CONFMGR_TEST(dump, 0), + END_OF_TESTCASES +}; diff --git a/src/test/test_confparse.c b/src/test/test_confparse.c index ec018f0c52..f04c412c0e 100644 --- a/src/test/test_confparse.c +++ b/src/test/test_confparse.c @@ -119,8 +119,6 @@ test_validate_cb(void *old_options, void *options, void *default_options, return 0; } -static void test_free_cb(void *options); - #define TEST_MAGIC 0x1337 static const config_format_t test_fmt = { @@ -134,29 +132,22 @@ static const config_format_t test_fmt = { test_deprecation_notes, test_vars, test_validate_cb, - test_free_cb, NULL, + NULL, + -1, }; -static void -test_free_cb(void *options) -{ - if (!options) - return; - - config_free(&test_fmt, options); -} - /* Make sure that config_init sets everything to the right defaults. */ static void test_confparse_init(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); - config_init(&test_fmt, tst); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = config_new(mgr); + config_init(mgr, tst); // Make sure that options are initialized right. */ - tt_uint_op(tst->magic, OP_EQ, TEST_MAGIC); tt_str_op(tst->s, OP_EQ, "hello"); tt_ptr_op(tst->fn, OP_EQ, NULL); tt_int_op(tst->pos, OP_EQ, 0); @@ -178,7 +169,8 @@ test_confparse_init(void *arg) tt_int_op(tst->hidden_int, OP_EQ, 0); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } static const char simple_settings[] = @@ -207,18 +199,18 @@ static const char simple_settings[] = /* Return a configuration object set up from simple_settings above. */ static test_struct_t * -get_simple_config(void) +get_simple_config(const config_mgr_t *mgr) { test_struct_t *result = NULL; - test_struct_t *tst = config_new(&test_fmt); + test_struct_t *tst = config_new(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines(simple_settings, &lines, 0); tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); @@ -227,7 +219,7 @@ get_simple_config(void) done: tor_free(msg); config_free_lines(lines); - config_free(&test_fmt, tst); + config_free(mgr, tst); return result; } @@ -236,7 +228,9 @@ static void test_confparse_assign_simple(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); tt_str_op(tst->s, OP_EQ, "this is a"); tt_str_op(tst->fn, OP_EQ, "/simple/test of the"); @@ -284,10 +278,11 @@ test_confparse_assign_simple(void *arg) tt_str_op(tst->mixed_hidden_lines->next->value, OP_EQ, "ABC"); tt_assert(!tst->mixed_hidden_lines->next->next); - tt_assert(config_check_ok(&test_fmt, tst, LOG_ERR)); + tt_assert(config_check_ok(mgr, tst, LOG_ERR)); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } /* Try to assign to an obsolete option, and make sure we get a warning. */ @@ -295,26 +290,29 @@ static void test_confparse_assign_obsolete(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("obsolete option here", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("Skipping obsolete configuration option"); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to assign to an deprecated option, and make sure we get a warning @@ -323,30 +321,33 @@ static void test_confparse_assign_deprecated(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("deprecated_int 7", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, CAL_WARN_DEPRECATIONS, &msg); + r = config_assign(mgr, tst, lines, CAL_WARN_DEPRECATIONS, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("This integer is deprecated."); tt_int_op(tst->deprecated_int, OP_EQ, 7); - tt_assert(config_check_ok(&test_fmt, tst, LOG_ERR)); + tt_assert(config_check_ok(mgr, tst, LOG_ERR)); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to re-assign an option name that has been depreacted in favor of @@ -355,16 +356,18 @@ static void test_confparse_assign_replaced(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("float 1000\n", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, CAL_WARN_DEPRECATIONS, &msg); + r = config_assign(mgr, tst, lines, CAL_WARN_DEPRECATIONS, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("use 'dbl' instead."); @@ -374,9 +377,10 @@ test_confparse_assign_replaced(void *arg) done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to set a linelist value with no option. */ @@ -384,25 +388,28 @@ static void test_confparse_assign_emptystring(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("lines\n", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("has no value"); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Try to set a the same option twice; make sure we get a warning. */ @@ -410,26 +417,29 @@ static void test_confparse_assign_twice(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines("pos 10\n" "pos 99\n", &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); expect_single_log_msg_containing("used more than once"); done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } typedef struct badval_test_t { @@ -443,16 +453,18 @@ static void test_confparse_assign_badval(void *arg) { const badval_test_t *bt = arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; - config_init(&test_fmt, tst); + config_init(mgr, tst); int r = config_get_lines(bt->cfg, &lines, 0); tt_int_op(r, OP_EQ, 0); setup_capture_of_logs(LOG_WARN); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_LT, 0); tt_ptr_op(msg, OP_NE, NULL); if (! strstr(msg, bt->expect_msg)) { @@ -461,9 +473,10 @@ test_confparse_assign_badval(void *arg) done: teardown_capture_of_logs(); - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Various arguments for badval test. @@ -495,88 +508,90 @@ static void test_confparse_dump(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); char *dumped = NULL; /* Minimal version. */ - dumped = config_dump(&test_fmt, NULL, tst, 1, 0); + dumped = config_dump(mgr, NULL, tst, 1, 0); tt_str_op(dumped, OP_EQ, - "s this is a\n" - "fn /simple/test of the\n" - "pos 77\n" - "i 3\n" - "u64 1000000000000\n" - "interval 300\n" - "msec_interval 300000\n" - "mem 10\n" - "dbl 6.060842\n" - "boolean 1\n" "autobool 0\n" - "time 2019-06-14 13:58:51\n" + "boolean 1\n" "csv configuration,parsing,system\n" "csv_interval 10\n" + "dbl 6.060842\n" + "fn /simple/test of the\n" + "i 3\n" + "interval 300\n" "lines hello\n" "lines world\n" + "mem 10\n" + "VisibleLineB ABC\n" "LineTypeA i d\n" "LineTypeB i c\n" + "msec_interval 300000\n" + "pos 77\n" "routerset $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n" - "VisibleLineB ABC\n"); + "s this is a\n" + "time 2019-06-14 13:58:51\n" + "u64 1000000000000\n"); - /* Maximal */ tor_free(dumped); - dumped = config_dump(&test_fmt, NULL, tst, 0, 0); + dumped = config_dump(mgr, NULL, tst, 0, 0); tt_str_op(dumped, OP_EQ, - "s this is a\n" - "fn /simple/test of the\n" - "pos 77\n" - "i 3\n" - "deprecated_int 3\n" - "u64 1000000000000\n" - "interval 300\n" - "msec_interval 300000\n" - "mem 10\n" - "dbl 6.060842\n" - "boolean 1\n" "autobool 0\n" - "time 2019-06-14 13:58:51\n" + "boolean 1\n" "csv configuration,parsing,system\n" "csv_interval 10\n" + "dbl 6.060842\n" + "deprecated_int 3\n" + "fn /simple/test of the\n" + "i 3\n" + "interval 300\n" "lines hello\n" "lines world\n" + "mem 10\n" + "VisibleLineB ABC\n" "LineTypeA i d\n" "LineTypeB i c\n" + "msec_interval 300000\n" + "pos 77\n" "routerset $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n" - "VisibleLineB ABC\n"); + "s this is a\n" + "time 2019-06-14 13:58:51\n" + "u64 1000000000000\n"); /* commented */ tor_free(dumped); - dumped = config_dump(&test_fmt, NULL, tst, 0, 1); + dumped = config_dump(mgr, NULL, tst, 0, 1); tt_str_op(dumped, OP_EQ, - "s this is a\n" - "fn /simple/test of the\n" - "pos 77\n" - "i 3\n" - "# deprecated_int 3\n" - "u64 1000000000000\n" - "interval 300\n" - "msec_interval 300000\n" - "mem 10\n" - "dbl 6.060842\n" - "boolean 1\n" "autobool 0\n" - "time 2019-06-14 13:58:51\n" + "boolean 1\n" "csv configuration,parsing,system\n" "csv_interval 10\n" + "dbl 6.060842\n" + "# deprecated_int 3\n" + "fn /simple/test of the\n" + "i 3\n" + "interval 300\n" "lines hello\n" "lines world\n" + "mem 10\n" + "VisibleLineB ABC\n" "LineTypeA i d\n" "LineTypeB i c\n" + "msec_interval 300000\n" + "pos 77\n" "routerset $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n" - "VisibleLineB ABC\n"); + "s this is a\n" + "time 2019-06-14 13:58:51\n" + "u64 1000000000000\n"); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); tor_free(dumped); + config_mgr_free(mgr); } /* Try confparse_reset_line(), and make sure it behaves correctly */ @@ -584,16 +599,19 @@ static void test_confparse_reset(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); - config_reset_line(&test_fmt, tst, "interval", 0); + config_reset_line(mgr, tst, "interval", 0); tt_int_op(tst->interval, OP_EQ, 0); - config_reset_line(&test_fmt, tst, "interval", 1); + config_reset_line(mgr, tst, "interval", 1); tt_int_op(tst->interval, OP_EQ, 10); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } /* Try setting options a second time on a config object, and make sure @@ -602,7 +620,9 @@ static void test_confparse_reassign(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL, *rs = NULL; @@ -613,7 +633,7 @@ test_confparse_reassign(void *arg) "csv 14,15\n" "routerset 127.0.0.1\n", &lines, 0); - r = config_assign(&test_fmt, tst,lines, 0, &msg); + r = config_assign(mgr, tst,lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); @@ -633,7 +653,7 @@ test_confparse_reassign(void *arg) tt_str_op(rs, OP_EQ, "127.0.0.1"); // Try again with the CLEAR_FIRST and USE_DEFAULTS flags - r = config_assign(&test_fmt, tst, lines, + r = config_assign(mgr, tst, lines, CAL_CLEAR_FIRST|CAL_USE_DEFAULTS, &msg); tt_int_op(r, OP_EQ, 0); @@ -644,10 +664,11 @@ test_confparse_reassign(void *arg) tt_int_op(tst->i, OP_EQ, 12); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); tor_free(rs); + config_mgr_free(mgr); } /* Try setting options a second time on a config object, using the +foo @@ -656,7 +677,9 @@ static void test_confparse_reassign_extend(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; char *msg = NULL; @@ -664,7 +687,7 @@ test_confparse_reassign_extend(void *arg) "+lines 13\n", &lines, 1); // allow extended format. tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst,lines, 0, &msg); + r = config_assign(mgr, tst,lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); @@ -684,27 +707,28 @@ test_confparse_reassign_extend(void *arg) "/lines\n", &lines, 1); // allow extended format. tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); tt_assert(tst->lines == NULL); config_free_lines(lines); - config_free(&test_fmt, tst); - tst = get_simple_config(); + config_free(mgr, tst); + tst = get_simple_config(mgr); r = config_get_lines( "/lines away!\n", &lines, 1); // allow extended format. tt_int_op(r, OP_EQ, 0); - r = config_assign(&test_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); tt_assert(tst->lines == NULL); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); tor_free(msg); + config_mgr_free(mgr); } /* Test out confparse_get_assigned(). */ @@ -712,30 +736,33 @@ static void test_confparse_get_assigned(void *arg) { (void)arg; - test_struct_t *tst = get_simple_config(); + + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = get_simple_config(mgr); config_line_t *lines = NULL; - lines = config_get_assigned_option(&test_fmt, tst, "I", 1); + lines = config_get_assigned_option(mgr, tst, "I", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "i"); tt_str_op(lines->value, OP_EQ, "3"); tt_assert(lines->next == NULL); config_free_lines(lines); - lines = config_get_assigned_option(&test_fmt, tst, "s", 1); + lines = config_get_assigned_option(mgr, tst, "s", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "s"); tt_str_op(lines->value, OP_EQ, "this is a"); tt_assert(lines->next == NULL); config_free_lines(lines); - lines = config_get_assigned_option(&test_fmt, tst, "obsolete", 1); + lines = config_get_assigned_option(mgr, tst, "obsolete", 1); tt_assert(!lines); - lines = config_get_assigned_option(&test_fmt, tst, "nonesuch", 1); + lines = config_get_assigned_option(mgr, tst, "nonesuch", 1); tt_assert(!lines); - lines = config_get_assigned_option(&test_fmt, tst, "mixedlines", 1); + lines = config_get_assigned_option(mgr, tst, "mixedlines", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "LineTypeA"); tt_str_op(lines->value, OP_EQ, "i d"); @@ -745,7 +772,7 @@ test_confparse_get_assigned(void *arg) tt_assert(lines->next->next == NULL); config_free_lines(lines); - lines = config_get_assigned_option(&test_fmt, tst, "linetypeb", 1); + lines = config_get_assigned_option(mgr, tst, "linetypeb", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "LineTypeB"); tt_str_op(lines->value, OP_EQ, "i c"); @@ -754,7 +781,7 @@ test_confparse_get_assigned(void *arg) tor_free(tst->s); tst->s = tor_strdup("Hello\nWorld"); - lines = config_get_assigned_option(&test_fmt, tst, "s", 1); + lines = config_get_assigned_option(mgr, tst, "s", 1); tt_assert(lines); tt_str_op(lines->key, OP_EQ, "s"); tt_str_op(lines->value, OP_EQ, "\"Hello\\nWorld\""); @@ -762,8 +789,9 @@ test_confparse_get_assigned(void *arg) config_free_lines(lines); done: - config_free(&test_fmt, tst); + config_free(mgr, tst); config_free_lines(lines); + config_mgr_free(mgr); } /* Another variant, which accepts and stores unrecognized lines.*/ @@ -786,8 +814,9 @@ static config_format_t etest_fmt = { test_deprecation_notes, test_vars, test_validate_cb, - test_free_cb, + NULL, &extra, + -1, }; /* Try out the feature where we can store unrecognized lines and dump them @@ -796,24 +825,26 @@ static void test_confparse_extra_lines(void *arg) { (void)arg; - test_struct_t *tst = config_new(&etest_fmt); + config_mgr_t *mgr = config_mgr_new(&etest_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = config_new(mgr); config_line_t *lines = NULL; char *msg = NULL, *dump = NULL; - config_init(&etest_fmt, tst); + config_init(mgr, tst); int r = config_get_lines( "unknotty addita\n" "pos 99\n" "wombat knish\n", &lines, 0); tt_int_op(r, OP_EQ, 0); - r = config_assign(&etest_fmt, tst, lines, 0, &msg); + r = config_assign(mgr, tst, lines, 0, &msg); tt_int_op(r, OP_EQ, 0); tt_ptr_op(msg, OP_EQ, NULL); tt_assert(tst->extra_lines); - dump = config_dump(&etest_fmt, NULL, tst, 1, 0); + dump = config_dump(mgr, NULL, tst, 1, 0); tt_str_op(dump, OP_EQ, "pos 99\n" "unknotty addita\n" @@ -823,7 +854,8 @@ test_confparse_extra_lines(void *arg) tor_free(msg); tor_free(dump); config_free_lines(lines); - config_free(&etest_fmt, tst); + config_free(mgr, tst); + config_mgr_free(mgr); } static void @@ -889,12 +921,106 @@ static void test_confparse_check_ok_fail(void *arg) { (void)arg; - test_struct_t *tst = config_new(&test_fmt); + config_mgr_t *mgr = config_mgr_new(&test_fmt); + config_mgr_freeze(mgr); + test_struct_t *tst = config_new(mgr); tst->pos = -10; - tt_assert(! config_check_ok(&test_fmt, tst, LOG_INFO)); + tt_assert(! config_check_ok(mgr, tst, LOG_INFO)); + + done: + config_free(mgr, tst); + config_mgr_free(mgr); +} + +static void +test_confparse_list_vars(void *arg) +{ + (void)arg; + config_mgr_t *mgr = config_mgr_new(&test_fmt); + smartlist_t *vars = config_mgr_list_vars(mgr); + smartlist_t *varnames = smartlist_new(); + char *joined = NULL; + + tt_assert(vars); + SMARTLIST_FOREACH(vars, config_var_t *, cv, + smartlist_add(varnames, (void*)cv->member.name)); + smartlist_sort_strings(varnames); + joined = smartlist_join_strings(varnames, "::", 0, NULL); + tt_str_op(joined, OP_EQ, + "LineTypeA::" + "LineTypeB::" + "MixedHiddenLines::" + "MixedLines::" + "VisibleLineB::" + "__HiddenInt::" + "__HiddenLineA::" + "autobool::" + "boolean::" + "csv::" + "csv_interval::" + "dbl::" + "deprecated_int::" + "fn::" + "i::" + "interval::" + "lines::" + "mem::" + "msec_interval::" + "obsolete::" + "pos::" + "routerset::" + "s::" + "time::" + "u64"); + + done: + tor_free(joined); + smartlist_free(varnames); + smartlist_free(vars); + config_mgr_free(mgr); +} + +static void +test_confparse_list_deprecated(void *arg) +{ + (void)arg; + config_mgr_t *mgr = config_mgr_new(&test_fmt); + smartlist_t *vars = config_mgr_list_deprecated_vars(mgr); + char *joined = NULL; + + tt_assert(vars); + smartlist_sort_strings(vars); + joined = smartlist_join_strings(vars, "::", 0, NULL); + + tt_str_op(joined, OP_EQ, "deprecated_int"); + + done: + tor_free(joined); + smartlist_free(vars); + config_mgr_free(mgr); +} + +static void +test_confparse_find_option_name(void *arg) +{ + (void)arg; + config_mgr_t *mgr = config_mgr_new(&test_fmt); + + // exact match + tt_str_op(config_find_option_name(mgr, "u64"), OP_EQ, "u64"); + // case-insensitive match + tt_str_op(config_find_option_name(mgr, "S"), OP_EQ, "s"); + tt_str_op(config_find_option_name(mgr, "linetypea"), OP_EQ, "LineTypeA"); + // prefix match + tt_str_op(config_find_option_name(mgr, "deprec"), OP_EQ, "deprecated_int"); + // explicit abbreviation + tt_str_op(config_find_option_name(mgr, "uint"), OP_EQ, "pos"); + tt_str_op(config_find_option_name(mgr, "UINT"), OP_EQ, "pos"); + // no match + tt_ptr_op(config_find_option_name(mgr, "absent"), OP_EQ, NULL); done: - config_free(&test_fmt, tst); + config_mgr_free(mgr); } #define CONFPARSE_TEST(name, flags) \ @@ -933,5 +1059,8 @@ struct testcase_t confparse_tests[] = { CONFPARSE_TEST(extra_lines, 0), CONFPARSE_TEST(unitparse, 0), CONFPARSE_TEST(check_ok_fail, 0), + CONFPARSE_TEST(list_vars, 0), + CONFPARSE_TEST(list_deprecated, 0), + CONFPARSE_TEST(find_option_name, 0), END_OF_TESTCASES }; diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index e57bd02584..edfd0c74e1 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -479,8 +479,7 @@ static or_options_t *mock_options = NULL; static void init_mock_options(void) { - mock_options = tor_malloc(sizeof(or_options_t)); - memset(mock_options, 0, sizeof(or_options_t)); + mock_options = options_new(); mock_options->TestingTorNetwork = 1; mock_options->DataDirectory = tor_strdup(get_fname_rnd("datadir_tmp")); mock_options->CacheDirectory = tor_strdup(mock_options->DataDirectory); diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c index c43b21c673..c8dd4b03ea 100644 --- a/src/test/test_entrynodes.c +++ b/src/test/test_entrynodes.c @@ -5,6 +5,7 @@ #define CIRCUITLIST_PRIVATE #define CIRCUITBUILD_PRIVATE +#define CONFIG_PRIVATE #define STATEFILE_PRIVATE #define ENTRYNODES_PRIVATE #define ROUTERLIST_PRIVATE @@ -201,7 +202,7 @@ big_fake_network_setup(const struct testcase_t *testcase) smartlist_add(big_fake_net_nodes, n); } - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); dummy_consensus = tor_malloc_zero(sizeof(networkstatus_t)); if (reasonably_future_consensus) { /* Make the dummy consensus valid in 6 hours, and expiring in 7 hours. */ @@ -235,12 +236,12 @@ mock_randomize_time_no_randomization(time_t a, time_t b) return a; } -static or_options_t mocked_options; +static or_options_t *mocked_options; static const or_options_t * mock_get_options(void) { - return &mocked_options; + return mocked_options; } #define TEST_IPV4_ADDR "123.45.67.89" @@ -259,7 +260,7 @@ test_node_preferred_orport(void *arg) tor_addr_port_t ap; /* Setup options */ - memset(&mocked_options, 0, sizeof(mocked_options)); + mocked_options = options_new(); /* We don't test ClientPreferIPv6ORPort here, because it's used in * nodelist_set_consensus to setup node.ipv6_preferred, which we set * directly. */ @@ -282,8 +283,8 @@ test_node_preferred_orport(void *arg) /* Check the preferred address is IPv4 if we're only using IPv4, regardless * of whether we prefer it or not */ - mocked_options.ClientUseIPv4 = 1; - mocked_options.ClientUseIPv6 = 0; + mocked_options->ClientUseIPv4 = 1; + mocked_options->ClientUseIPv6 = 0; node.ipv6_preferred = 0; node_get_pref_orport(&node, &ap); tt_assert(tor_addr_eq(&ap.addr, &ipv4_addr)); @@ -296,8 +297,8 @@ test_node_preferred_orport(void *arg) /* Check the preferred address is IPv4 if we're using IPv4 and IPv6, but * don't prefer the IPv6 address */ - mocked_options.ClientUseIPv4 = 1; - mocked_options.ClientUseIPv6 = 1; + mocked_options->ClientUseIPv4 = 1; + mocked_options->ClientUseIPv6 = 1; node.ipv6_preferred = 0; node_get_pref_orport(&node, &ap); tt_assert(tor_addr_eq(&ap.addr, &ipv4_addr)); @@ -305,28 +306,29 @@ test_node_preferred_orport(void *arg) /* Check the preferred address is IPv6 if we prefer it and * ClientUseIPv6 is 1, regardless of ClientUseIPv4 */ - mocked_options.ClientUseIPv4 = 1; - mocked_options.ClientUseIPv6 = 1; + mocked_options->ClientUseIPv4 = 1; + mocked_options->ClientUseIPv6 = 1; node.ipv6_preferred = 1; node_get_pref_orport(&node, &ap); tt_assert(tor_addr_eq(&ap.addr, &ipv6_addr)); tt_assert(ap.port == ipv6_port); - mocked_options.ClientUseIPv4 = 0; + mocked_options->ClientUseIPv4 = 0; node_get_pref_orport(&node, &ap); tt_assert(tor_addr_eq(&ap.addr, &ipv6_addr)); tt_assert(ap.port == ipv6_port); /* Check the preferred address is IPv6 if we don't prefer it, but * ClientUseIPv4 is 0 */ - mocked_options.ClientUseIPv4 = 0; - mocked_options.ClientUseIPv6 = 1; - node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport(&mocked_options); + mocked_options->ClientUseIPv4 = 0; + mocked_options->ClientUseIPv6 = 1; + node.ipv6_preferred = fascist_firewall_prefer_ipv6_orport(mocked_options); node_get_pref_orport(&node, &ap); tt_assert(tor_addr_eq(&ap.addr, &ipv6_addr)); tt_assert(ap.port == ipv6_port); done: + or_options_free(mocked_options); UNMOCK(get_options); } diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index b4389f2d17..31a6540efc 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -295,7 +295,7 @@ helper_parse_options(const char *conf) if (ret != 0) { goto done; } - ret = config_assign(&options_format, opt, line, 0, &msg); + ret = config_assign(get_options_mgr(), opt, line, 0, &msg); if (ret != 0) { goto done; } diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index c0803a5a59..c5854f0ff8 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -1178,7 +1178,7 @@ test_introduce2(void *arg) MOCK(get_or_state, get_or_state_replacement); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_S_INTRO, flags); tt_assert(circ); @@ -1343,7 +1343,7 @@ test_rotate_descriptors(void *arg) (void) arg; - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); hs_init(); MOCK(get_or_state, get_or_state_replacement); @@ -1460,7 +1460,7 @@ test_build_update_descriptors(void *arg) MOCK(networkstatus_get_live_consensus, mock_networkstatus_get_live_consensus); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC", &mock_ns.valid_after); @@ -1691,7 +1691,7 @@ test_build_descriptors(void *arg) MOCK(networkstatus_get_live_consensus, mock_networkstatus_get_live_consensus); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC", &mock_ns.valid_after); @@ -1792,7 +1792,7 @@ test_upload_descriptors(void *arg) MOCK(networkstatus_get_live_consensus, mock_networkstatus_get_live_consensus); - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", &mock_ns.valid_after); diff --git a/src/test/test_options.c b/src/test/test_options.c index 64fcd011e7..a6bccdc524 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -96,7 +96,7 @@ clear_log_messages(void) opt->command = CMD_RUN_TOR; \ options_init(opt); \ \ - dflt = config_dup(&options_format, opt); \ + dflt = config_dup(get_options_mgr(), opt); \ clear_log_messages(); \ } while (0) @@ -196,7 +196,7 @@ test_options_validate_impl(const char *configuration, if (r) goto done; - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); if (phase == PH_ASSIGN) { if (test_options_checkmsgs(configuration, expect_errmsg, expect_log_severity, @@ -304,7 +304,7 @@ test_have_enough_mem_for_dircache(void *arg) r = config_get_lines(configuration, &cl, 1); tt_int_op(r, OP_EQ, 0); - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); tt_int_op(r, OP_EQ, 0); /* 300 MB RAM available, DirCache enabled */ @@ -327,7 +327,7 @@ test_have_enough_mem_for_dircache(void *arg) r = config_get_lines(configuration, &cl, 1); tt_int_op(r, OP_EQ, 0); - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); tt_int_op(r, OP_EQ, 0); /* 300 MB RAM available, DirCache enabled, Bridge */ @@ -350,7 +350,7 @@ test_have_enough_mem_for_dircache(void *arg) r = config_get_lines(configuration, &cl, 1); tt_int_op(r, OP_EQ, 0); - r = config_assign(&options_format, opt, cl, 0, &msg); + r = config_assign(get_options_mgr(), opt, cl, 0, &msg); tt_int_op(r, OP_EQ, 0); /* 200 MB RAM available, DirCache disabled */ @@ -438,7 +438,7 @@ get_options_test_data(const char *conf) rv = config_get_lines(conf, &cl, 1); tt_int_op(rv, OP_EQ, 0); - rv = config_assign(&options_format, result->opt, cl, 0, &msg); + rv = config_assign(get_options_mgr(), result->opt, cl, 0, &msg); if (msg) { /* Display the parse error message by comparing it with an empty string */ tt_str_op(msg, OP_EQ, ""); @@ -449,7 +449,7 @@ get_options_test_data(const char *conf) result->opt->TokenBucketRefillInterval = 1; rv = config_get_lines(TEST_OPTIONS_OLD_VALUES, &cl, 1); tt_int_op(rv, OP_EQ, 0); - rv = config_assign(&options_format, result->def_opt, cl, 0, &msg); + rv = config_assign(get_options_mgr(), result->def_opt, cl, 0, &msg); if (msg) { /* Display the parse error message by comparing it with an empty string */ tt_str_op(msg, OP_EQ, ""); diff --git a/src/test/test_pt.c b/src/test/test_pt.c index 87e3ba356c..362c6664db 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -352,7 +352,7 @@ test_pt_configure_proxy(void *arg) managed_proxy_t *mp = NULL; (void) arg; - dummy_state = tor_malloc_zero(sizeof(or_state_t)); + dummy_state = or_state_new(); MOCK(process_read_stdout, process_read_stdout_replacement); MOCK(get_or_state, |