mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Extend confmgr tests to handle validation callbacks.
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user