diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-10-24 17:35:15 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-10-24 20:37:53 -0400 |
commit | f796bf3aa5f42451db9a7b8be10e97cb17b2f54c (patch) | |
tree | 7dbad297ff6d8e4b617e825ff3f45a88026f72b9 /src/test/test_confmgr.c | |
parent | d17aa0930872e391a19480f65545a029e2359dd7 (diff) | |
download | tor-f796bf3aa5f42451db9a7b8be10e97cb17b2f54c.tar.gz tor-f796bf3aa5f42451db9a7b8be10e97cb17b2f54c.zip |
Extend confmgr tests to handle validation callbacks.
Diffstat (limited to 'src/test/test_confmgr.c')
-rw-r--r-- | src/test/test_confmgr.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/test/test_confmgr.c b/src/test/test_confmgr.c index d5c73b48e4..bcacfe953d 100644 --- a/src/test/test_confmgr.c +++ b/src/test/test_confmgr.c @@ -43,6 +43,8 @@ typedef struct { int fuzziness; char *alpacaname; int n_wings; /* deprecated; alpacas don't have wings. */ + + int square_fuzziness; /* Derived from fuzziness. */ } alpaca_cfg_t; /* @@ -105,6 +107,84 @@ static config_abbrev_t llama_abbrevs[] = { { NULL, NULL, 0, 0 }, }; +static int +legacy_validate_pasture(const void *old_, void *obj, char **msg_out) +{ + const pasture_cfg_t *old = old_; + pasture_cfg_t *p = obj; + + // llamas can't find their way home if the letters are lowercase. + if (p->address) + tor_strupper(p->address); + + if (old && old->address && + (!p->address || strcmp(old->address, p->address))) { + *msg_out = tor_strdup("You can't move a pasture."); + return -1; + } + + return 0; +} + +static int +validate_llama(const void *obj, char **msg_out) +{ + const llama_cfg_t *llama = obj; + tor_assert(llama->magic == 0x11aa11); + + if (! llama->llamaname || strlen(llama->llamaname) == 0) { + *msg_out = tor_strdup("A llama has no name!?"); + return -1; + } + + if (strspn(llama->llamaname, "0123456789") == strlen(llama->llamaname)) { + *msg_out = tor_strdup("It is not a number; it is a free llama!"); + return -1; + } + + return 0; +} + +static int +check_transition_alpaca(const void *old_, const void *new_, char **msg_out) +{ + const alpaca_cfg_t *old_alpaca = old_; + const alpaca_cfg_t *new_alpaca = new_; + + tor_assert(old_alpaca && new_alpaca); + tor_assert(old_alpaca->magic == 0xa15aca); + tor_assert(new_alpaca->magic == 0xa15aca); + + if (old_alpaca->fuzziness > new_alpaca->fuzziness) { + *msg_out = tor_strdup("An alpaca only becomes more fuzzy over time."); + return -1; + } + + return 0; +} + +static int +post_normalize_llama(void *obj, char **msg_out) +{ + (void)msg_out; + llama_cfg_t *llama = obj; + tor_assert(llama->magic == 0x11aa11); + tor_assert(llama->llamaname); // we have already checked for a NULL name. + tor_free(llama->description); + tor_asprintf(&llama->description, "A llama called %s.", llama->llamaname); + return 0; +} + +static int +pre_normalize_alpaca(void *obj, char **msg_out) +{ + (void)msg_out; + alpaca_cfg_t *alpaca = obj; + tor_assert(alpaca->magic == 0xa15aca); + alpaca->square_fuzziness = alpaca->fuzziness * alpaca->fuzziness; + return 0; +} + static const config_format_t pasture_fmt = { sizeof(pasture_cfg_t), { @@ -114,6 +194,7 @@ static const config_format_t pasture_fmt = { }, .vars = pasture_vars, .config_suite_offset = offsetof(pasture_cfg_t, subobjs), + .legacy_validate_fn = legacy_validate_pasture, }; static const config_format_t llama_fmt = { @@ -128,6 +209,8 @@ static const config_format_t llama_fmt = { .deprecations = llama_deprecations, .abbrevs = llama_abbrevs, .clear_fn = clear_llama_cfg, + .validate_fn = validate_llama, + .post_normalize_fn = post_normalize_llama, }; static const config_format_t alpaca_fmt = { @@ -140,6 +223,8 @@ static const config_format_t alpaca_fmt = { .vars = alpaca_vars, .config_suite_offset = -1, .deprecations = alpaca_deprecations, + .pre_normalize_fn = pre_normalize_alpaca, + .check_transition_fn = check_transition_alpaca, }; #define LLAMA_IDX 0 @@ -313,6 +398,95 @@ test_confmgr_dump(void *arg) tor_free(s); } +static pasture_cfg_t * +parse_and_validate(config_mgr_t *mgr, + const char *inp, const pasture_cfg_t *old, char **msg_out) +{ + pasture_cfg_t *p = config_new(mgr); + pasture_cfg_t *result = NULL; + config_line_t *lines = NULL; + + config_init(mgr, p); // set defaults. + int r = config_get_lines(inp, &lines, 0); + tt_int_op(r, OP_EQ, 0); + r = config_assign(mgr, p, lines, 0, msg_out); + tt_int_op(r, OP_EQ, 0); + tor_free(*msg_out); // sets it to NULL + r = config_validate(mgr, old, p, msg_out); + if (r < 0) + goto done; + + tt_ptr_op(*msg_out, OP_EQ, NULL); + result = p; + p = NULL; // prevent free + done: + config_free(mgr, p); + config_free_lines(lines); + return result; +} + +static void +test_confmgr_validate(void *arg) +{ + (void)arg; + char *msg = NULL; + config_mgr_t *mgr = get_mgr(true); + pasture_cfg_t *p_orig, *p=NULL; + + p_orig = parse_and_validate(mgr, "Llamaname Quest\n" + "Address 99 camelid way\n" + "Fuzziness 8\n", NULL, &msg); + tt_assert(p_orig); + + // Make sure normalization code was run. + const alpaca_cfg_t *ac0 = config_mgr_get_obj(mgr, p_orig, ALPACA_IDX); + const llama_cfg_t *lc0 = config_mgr_get_obj(mgr, p_orig, LLAMA_IDX); + tt_int_op(ac0->fuzziness, OP_EQ, 8); + tt_int_op(ac0->square_fuzziness, OP_EQ, 64); + tt_str_op(lc0->description, OP_EQ, "A llama called Quest."); + tt_str_op(p_orig->address, OP_EQ, "99 CAMELID WAY"); + + // try a bad llamaname. + p = parse_and_validate(mgr, "llamaname 123", p_orig, &msg); + tt_assert(!p); + tt_str_op(msg, OP_EQ, "It is not a number; it is a free llama!"); + tor_free(msg); + + // try a llamaname that would crash the post_normalize step, if it ran. + p = parse_and_validate(mgr, "", p_orig, &msg); + tt_assert(!p); + tt_str_op(msg, OP_EQ, "A llama has no name!?"); + tor_free(msg); + + // Verify that a transition to a less fuzzy alpaca fails. + p = parse_and_validate(mgr, "Llamaname Quest\n" + "Address 99 camelid way\n" + "Fuzziness 4\n", p_orig, &msg); + tt_assert(!p); + tt_str_op(msg, OP_EQ, "An alpaca only becomes more fuzzy over time."); + tor_free(msg); + + // Try a transition to a more fuzzy alpaca; it should work fine. + p = parse_and_validate(mgr, "Llamaname Mercutio\n" + // the default fuzziness is 50 + "Address 99 camelid way\n", p_orig, &msg); + tt_assert(p); + config_free(mgr, p); + + // Verify that we can't move the pasture. + p = parse_and_validate(mgr, "Llamaname Montague\n" + // the default fuzziness is 50 + "Address 99 ungulate st\n", p_orig, &msg); + tt_assert(!p); + tt_str_op(msg, OP_EQ, "You can't move a pasture."); + + done: + config_free(mgr, p); + config_free(mgr, p_orig); + config_mgr_free(mgr); + tor_free(msg); +} + #define CONFMGR_TEST(name, flags) \ { #name, test_confmgr_ ## name, flags, NULL, NULL } @@ -321,5 +495,6 @@ struct testcase_t confmgr_tests[] = { CONFMGR_TEST(magic, 0), CONFMGR_TEST(parse, 0), CONFMGR_TEST(dump, 0), + CONFMGR_TEST(validate, 0), END_OF_TESTCASES }; |