]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-conf-parser.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2015 Ronny Chevalier
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include "conf-parser.h"
26 #include "string-util.h"
30 static void test_config_parse_path_one(const char *rvalue
, const char *expected
) {
31 _cleanup_free_
char *path
= NULL
;
33 assert_se(config_parse_path("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &path
, NULL
) >= 0);
34 assert_se(streq_ptr(expected
, path
));
37 static void test_config_parse_log_level_one(const char *rvalue
, int expected
) {
40 assert_se(config_parse_log_level("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &log_level
, NULL
) >= 0);
41 assert_se(expected
== log_level
);
44 static void test_config_parse_log_facility_one(const char *rvalue
, int expected
) {
47 assert_se(config_parse_log_facility("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &log_facility
, NULL
) >= 0);
48 assert_se(expected
== log_facility
);
51 static void test_config_parse_iec_size_one(const char *rvalue
, size_t expected
) {
54 assert_se(config_parse_iec_size("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &iec_size
, NULL
) >= 0);
55 assert_se(expected
== iec_size
);
58 static void test_config_parse_si_size_one(const char *rvalue
, size_t expected
) {
61 assert_se(config_parse_si_size("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &si_size
, NULL
) >= 0);
62 assert_se(expected
== si_size
);
65 static void test_config_parse_int_one(const char *rvalue
, int expected
) {
68 assert_se(config_parse_int("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &v
, NULL
) >= 0);
69 assert_se(expected
== v
);
72 static void test_config_parse_unsigned_one(const char *rvalue
, unsigned expected
) {
75 assert_se(config_parse_unsigned("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &v
, NULL
) >= 0);
76 assert_se(expected
== v
);
79 static void test_config_parse_strv_one(const char *rvalue
, char **expected
) {
80 _cleanup_strv_free_
char **strv
= NULL
;
82 assert_se(config_parse_strv("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &strv
, NULL
) >= 0);
83 assert_se(strv_equal(expected
, strv
));
86 static void test_config_parse_mode_one(const char *rvalue
, mode_t expected
) {
89 assert_se(config_parse_mode("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &v
, NULL
) >= 0);
90 assert_se(expected
== v
);
93 static void test_config_parse_sec_one(const char *rvalue
, usec_t expected
) {
96 assert_se(config_parse_sec("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue
, &v
, NULL
) >= 0);
97 assert_se(expected
== v
);
100 static void test_config_parse_nsec_one(const char *rvalue
, nsec_t expected
) {
103 assert_se(config_parse_nsec("unit", "filename", 1, "nsection", 1, "lvalue", 0, rvalue
, &v
, NULL
) >= 0);
104 assert_se(expected
== v
);
107 static void test_config_parse_path(void) {
108 test_config_parse_path_one("/path", "/path");
109 test_config_parse_path_one("/path//////////", "/path");
110 test_config_parse_path_one("///path/foo///bar////bar//", "/path/foo/bar/bar");
111 test_config_parse_path_one("/path/\xc3\x80", "/path/\xc3\x80");
113 test_config_parse_path_one("not_absolute/path", NULL
);
114 test_config_parse_path_one("/path/\xc3\x7f", NULL
);
117 static void test_config_parse_log_level(void) {
118 test_config_parse_log_level_one("debug", LOG_DEBUG
);
119 test_config_parse_log_level_one("info", LOG_INFO
);
121 test_config_parse_log_level_one("garbage", 0);
124 static void test_config_parse_log_facility(void) {
125 test_config_parse_log_facility_one("mail", LOG_MAIL
);
126 test_config_parse_log_facility_one("user", LOG_USER
);
128 test_config_parse_log_facility_one("garbage", 0);
131 static void test_config_parse_iec_size(void) {
132 test_config_parse_iec_size_one("1024", 1024);
133 test_config_parse_iec_size_one("2K", 2048);
134 test_config_parse_iec_size_one("10M", 10 * 1024 * 1024);
135 test_config_parse_iec_size_one("1G", 1 * 1024 * 1024 * 1024);
136 test_config_parse_iec_size_one("0G", 0);
137 test_config_parse_iec_size_one("0", 0);
139 test_config_parse_iec_size_one("-982", 0);
140 test_config_parse_iec_size_one("49874444198739873000000G", 0);
141 test_config_parse_iec_size_one("garbage", 0);
144 static void test_config_parse_si_size(void) {
145 test_config_parse_si_size_one("1024", 1024);
146 test_config_parse_si_size_one("2K", 2000);
147 test_config_parse_si_size_one("10M", 10 * 1000 * 1000);
148 test_config_parse_si_size_one("1G", 1 * 1000 * 1000 * 1000);
149 test_config_parse_si_size_one("0G", 0);
150 test_config_parse_si_size_one("0", 0);
152 test_config_parse_si_size_one("-982", 0);
153 test_config_parse_si_size_one("49874444198739873000000G", 0);
154 test_config_parse_si_size_one("garbage", 0);
157 static void test_config_parse_int(void) {
158 test_config_parse_int_one("1024", 1024);
159 test_config_parse_int_one("-1024", -1024);
160 test_config_parse_int_one("0", 0);
162 test_config_parse_int_one("99999999999999999999999999999999999999999999999999999999", -1);
163 test_config_parse_int_one("-99999999999999999999999999999999999999999999999999999999", -1);
164 test_config_parse_int_one("1G", -1);
165 test_config_parse_int_one("garbage", -1);
168 static void test_config_parse_unsigned(void) {
169 test_config_parse_unsigned_one("10241024", 10241024);
170 test_config_parse_unsigned_one("1024", 1024);
171 test_config_parse_unsigned_one("0", 0);
173 test_config_parse_unsigned_one("99999999999999999999999999999999999999999999999999999999", 0);
174 test_config_parse_unsigned_one("1G", 0);
175 test_config_parse_unsigned_one("garbage", 0);
176 test_config_parse_unsigned_one("1000garbage", 0);
179 static void test_config_parse_strv(void) {
180 test_config_parse_strv_one("", STRV_MAKE_EMPTY
);
181 test_config_parse_strv_one("foo", STRV_MAKE("foo"));
182 test_config_parse_strv_one("foo bar foo", STRV_MAKE("foo", "bar", "foo"));
183 test_config_parse_strv_one("\"foo bar\" foo", STRV_MAKE("foo bar", "foo"));
184 test_config_parse_strv_one("\xc3\x80", STRV_MAKE("\xc3\x80"));
185 test_config_parse_strv_one("\xc3\x7f", STRV_MAKE_EMPTY
);
188 static void test_config_parse_mode(void) {
189 test_config_parse_mode_one("777", 0777);
190 test_config_parse_mode_one("644", 0644);
192 test_config_parse_mode_one("-777", 0);
193 test_config_parse_mode_one("999", 0);
194 test_config_parse_mode_one("garbage", 0);
195 test_config_parse_mode_one("777garbage", 0);
196 test_config_parse_mode_one("777 garbage", 0);
199 static void test_config_parse_sec(void) {
200 test_config_parse_sec_one("1", 1 * USEC_PER_SEC
);
201 test_config_parse_sec_one("1s", 1 * USEC_PER_SEC
);
202 test_config_parse_sec_one("100ms", 100 * USEC_PER_MSEC
);
203 test_config_parse_sec_one("5min 20s", 5 * 60 * USEC_PER_SEC
+ 20 * USEC_PER_SEC
);
205 test_config_parse_sec_one("-1", 0);
206 test_config_parse_sec_one("10foo", 0);
207 test_config_parse_sec_one("garbage", 0);
210 static void test_config_parse_nsec(void) {
211 test_config_parse_nsec_one("1", 1);
212 test_config_parse_nsec_one("1s", 1 * NSEC_PER_SEC
);
213 test_config_parse_nsec_one("100ms", 100 * NSEC_PER_MSEC
);
214 test_config_parse_nsec_one("5min 20s", 5 * 60 * NSEC_PER_SEC
+ 20 * NSEC_PER_SEC
);
216 test_config_parse_nsec_one("-1", 0);
217 test_config_parse_nsec_one("10foo", 0);
218 test_config_parse_nsec_one("garbage", 0);
221 static void test_config_parse_iec_uint64(void) {
223 assert_se(config_parse_iec_uint64(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset
, NULL
) == 0);
224 assert_se(offset
== 4 * 1024 * 1024);
226 assert_se(config_parse_iec_uint64(NULL
, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset
, NULL
) == 0);
229 #define x10(x) x x x x x x x x x x
230 #define x100(x) x10(x10(x))
231 #define x1000(x) x10(x100(x))
233 static const char* const config_file
[] = {
238 "setting1=1", /* no terminating newline */
240 "\n\n\n\n[Section]\n\n\n"
241 "setting1=1", /* some whitespace, no terminating newline */
247 "setting1=1\n", /* repeated settings */
250 "setting1=1\\\n" /* normal continuation */
255 "setting1=1\\\\\\\n" /* continuation with trailing escape symbols */
256 "\\\\2\n", /* note that C requires one level of escaping, so the
257 * parser gets "…1 BS BS BS NL BS BS 2 NL", which
258 * it translates into "…1 BS BS SP BS BS 2" */
261 "setting1=" /* a line above LINE_MAX length */
266 "setting1=" /* a line above LINE_MAX length, with continuation */
271 "setting1=" /* a line above the allowed limit: 9 + 1050000 + 1 */
272 x1000(x1000("x") x10("abcde")) "\n",
275 "setting1=" /* many continuation lines, together above the limit */
276 x1000(x1000("x") x10("abcde") "\\\n") "xxx",
279 static void test_config_parse(unsigned i
, const char *s
) {
280 char name
[] = "/tmp/test-conf-parser.XXXXXX";
282 _cleanup_fclose_
FILE *f
= NULL
;
283 _cleanup_free_
char *setting1
= NULL
;
285 const ConfigTableItem items
[] = {
286 { "Section", "setting1", config_parse_string
, 0, &setting1
},
290 log_info("== %s[%i] ==", __func__
, i
);
292 fd
= mkostemp_safe(name
);
294 assert_se((size_t) write(fd
, s
, strlen(s
)) == strlen(s
));
296 assert_se(lseek(fd
, 0, SEEK_SET
) == 0);
297 assert_se(f
= fdopen(fd
, "r"));
300 int config_parse(const char *unit,
301 const char *filename,
303 const char *sections,
304 ConfigItemLookup lookup,
312 r
= config_parse(NULL
, name
, f
,
314 config_item_table_lookup
, items
,
315 CONFIG_PARSE_WARN
, NULL
);
320 assert_se(streq(setting1
, "1"));
325 assert_se(streq(setting1
, "1 2 3"));
330 assert_se(streq(setting1
, "1\\\\ \\\\2"));
335 assert_se(streq(setting1
, x1000("ABCD")));
340 assert_se(streq(setting1
, x1000("ABCD") " foobar"));
344 assert_se(r
== -ENOBUFS
);
345 assert_se(setting1
== NULL
);
350 int main(int argc
, char **argv
) {
353 log_parse_environment();
356 test_config_parse_path();
357 test_config_parse_log_level();
358 test_config_parse_log_facility();
359 test_config_parse_iec_size();
360 test_config_parse_si_size();
361 test_config_parse_int();
362 test_config_parse_unsigned();
363 test_config_parse_strv();
364 test_config_parse_mode();
365 test_config_parse_sec();
366 test_config_parse_nsec();
367 test_config_parse_iec_uint64();
369 for (i
= 0; i
< ELEMENTSOF(config_file
); i
++)
370 test_config_parse(i
, config_file
[i
]);