1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#include <usual/cfparser.h>
#include <usual/time.h>
#include <usual/string.h>
#include <usual/logging.h>
#include <usual/fileutil.h>
#include "test_common.h"
struct Config1 {
char *str1;
char *def1;
int int1;
int bool1;
};
struct Config2 {
char *str2;
char *def2;
double time_double;
usec_t time_usec;
char *value2;
};
static struct Config1 cf1;
static struct Config2 cf2;
static void cleanup(void)
{
free(cf1.str1);
free(cf1.def1);
free(cf2.str2);
free(cf2.def2);
memset(&cf1, 0, sizeof(cf1));
memset(&cf2, 0, sizeof(cf2));
}
static const struct CfKey keys1 [] = {
CF_ABS("str1", CF_STR, cf1.str1, 0, NULL),
CF_ABS("def1", CF_STR, cf1.def1, 0, NULL),
CF_ABS("int", CF_INT, cf1.int1, 0, NULL),
CF_ABS("bool", CF_BOOL, cf1.bool1, 0, NULL),
{ NULL },
};
static const struct CfKey keys2 [] = {
CF_ABS("str2", CF_STR, cf2.str2, 0, NULL),
CF_ABS("def2", CF_STR, cf2.def2, 0, "somedefault"),
CF_ABS("time1", CF_TIME_USEC, cf2.time_usec, 0, NULL),
CF_ABS("time2", CF_TIME_DOUBLE, cf2.time_double, 0, NULL),
CF_ABS("test key", CF_STR, cf2.value2, 0, NULL),
{ NULL },
};
static const struct CfSect sects [] = {
{ "one", keys1 },
{ "two", keys2 },
{ NULL },
};
static struct CfContext cfdesc1 = { sects, NULL };
static void test_abs(void *ptr)
{
char buf[128];
enum LogLevel save_level;
int_check(1, cf_load_file(&cfdesc1, tdata("test_cfparser.ini")));
str_check(cf1.str1, "val1");
tt_assert(cf1.def1 == NULL);
str_check(cf2.str2, "val2");
str_check(cf2.def2, "somedefault");
tt_assert(cf2.time_usec == (3 * USEC / 2));
tt_assert(cf2.time_double == 2.5);
str_check("val1", cf_get(&cfdesc1, "one", "str1", buf, sizeof(buf)));
int_check(1, cf_set(&cfdesc1, "one", "str1", "val2"));
str_check("val2", cf_get(&cfdesc1, "one", "str1", buf, sizeof(buf)));
save_level = cf_stderr_level;
cf_stderr_level = LG_FATAL;
int_check(0, cf_set(&cfdesc1, "one", "nonexistent", "foo"));
cf_stderr_level = save_level;
end:
cleanup();
}
/*
* relative addressing.
*/
#define CF_REL_BASE struct Config1
static const struct CfKey rkeys1 [] = {
CF_REL("str1", CF_STR, str1, 0, NULL),
CF_REL("def1", CF_STR, def1, 0, NULL),
CF_REL("int", CF_INT, int1, 0, NULL),
CF_REL("bool", CF_BOOL, bool1, 0, NULL),
{ NULL },
};
#undef CF_REL_BASE
#define CF_REL_BASE struct Config2
static const struct CfKey rkeys2 [] = {
CF_REL("str2", CF_STR, str2, 0, NULL),
CF_REL("def2", CF_STR, def2, 0, "somedefault"),
CF_REL("time1", CF_TIME_USEC, time_usec, 0, NULL),
CF_REL("time2", CF_TIME_DOUBLE, time_double, 0, NULL),
CF_REL("test key", CF_STR, value2, 0, NULL),
{ NULL },
};
#undef CF_REL_BASE
static void *get_two(void *top_arg, const char *sect_name)
{
return &cf2;
}
static const struct CfSect rsects [] = {
{ "one", rkeys1 },
{ "two", rkeys2, get_two, },
{ NULL },
};
static struct CfContext cfdesc2 = { rsects, &cf1 };
static void test_rel(void *ptr)
{
char buf[128];
const char *fn = tdata("test_cfparser.ini");
cleanup();
int_check(1, cf_load_file(&cfdesc2, fn));
str_check(cf1.str1, "val1");
tt_assert(cf1.def1 == NULL);
str_check(cf2.str2, "val2");
str_check(cf2.def2, "somedefault");
tt_assert(cf2.time_usec == (3 * USEC / 2));
tt_assert(cf2.time_double == 2.5);
str_check("val1", cf_get(&cfdesc2, "one", "str1", buf, sizeof(buf)));
int_check(1, cf_set(&cfdesc2, "one", "str1", "val2"));
str_check("val2", cf_get(&cfdesc2, "one", "str1", buf, sizeof(buf)));
end:
cleanup();
}
/*
* Describe
*/
struct testcase_t cfparser_tests[] = {
{ "abs", test_abs },
{ "rel", test_rel },
END_OF_TESTCASES
};
|