2 * test-api.c: test public API functions for conformance
4 * Copyright (C) 2009-2011 Red Hat Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Author: David Lutterkort <lutter@redhat.com>
32 #include <libxml/tree.h>
34 static const char *abs_top_srcdir;
36 static char *loadpath;
40 fprintf(stderr, "%d: Fatal error: %s\n", __LINE__, msg); \
44 static void testGet(CuTest *tc) {
49 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
50 CuAssertPtrNotNull(tc, aug);
51 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
53 /* Make sure we're looking at the right thing */
54 r = aug_match(aug, "/augeas/version/save/*", NULL);
55 CuAssertTrue(tc, r > 1);
56 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
58 /* aug_get returns 1 and the value if exactly one node matches */
59 r = aug_get(aug, "/augeas/version/save/*[1]", &value);
60 CuAssertIntEquals(tc, 1, r);
61 CuAssertPtrNotNull(tc, value);
62 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
64 /* aug_get returns 0 and no value when no node matches */
65 r = aug_get(aug, "/augeas/version/save/*[ last() + 1 ]", &value);
66 CuAssertIntEquals(tc, 0, r);
67 CuAssertPtrEquals(tc, NULL, value);
68 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
70 /* aug_get should return an error when multiple nodes match */
71 r = aug_get(aug, "/augeas/version/save/*", &value);
72 CuAssertIntEquals(tc, -1, r);
73 CuAssertPtrEquals(tc, NULL, value);
74 CuAssertIntEquals(tc, AUG_EMMATCH, aug_error(aug));
76 /* augeas should prepend context if relative path given */
77 r = aug_set(aug, "/augeas/context", "/augeas/version");
78 r = aug_get(aug, "save/*[1]", &value);
79 CuAssertIntEquals(tc, 1, r);
80 CuAssertPtrNotNull(tc, value);
81 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
83 /* augeas should still work with an empty context */
84 r = aug_set(aug, "/augeas/context", "");
85 r = aug_get(aug, "/augeas/version", &value);
86 CuAssertIntEquals(tc, 1, r);
87 CuAssertPtrNotNull(tc, value);
88 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
90 /* augeas should ignore trailing slashes in context */
91 r = aug_set(aug, "/augeas/context", "/augeas/version/");
92 r = aug_get(aug, "save/*[1]", &value);
93 CuAssertIntEquals(tc, 1, r);
94 CuAssertPtrNotNull(tc, value);
95 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
100 static void testSet(CuTest *tc) {
105 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
106 CuAssertPtrNotNull(tc, aug);
107 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
109 /* aug_set returns 0 for a simple set */
110 r = aug_set(aug, "/augeas/testSet", "foo");
111 CuAssertIntEquals(tc, 0, r);
112 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
114 /* aug_set returns -1 when cannot set due to multiple nodes */
115 r = aug_set(aug, "/augeas/version/save/*", "foo");
116 CuAssertIntEquals(tc, -1, r);
117 CuAssertIntEquals(tc, AUG_EMMATCH, aug_error(aug));
119 /* aug_set is able to set the context, even when currently invalid */
120 r = aug_set(aug, "/augeas/context", "( /files | /augeas )");
121 CuAssertIntEquals(tc, 0, r);
122 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
123 r = aug_get(aug, "/augeas/version", &value);
124 CuAssertIntEquals(tc, -1, r);
125 CuAssertIntEquals(tc, AUG_EMMATCH, aug_error(aug));
126 r = aug_set(aug, "/augeas/context", "/files");
127 CuAssertIntEquals(tc, 0, r);
128 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
133 static void testSetM(CuTest *tc) {
137 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
138 CuAssertPtrNotNull(tc, aug);
139 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
141 /* Change base nodes when SUB is NULL */
142 r = aug_setm(aug, "/augeas/version/save/*", NULL, "changed");
143 CuAssertIntEquals(tc, 4, r);
145 r = aug_match(aug, "/augeas/version/save/*[. = 'changed']", NULL);
146 CuAssertIntEquals(tc, 4, r);
148 /* Only change existing nodes */
149 r = aug_setm(aug, "/augeas/version/save", "mode", "again");
150 CuAssertIntEquals(tc, 4, r);
152 r = aug_match(aug, "/augeas/version/save/*", NULL);
153 CuAssertIntEquals(tc, 4, r);
155 r = aug_match(aug, "/augeas/version/save/*[. = 'again']", NULL);
156 CuAssertIntEquals(tc, 4, r);
158 /* Create a new node */
159 r = aug_setm(aug, "/augeas/version/save", "mode[last() + 1]", "newmode");
160 CuAssertIntEquals(tc, 1, r);
162 r = aug_match(aug, "/augeas/version/save/*", NULL);
163 CuAssertIntEquals(tc, 5, r);
165 r = aug_match(aug, "/augeas/version/save/*[. = 'again']", NULL);
166 CuAssertIntEquals(tc, 4, r);
168 r = aug_match(aug, "/augeas/version/save/*[last()][. = 'newmode']", NULL);
169 CuAssertIntEquals(tc, 1, r);
171 /* Noexistent base */
172 r = aug_setm(aug, "/augeas/version/save[last()+1]", "mode", "newmode");
173 CuAssertIntEquals(tc, 0, r);
175 /* Invalid path expressions */
176 r = aug_setm(aug, "/augeas/version/save[]", "mode", "invalid");
177 CuAssertIntEquals(tc, -1, r);
179 r = aug_setm(aug, "/augeas/version/save/*", "mode[]", "invalid");
180 CuAssertIntEquals(tc, -1, r);
185 /* Check that defining a variable leads to a corresponding entry in
186 * /augeas/variables and that that entry disappears when the variable is
188 static void testDefVarMeta(CuTest *tc) {
191 static const char *const expr = "/augeas/version/save/mode";
194 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
195 CuAssertPtrNotNull(tc, aug);
196 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
198 r = aug_defvar(aug, "var", expr);
199 CuAssertIntEquals(tc, 4, r);
201 r = aug_match(aug, "/augeas/variables/*", NULL);
202 CuAssertIntEquals(tc, 1, r);
204 r = aug_get(aug, "/augeas/variables/var", &value);
205 CuAssertStrEquals(tc, expr, value);
207 r = aug_defvar(aug, "var", NULL);
208 CuAssertIntEquals(tc, 0, r);
210 r = aug_match(aug, "/augeas/variables/*", NULL);
211 CuAssertIntEquals(tc, 0, r);
216 /* Check that defining a variable with defnode leads to a corresponding
217 * entry in /augeas/variables and that that entry disappears when the
218 * variable is undefined
220 static void testDefNodeExistingMeta(CuTest *tc) {
223 static const char *const expr = "/augeas/version/save/mode";
226 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
227 CuAssertPtrNotNull(tc, aug);
228 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
230 r = aug_defnode(aug, "var", expr, "other", &created);
231 CuAssertIntEquals(tc, 4, r);
232 CuAssertIntEquals(tc, 0, created);
234 r = aug_match(aug, "/augeas/variables/*", NULL);
235 CuAssertIntEquals(tc, 1, r);
237 r = aug_get(aug, "/augeas/variables/var", &value);
238 CuAssertStrEquals(tc, expr, value);
240 r = aug_defvar(aug, "var", NULL);
241 CuAssertIntEquals(tc, 0, r);
243 r = aug_match(aug, "/augeas/variables/*", NULL);
244 CuAssertIntEquals(tc, 0, r);
249 /* Check that defining a variable with defnode leads to a corresponding
250 * entry in /augeas/variables and that that entry disappears when the
251 * variable is undefined
253 static void testDefNodeCreateMeta(CuTest *tc) {
256 static const char *const expr = "/augeas/version/save/mode[last()+1]";
257 static const char *const expr_can = "/augeas/version/save/mode[5]";
260 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
261 CuAssertPtrNotNull(tc, aug);
262 CuAssertIntEquals(tc, AUG_NOERROR, aug_error(aug));
264 r = aug_defnode(aug, "var", expr, "other", &created);
265 CuAssertIntEquals(tc, 1, r);
266 CuAssertIntEquals(tc, 1, created);
268 r = aug_match(aug, "/augeas/variables/*", NULL);
269 CuAssertIntEquals(tc, 1, r);
271 r = aug_get(aug, "/augeas/variables/var", &value);
272 CuAssertStrEquals(tc, expr_can, value);
274 r = aug_defvar(aug, "var", NULL);
275 CuAssertIntEquals(tc, 0, r);
277 r = aug_match(aug, "/augeas/variables/*", NULL);
278 CuAssertIntEquals(tc, 0, r);
283 static void reset_indexes(uint *a, uint *b, uint *c, uint *d, uint *e, uint *f) {
284 *a = 0; *b = 0; *c = 0; *d = 0; *e = 0; *f = 0;
287 #define SPAN_TEST_DEF_LAST { .expr = NULL, .ls = 0, .le = 0, \
288 .vs = 0, .ve = 0, .ss = 0, .se = 0 }
290 struct span_test_def {
302 static const struct span_test_def span_test[] = {
303 { .expr = "/files/etc/hosts/1/ipaddr", .f = "hosts", .ret = 0, .ls = 0, .le = 0, .vs = 104, .ve = 113, .ss = 104, .se = 113 },
304 { .expr = "/files/etc/hosts/1", .f = "hosts", .ret = 0, .ls = 0, .le = 0, .vs = 0, .ve = 0, .ss = 104, .se = 171 },
305 { .expr = "/files/etc/hosts/*[last()]", .f = "hosts", .ret = 0, .ls = 0, .le = 0, .vs = 0, .ve = 0, .ss = 266, .se = 309 },
306 { .expr = "/files/etc/hosts/#comment[2]", .f = "hosts", .ret = 0, .ls = 0, .le = 0, .vs = 58, .ve = 103, .ss = 56, .se = 104 },
307 { .expr = "/files/etc/hosts", .f = "hosts", .ret = 0, .ls = 0, .le = 0, .vs = 0, .ve = 0, .ss = 0, .se = 309 },
308 { .expr = "/files", .f = NULL, .ret = -1, .ls = 0, .le = 0, .vs = 0, .ve = 0, .ss = 0, .se = 0 },
309 { .expr = "/random", .f = NULL, .ret = -1, .ls = 0, .le = 0, .vs = 0, .ve = 0, .ss = 0, .se = 0 },
313 static void testNodeInfo(CuTest *tc) {
317 struct span_test_def test;
320 static const char *const expr = "/files/etc/hosts/1/ipaddr";
323 uint label_start, label_end, value_start, value_end, span_start, span_end;
325 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD|AUG_ENABLE_SPAN);
327 CuAssertRetSuccess(tc, ret);
329 while(span_test[i].expr != NULL) {
332 ret = aug_span(aug, test.expr, &filename_ac, &label_start, &label_end,
333 &value_start, &value_end, &span_start, &span_end);
334 sprintf(msg, "span_test %d ret\n", i);
335 CuAssertIntEquals_Msg(tc, msg, test.ret, ret);
336 sprintf(msg, "span_test %d label_start\n", i);
337 CuAssertIntEquals_Msg(tc, msg, test.ls, label_start);
338 sprintf(msg, "span_test %d label_end\n", i);
339 CuAssertIntEquals_Msg(tc, msg, test.le, label_end);
340 sprintf(msg, "span_test %d value_start\n", i);
341 CuAssertIntEquals_Msg(tc, msg, test.vs, value_start);
342 sprintf(msg, "span_test %d value_end\n", i);
343 CuAssertIntEquals_Msg(tc, msg, test.ve, value_end);
344 sprintf(msg, "span_test %d span_start\n", i);
345 CuAssertIntEquals_Msg(tc, msg, test.ss, span_start);
346 sprintf(msg, "span_test %d span_end\n", i);
347 CuAssertIntEquals_Msg(tc, msg, test.se, span_end);
348 if (filename_ac != NULL) {
349 fbase = basename(filename_ac);
353 sprintf(msg, "span_test %d filename\n", i);
354 CuAssertStrEquals_Msg(tc, msg, test.f, fbase);
357 reset_indexes(&label_start, &label_end, &value_start, &value_end,
358 &span_start, &span_end);
361 /* aug_span returns -1 and when no node matches */
362 ret = aug_span(aug, "/files/etc/hosts/*[ last() + 1 ]", &filename_ac,
363 &label_start, &label_end, &value_start, &value_end,
364 &span_start, &span_end);
365 CuAssertIntEquals(tc, -1, ret);
366 CuAssertPtrEquals(tc, NULL, filename_ac);
367 CuAssertIntEquals(tc, AUG_ENOMATCH, aug_error(aug));
369 /* aug_span should return an error when multiple nodes match */
370 ret = aug_span(aug, "/files/etc/hosts/*", &filename_ac,
371 &label_start, &label_end, &value_start, &value_end,
372 &span_start, &span_end);
373 CuAssertIntEquals(tc, -1, ret);
374 CuAssertPtrEquals(tc, NULL, filename_ac);
375 CuAssertIntEquals(tc, AUG_EMMATCH, aug_error(aug));
377 /* aug_span returns -1 if nodes span are not loaded */
379 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
381 CuAssertRetSuccess(tc, ret);
382 ret = aug_span(aug, expr, &filename_ac, &label_start, &label_end,
383 &value_start, &value_end, &span_start, &span_end);
384 CuAssertIntEquals(tc, -1, ret);
385 CuAssertPtrEquals(tc, NULL, filename_ac);
386 CuAssertIntEquals(tc, AUG_ENOSPAN, aug_error(aug));
387 reset_indexes(&label_start, &label_end, &value_start, &value_end,
388 &span_start, &span_end);
393 static void testMv(CuTest *tc) {
397 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
398 CuAssertPtrNotNull(tc, aug);
400 r = aug_set(aug, "/a/b/c", "value");
401 CuAssertRetSuccess(tc, r);
403 r = aug_mv(aug, "/a/b/c", "/a/b/c/d");
404 CuAssertIntEquals(tc, -1, r);
405 CuAssertIntEquals(tc, AUG_EMVDESC, aug_error(aug));
411 static void testToXml(CuTest *tc) {
415 const xmlChar *value;
417 aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
419 CuAssertRetSuccess(tc, r);
421 r = aug_to_xml(aug, "/files/etc/passwd", &xmldoc, 0);
422 CuAssertRetSuccess(tc, r);
424 value = xmlGetProp(xmldoc, BAD_CAST "match");
425 CuAssertStrEquals(tc, "/files/etc/passwd", (const char*)value);
427 xmldoc = xmlFirstElementChild(xmldoc);
428 value = xmlGetProp(xmldoc, BAD_CAST "label");
429 CuAssertStrEquals(tc, "passwd", (const char*)value);
431 value = xmlGetProp(xmldoc, BAD_CAST "path");
432 CuAssertStrEquals(tc, "/files/etc/passwd", (const char*)value);
434 xmldoc = xmlFirstElementChild(xmldoc);
435 value = xmlGetProp(xmldoc, BAD_CAST "label");
436 CuAssertStrEquals(tc, "root", (const char*)value);
443 CuSuite* suite = CuSuiteNew();
444 CuSuiteSetup(suite, NULL, NULL);
446 SUITE_ADD_TEST(suite, testGet);
447 SUITE_ADD_TEST(suite, testSet);
448 SUITE_ADD_TEST(suite, testSetM);
449 SUITE_ADD_TEST(suite, testDefVarMeta);
450 SUITE_ADD_TEST(suite, testDefNodeExistingMeta);
451 SUITE_ADD_TEST(suite, testDefNodeCreateMeta);
452 SUITE_ADD_TEST(suite, testNodeInfo);
453 SUITE_ADD_TEST(suite, testMv);
454 SUITE_ADD_TEST(suite, testToXml);
456 abs_top_srcdir = getenv("abs_top_srcdir");
457 if (abs_top_srcdir == NULL)
458 die("env var abs_top_srcdir must be set");
460 if (asprintf(&root, "%s/tests/root", abs_top_srcdir) < 0) {
461 die("failed to set root");
464 if (asprintf(&loadpath, "%s/lenses", abs_top_srcdir) < 0) {
465 die("failed to set loadpath");
469 CuSuiteSummary(suite, &output);
470 CuSuiteDetails(suite, &output);
471 printf("%s\n", output);
473 return suite->failCount;
478 * indent-tabs-mode: nil