2 * Copyright (c) 2013, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/param.h>
35 #include <cfzy_list.h>
36 #include <cfzy_htable.h>
37 #include <cfzy_confnode.h>
38 #include <cfzy_conftree.h>
39 #include <cfzy_dotconfig.h>
40 #include <cfzy_c_hdr.h>
42 #include "test_conftree.h"
44 #define LOG(level, fmt, args...) \
45 CFZY_LOG("test_conftree", level, fmt, ##args)
48 #define CANNOT_PARSE_CONFTREE -1
49 #define CANNOT_DUMP_CONFTREE -2
50 #define CANNOT_FIND_SYMBOL -3
51 #define CANNOT_EVAL_CONFTREE -4
52 #define CANNOT_GET_VALUE -5
53 #define CANNOT_SET_VALUE -6
54 #define INVALID_VALUE -7
55 #define CANNOT_FILTER_CONFTREE -8
56 #define CANNOT_SAVE_CONFTREE_VALUES -9
58 /* check that a node is set to the expected value */
59 static int test_one_confnode(const struct cfzy_conftree *conftree,
60 const char *name, int expected_value)
64 val = cfzy_confnode_get_boolvalue(name, conftree);
66 LOG(DEBUG, "cannot get node value\n");
67 return CANNOT_GET_VALUE;
69 if (val != expected_value) {
70 LOG(DEBUG, "invalid val for %s: val=%d, expect=%d\n",
71 name, val, expected_value);
78 static int test_one_conftree(const char *name)
80 struct cfzy_list_head *node_list = NULL;
81 struct cfzy_list_elt *e;
82 struct cfzy_conftree *conftree;
83 struct cfzy_confnode *n;
86 conftree = cfzy_conftree_new(name);
88 return CANNOT_PARSE_CONFTREE;
90 if (cfzy_conftree_evaluate(conftree) < 0) {
91 LOG(DEBUG, "cannot eval conftree\n");
92 cfzy_conftree_free(conftree);
93 return CANNOT_EVAL_CONFTREE;
96 if (cfzy_conftree_dump(conftree, "/tmp/conftree.dump") < 0) {
97 cfzy_conftree_free(conftree);
98 return CANNOT_DUMP_CONFTREE;
101 /* node value should be 1 (default) */
102 ret = test_one_confnode(conftree, "MENU1_CONFIG1", 1);
104 cfzy_conftree_free(conftree);
108 /* node value should be 0 (default) */
109 ret = test_one_confnode(conftree, "MENU1_CONFIG2", 0);
111 cfzy_conftree_free(conftree);
115 /* lookup for this node */
116 n = cfzy_htable_lookup(conftree->nodes_htable, "MENU1_CONFIG1");
118 LOG(DEBUG, "cannot find node\n");
119 cfzy_conftree_free(conftree);
120 return CANNOT_FIND_SYMBOL;
123 /* try to assign an invalid value: should fail */
124 if (cfzy_confnode_set_uservalue(n, "dummy") == 0) {
125 LOG(DEBUG, "set_uservalue returned 0 but should not\n");
126 cfzy_conftree_free(conftree);
127 return CANNOT_SET_VALUE;
130 /* set thiis node to NO */
131 if (cfzy_confnode_set_uservalue(n, "n") < 0) {
132 LOG(DEBUG, "cannot set node value\n");
133 cfzy_conftree_free(conftree);
134 return CANNOT_SET_VALUE;
137 /* node value should be 1 because we did not evaluate the tree */
138 ret = test_one_confnode(conftree, "MENU1_CONFIG1", 1);
140 cfzy_conftree_free(conftree);
144 if (cfzy_conftree_evaluate(conftree) < 0) {
145 LOG(DEBUG, "cannot eval conftree\n");
146 cfzy_conftree_free(conftree);
147 return CANNOT_EVAL_CONFTREE;
150 if (cfzy_conftree_dump(conftree, "/tmp/conftree2.dump") < 0) {
151 cfzy_conftree_free(conftree);
152 return CANNOT_DUMP_CONFTREE;
155 if (cfzy_conftree_save_values(conftree) < 0) {
156 cfzy_conftree_free(conftree);
157 return CANNOT_SAVE_CONFTREE_VALUES;
160 if (cfzy_conftree_dump(conftree, "/tmp/conftree3.dump") < 0) {
161 cfzy_conftree_free(conftree);
162 return CANNOT_DUMP_CONFTREE;
165 /* node value should now be 0 */
166 ret = test_one_confnode(conftree, "MENU1_CONFIG1", 0);
168 cfzy_conftree_free(conftree);
172 /* node value should now be 1 (depends on !MENU1_CONFIG1) */
173 ret = test_one_confnode(conftree, "MENU1_CONFIG2", 1);
175 cfzy_conftree_free(conftree);
179 /* test "choice" nodes */
181 /* node value should be 0 (default) */
182 ret = test_one_confnode(conftree, "MENU1_CHOICE1", 0);
184 cfzy_conftree_free(conftree);
188 /* node value should be 0 (default) */
189 ret = test_one_confnode(conftree, "MENU1_CHOICE2", 0);
191 cfzy_conftree_free(conftree);
195 /* node value should be 1 (default) */
196 ret = test_one_confnode(conftree, "MENU1_CHOICE3", 1);
198 cfzy_conftree_free(conftree);
202 /* lookup for this node */
203 n = cfzy_htable_lookup(conftree->nodes_htable, "MENU1_CHOICE1");
205 LOG(DEBUG, "cannot find node\n");
206 cfzy_conftree_free(conftree);
207 return CANNOT_FIND_SYMBOL;
210 /* set this node to Y */
211 if (cfzy_confnode_set_uservalue(n, "y") < 0) {
212 LOG(DEBUG, "cannot set node value\n");
213 cfzy_conftree_free(conftree);
214 return CANNOT_SET_VALUE;
217 if (cfzy_conftree_evaluate(conftree) < 0) {
218 LOG(DEBUG, "cannot eval conftree\n");
219 cfzy_conftree_free(conftree);
220 return CANNOT_EVAL_CONFTREE;
223 if (cfzy_conftree_dump(conftree, "/tmp/conftree.dump") < 0) {
224 cfzy_conftree_free(conftree);
225 return CANNOT_DUMP_CONFTREE;
228 /* node value should be 1 */
229 ret = test_one_confnode(conftree, "MENU1_CHOICE1", 1);
231 cfzy_conftree_free(conftree);
235 /* node value should be 0 */
236 ret = test_one_confnode(conftree, "MENU1_CHOICE2", 0);
238 cfzy_conftree_free(conftree);
242 /* node value should be 0 */
243 ret = test_one_confnode(conftree, "MENU1_CHOICE3", 0);
245 cfzy_conftree_free(conftree);
249 /* check the "menuconfig" node value, should be 1 (default) */
250 ret = test_one_confnode(conftree, "MENUCONFIG1", 1);
252 cfzy_conftree_free(conftree);
256 /* check which node were changed by the user */
257 node_list = cfzy_conftree_filter(conftree, CFZY_FILTER_F_USR_CHANGED);
258 if (node_list == NULL) {
259 cfzy_conftree_free(conftree);
260 return CANNOT_FILTER_CONFTREE;
262 TAILQ_FOREACH(e, node_list, next) {
264 printf("node %s\n", cfzy_confnode_name(n));
266 cfzy_list_free(node_list, NULL);
268 /* check which effective value changed */
269 node_list = cfzy_conftree_filter(conftree, CFZY_FILTER_F_EFF_CHANGED);
270 if (node_list == NULL) {
271 cfzy_conftree_free(conftree);
272 return CANNOT_FILTER_CONFTREE;
274 TAILQ_FOREACH(e, node_list, next) {
276 printf("node2 %s\n", cfzy_confnode_name(n));
278 cfzy_list_free(node_list, NULL);
280 cfzy_conftree_free(conftree);
284 static int test_one_invalid_conftree(const char *name)
286 struct cfzy_conftree *conftree;
288 conftree = cfzy_conftree_new(name);
289 if (conftree == NULL)
290 return CANNOT_PARSE_CONFTREE;
292 cfzy_conftree_free(conftree);
296 static void print_error(const char *in, int err)
298 printf("Unexpected return value when parsing: <%s>\n", in);
301 printf("Test returned success, but should not\n");
303 case CANNOT_PARSE_CONFTREE:
304 printf("Cannot parse configuration tree\n");
306 case CANNOT_DUMP_CONFTREE:
307 printf("Cannot dump configuration tree\n");
309 case CANNOT_EVAL_CONFTREE:
310 printf("Cannot evalulate configuration tree\n");
312 case CANNOT_FIND_SYMBOL:
313 printf("Cannot find symbol\n");
315 case CANNOT_GET_VALUE:
316 printf("Cannot get node value\n");
318 case CANNOT_SET_VALUE:
319 printf("Cannot set node value\n");
322 printf("invalid value\n");
324 case CANNOT_FILTER_CONFTREE:
325 printf("Cannot filter configuration tree\n");
327 case CANNOT_SAVE_CONFTREE_VALUES:
328 printf("Cannot save configuration tree values\n");
331 printf("Invalid error %d\n", err);
336 int test_conftree(const char *progname)
338 char filename[PATH_MAX];
342 cfzy_log_set_default_level(CFZY_LOG_DEBUG);
344 /* progdir is the directory where confizery-test is located */
345 progdir = strdup(progname);
348 /* unexistant file */
349 snprintf(filename, sizeof(filename), "foobar");
350 err = test_one_invalid_conftree(filename);
351 if (err != CANNOT_PARSE_CONFTREE) {
352 print_error(filename, err);
356 /* invalid command */
357 snprintf(filename, sizeof(filename),
358 "%s/../../src/confizery-test/invalid-configs/"
359 "invalid-command.cfzy", progdir);
360 err = test_one_invalid_conftree(filename);
361 if (err != CANNOT_PARSE_CONFTREE) {
362 print_error(filename, err);
366 /* invalid attribute */
367 snprintf(filename, sizeof(filename),
368 "%s/../../src/confizery-test/invalid-configs/"
369 "invalid-attribute.cfzy", progdir);
370 err = test_one_invalid_conftree(filename);
371 if (err != CANNOT_PARSE_CONFTREE) {
372 print_error(filename, err);
376 /* circular dependency */
377 snprintf(filename, sizeof(filename),
378 "%s/../../src/confizery-test/invalid-configs/"
379 "circular-dep.cfzy", progdir);
380 err = test_one_invalid_conftree(filename);
381 if (err != CANNOT_PARSE_CONFTREE) {
382 print_error(filename, err);
386 /* circular dependency */
387 snprintf(filename, sizeof(filename),
388 "%s/../../src/confizery-test/invalid-configs/"
389 "circular-dep2.cfzy", progdir);
390 err = test_one_invalid_conftree(filename);
391 if (err != CANNOT_PARSE_CONFTREE) {
392 print_error(filename, err);
396 /* node not closed */
397 snprintf(filename, sizeof(filename),
398 "%s/../../src/confizery-test/invalid-configs/"
399 "node-not-closed.cfzy", progdir);
400 err = test_one_invalid_conftree(filename);
401 if (err != CANNOT_PARSE_CONFTREE) {
402 print_error(filename, err);
406 /* duplicated config name */
407 snprintf(filename, sizeof(filename),
408 "%s/../../src/confizery-test/invalid-configs/"
409 "dup-name.cfzy", progdir);
410 err = test_one_invalid_conftree(filename);
411 if (err != CANNOT_PARSE_CONFTREE) {
412 print_error(filename, err);
416 /* invalid default value */
417 snprintf(filename, sizeof(filename),
418 "%s/../../src/confizery-test/invalid-configs/"
419 "invalid-value.cfzy", progdir);
420 err = test_one_invalid_conftree(filename);
421 if (err != CANNOT_PARSE_CONFTREE) {
422 print_error(filename, err);
426 /* invalid expression */
427 snprintf(filename, sizeof(filename),
428 "%s/../../src/confizery-test/invalid-configs/"
429 "invalid-expr.cfzy", progdir);
430 err = test_one_invalid_conftree(filename);
431 if (err != CANNOT_PARSE_CONFTREE) {
432 print_error(filename, err);
438 /* an example config */
439 snprintf(filename, sizeof(filename),
440 "%s/../../src/confizery-test/test-configs/"
441 "conftree.cfzy", progdir);
442 err = test_one_conftree(filename);
443 if (err != SUCCESS) {
444 print_error(filename, err);