Simple tests for nested configuration formats

One test makes sure that the toplevel magic numbers are distinct.

One test makes sure that we can parse a configuration object
with two sub-objects.
This commit is contained in:
Nick Mathewson 2019-08-27 11:12:34 -04:00
parent d9fe9f5ede
commit 8db3859cc6
3 changed files with 94 additions and 4 deletions

View File

@ -234,7 +234,7 @@ config_mgr_get_suite_ptr(const config_mgr_t *mgr, void *toplevel)
* to configuration objects for other modules. This function gets * to configuration objects for other modules. This function gets
* the sub-object for a particular modules. * the sub-object for a particular modules.
*/ */
static void * STATIC void *
config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx) config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
{ {
tor_assert(mgr); tor_assert(mgr);
@ -253,7 +253,7 @@ config_mgr_get_obj_mutable(const config_mgr_t *mgr, void *toplevel, int idx)
} }
/** As config_mgr_get_obj_mutable(), but return a const pointer. */ /** As config_mgr_get_obj_mutable(), but return a const pointer. */
static const void * STATIC const void *
config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx) config_mgr_get_obj(const config_mgr_t *mgr, const void *toplevel, int idx)
{ {
return config_mgr_get_obj_mutable(mgr, (void*)toplevel, idx); return config_mgr_get_obj_mutable(mgr, (void*)toplevel, idx);

View File

@ -146,6 +146,10 @@ bool config_var_is_contained(const config_var_t *var);
#ifdef CONFPARSE_PRIVATE #ifdef CONFPARSE_PRIVATE
STATIC void config_reset_line(const config_mgr_t *mgr, void *options, STATIC void config_reset_line(const config_mgr_t *mgr, void *options,
const char *key, int use_defaults); const char *key, int use_defaults);
STATIC void *config_mgr_get_obj_mutable(const config_mgr_t *mgr,
void *toplevel, int idx);
STATIC const void *config_mgr_get_obj(const config_mgr_t *mgr,
const void *toplevel, int idx);
#endif #endif
#endif /* !defined(TOR_CONFPARSE_H) */ #endif /* !defined(TOR_CONFPARSE_H) */

View File

@ -8,6 +8,7 @@
* formats and configuration objects. * formats and configuration objects.
*/ */
#define CONFPARSE_PRIVATE
#include "orconfig.h" #include "orconfig.h"
#include "core/or/or.h" #include "core/or/or.h"
@ -128,12 +129,15 @@ static const config_format_t alpaca_fmt = {
.deprecations = alpaca_deprecations, .deprecations = alpaca_deprecations,
}; };
#define LLAMA_IDX 0
#define ALPACA_IDX 1
static config_mgr_t * static config_mgr_t *
get_mgr(bool freeze) get_mgr(bool freeze)
{ {
config_mgr_t *mgr = config_mgr_new(&pasture_fmt); config_mgr_t *mgr = config_mgr_new(&pasture_fmt);
tt_int_op(0, OP_EQ, config_mgr_add_format(mgr, &llama_fmt)); tt_int_op(LLAMA_IDX, OP_EQ, config_mgr_add_format(mgr, &llama_fmt));
tt_int_op(1, OP_EQ, config_mgr_add_format(mgr, &alpaca_fmt)); tt_int_op(ALPACA_IDX, OP_EQ, config_mgr_add_format(mgr, &alpaca_fmt));
if (freeze) if (freeze)
config_mgr_freeze(mgr); config_mgr_freeze(mgr);
return mgr; return mgr;
@ -173,10 +177,92 @@ test_confmgr_init(void *arg)
config_mgr_free(mgr); 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);
done:
config_free_lines(lines);
config_free(mgr, p);
config_mgr_free(mgr);
tor_free(msg);
}
#define CONFMGR_TEST(name, flags) \ #define CONFMGR_TEST(name, flags) \
{ #name, test_confmgr_ ## name, flags, NULL, NULL } { #name, test_confmgr_ ## name, flags, NULL, NULL }
struct testcase_t confmgr_tests[] = { struct testcase_t confmgr_tests[] = {
CONFMGR_TEST(init, 0), CONFMGR_TEST(init, 0),
CONFMGR_TEST(magic, 0),
CONFMGR_TEST(parse, 0),
END_OF_TESTCASES END_OF_TESTCASES
}; };