qemu: Validate spapr-vio addresses
[libvirt/ericb.git] / tests / virbuftest.c
blobcaad6f3ecb2b7bc4c2686901d88c316de638ca40
1 #include <config.h>
4 #include "internal.h"
5 #include "testutils.h"
6 #include "virbuffer.h"
7 #include "viralloc.h"
8 #include "virstring.h"
10 #define VIR_FROM_THIS VIR_FROM_NONE
12 struct testInfo {
13 int doEscape;
16 static int testBufInfiniteLoop(const void *data)
18 virBuffer bufinit = VIR_BUFFER_INITIALIZER;
19 virBufferPtr buf = &bufinit;
20 char *addstr = NULL, *bufret = NULL;
21 int ret = -1;
22 const struct testInfo *info = data;
23 int len;
25 virBufferAddChar(buf, 'a');
28 * Infinite loop used to trigger if:
29 * (strlen + 1 > 1000) && (strlen == buf-size - buf-use - 1)
30 * which was the case after the above addchar at the time of the bug.
31 * This test is a bit fragile, since it relies on virBuffer internals.
33 len = buf->size - buf->use - 1;
34 if (virAsprintf(&addstr, "%*s", len, "a") < 0)
35 goto out;
37 if (info->doEscape)
38 virBufferEscapeString(buf, "%s", addstr);
39 else
40 virBufferAsprintf(buf, "%s", addstr);
42 ret = 0;
43 out:
44 bufret = virBufferContentAndReset(buf);
45 if (!bufret) {
46 VIR_TEST_DEBUG("Buffer had error set");
47 ret = -1;
50 VIR_FREE(addstr);
51 VIR_FREE(bufret);
52 return ret;
55 static int testBufAutoIndent(const void *data ATTRIBUTE_UNUSED)
57 virBuffer bufinit = VIR_BUFFER_INITIALIZER;
58 virBufferPtr buf = &bufinit;
59 const char expected[] =
60 " 1\n 2\n 3\n 4\n 5\n 6\n 7\n &amp;\n 8\n 9\n 10\n ' 11'\n";
61 char *result = NULL;
62 int ret = 0;
64 if (virBufferGetIndent(buf, false) != 0 ||
65 virBufferGetIndent(buf, true) != 0) {
66 VIR_TEST_DEBUG("Wrong indentation");
67 ret = -1;
69 virBufferAdjustIndent(buf, 3);
70 if (STRNEQ(virBufferCurrentContent(buf), "")) {
71 VIR_TEST_DEBUG("Wrong content");
72 ret = -1;
74 if (virBufferGetIndent(buf, false) != 3 ||
75 virBufferGetIndent(buf, true) != 3 ||
76 virBufferError(buf)) {
77 VIR_TEST_DEBUG("Wrong indentation");
78 ret = -1;
80 virBufferAdjustIndent(buf, -2);
81 if (virBufferGetIndent(buf, false) != 1 ||
82 virBufferGetIndent(buf, true) != 1 ||
83 virBufferError(buf)) {
84 VIR_TEST_DEBUG("Wrong indentation");
85 ret = -1;
87 virBufferAdjustIndent(buf, -3);
88 if (virBufferGetIndent(buf, false) != -1 ||
89 virBufferGetIndent(buf, true) != -1 ||
90 virBufferError(buf) != -1) {
91 VIR_TEST_DEBUG("Usage error not flagged");
92 ret = -1;
94 virBufferFreeAndReset(buf);
95 if (virBufferGetIndent(buf, false) != 0 ||
96 virBufferGetIndent(buf, true) != 0 ||
97 virBufferError(buf)) {
98 VIR_TEST_DEBUG("Reset didn't clear indentation");
99 ret = -1;
101 virBufferAdjustIndent(buf, 2);
102 virBufferAddLit(buf, "1");
103 if (virBufferError(buf)) {
104 VIR_TEST_DEBUG("Buffer had error");
105 return -1;
107 if (STRNEQ(virBufferCurrentContent(buf), " 1")) {
108 VIR_TEST_DEBUG("Wrong content");
109 ret = -1;
111 if (virBufferGetIndent(buf, false) != 2 ||
112 virBufferGetIndent(buf, true) != 0) {
113 VIR_TEST_DEBUG("Wrong indentation");
114 ret = -1;
116 virBufferAddLit(buf, "\n");
117 virBufferAdd(buf, "" "2\n", -1); /* Extra "" appeases syntax-check */
118 virBufferAddChar(buf, '3');
119 virBufferAddChar(buf, '\n');
120 virBufferAsprintf(buf, "%d", 4);
121 virBufferAsprintf(buf, "%c", '\n');
122 virBufferStrcat(buf, "5", "\n", "6\n", NULL);
123 virBufferEscapeString(buf, "%s\n", "7");
124 virBufferEscapeString(buf, "%s\n", "&");
125 virBufferEscapeSexpr(buf, "%s", "8\n");
126 virBufferURIEncodeString(buf, "9");
127 virBufferAddChar(buf, '\n');
128 virBufferEscapeShell(buf, "10");
129 virBufferAddChar(buf, '\n');
130 virBufferEscapeShell(buf, " 11");
131 virBufferAddChar(buf, '\n');
133 if (virBufferError(buf)) {
134 VIR_TEST_DEBUG("Buffer had error");
135 return -1;
138 result = virBufferContentAndReset(buf);
139 if (!result || STRNEQ(result, expected)) {
140 virTestDifference(stderr, expected, result);
141 ret = -1;
143 VIR_FREE(result);
144 return ret;
147 static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
149 virBuffer bufinit = VIR_BUFFER_INITIALIZER;
150 virBufferPtr buf = NULL;
151 char *result = NULL;
152 const char *expected = "a,b";
153 int ret = -1;
155 virBufferTrim(buf, "", 0);
156 buf = &bufinit;
158 virBufferAddLit(buf, "a;");
159 virBufferTrim(buf, "", 0);
160 virBufferTrim(buf, "", -1);
161 virBufferTrim(buf, NULL, 1);
162 virBufferTrim(buf, NULL, 5);
163 virBufferTrim(buf, "a", 2);
165 virBufferAddLit(buf, ",b,,");
166 virBufferTrim(buf, "b", -1);
167 virBufferTrim(buf, "b,,", 1);
168 virBufferTrim(buf, ",", -1);
170 if (virBufferError(buf)) {
171 VIR_TEST_DEBUG("Buffer had error");
172 return -1;
175 result = virBufferContentAndReset(buf);
176 if (!result || STRNEQ(result, expected)) {
177 virTestDifference(stderr, expected, result);
178 goto cleanup;
181 virBufferTrim(buf, NULL, -1);
182 if (virBufferError(buf) != -1) {
183 VIR_TEST_DEBUG("Usage error not flagged");
184 goto cleanup;
187 ret = 0;
189 cleanup:
190 virBufferFreeAndReset(buf);
191 VIR_FREE(result);
192 return ret;
195 static int testBufAddBuffer(const void *data ATTRIBUTE_UNUSED)
197 virBuffer buf1 = VIR_BUFFER_INITIALIZER;
198 virBuffer buf2 = VIR_BUFFER_INITIALIZER;
199 virBuffer buf3 = VIR_BUFFER_INITIALIZER;
200 int ret = -1;
201 char *result = NULL;
202 const char *expected = \
203 " A long time ago, in a galaxy far,\n" \
204 " far away...\n" \
205 " It is a period of civil war.\n" \
206 " Rebel spaceships, striking\n" \
207 " from a hidden base, have won\n" \
208 " their first victory against\n" \
209 " the evil Galactic Empire.\n" \
210 " During the battle, rebel\n" \
211 " spies managed to steal secret\n" \
212 " plans to the Empire's\n" \
213 " ultimate weapon, the DEATH\n" \
214 " STAR, an armored space\n" \
215 " station with enough power to\n" \
216 " destroy an entire planet.\n";
218 if (virBufferUse(&buf1)) {
219 VIR_TEST_DEBUG("buf1 already in use");
220 goto cleanup;
223 if (virBufferUse(&buf2)) {
224 VIR_TEST_DEBUG("buf2 already in use");
225 goto cleanup;
228 if (virBufferUse(&buf3)) {
229 VIR_TEST_DEBUG("buf3 already in use");
230 goto cleanup;
233 virBufferAdjustIndent(&buf1, 2);
234 virBufferAddLit(&buf1, "A long time ago, in a galaxy far,\n");
235 virBufferAddLit(&buf1, "far away...\n");
237 virBufferAdjustIndent(&buf2, 4);
238 virBufferAddLit(&buf2, "It is a period of civil war.\n");
239 virBufferAddLit(&buf2, "Rebel spaceships, striking\n");
240 virBufferAddLit(&buf2, "from a hidden base, have won\n");
241 virBufferAddLit(&buf2, "their first victory against\n");
242 virBufferAddLit(&buf2, "the evil Galactic Empire.\n");
244 virBufferAdjustIndent(&buf3, 2);
245 virBufferAddLit(&buf3, "During the battle, rebel\n");
246 virBufferAddLit(&buf3, "spies managed to steal secret\n");
247 virBufferAddLit(&buf3, "plans to the Empire's\n");
248 virBufferAddLit(&buf3, "ultimate weapon, the DEATH\n");
249 virBufferAddLit(&buf3, "STAR, an armored space\n");
250 virBufferAddLit(&buf3, "station with enough power to\n");
251 virBufferAddLit(&buf3, "destroy an entire planet.\n");
253 if (!virBufferUse(&buf1)) {
254 VIR_TEST_DEBUG("Error adding to buf1");
255 goto cleanup;
258 if (!virBufferUse(&buf2)) {
259 VIR_TEST_DEBUG("Error adding to buf2");
260 goto cleanup;
263 if (!virBufferUse(&buf3)) {
264 VIR_TEST_DEBUG("Error adding to buf3");
265 goto cleanup;
268 virBufferAddBuffer(&buf2, &buf3);
270 if (!virBufferUse(&buf2)) {
271 VIR_TEST_DEBUG("buf2 cleared mistakenly");
272 goto cleanup;
275 if (virBufferUse(&buf3)) {
276 VIR_TEST_DEBUG("buf3 is not clear even though it should be");
277 goto cleanup;
280 virBufferAddBuffer(&buf1, &buf2);
282 if (!virBufferUse(&buf1)) {
283 VIR_TEST_DEBUG("buf1 cleared mistakenly");
284 goto cleanup;
287 if (virBufferUse(&buf2)) {
288 VIR_TEST_DEBUG("buf2 is not clear even though it should be");
289 goto cleanup;
292 result = virBufferContentAndReset(&buf1);
293 if (STRNEQ_NULLABLE(result, expected)) {
294 virTestDifference(stderr, expected, result);
295 goto cleanup;
298 ret = 0;
299 cleanup:
300 virBufferFreeAndReset(&buf1);
301 virBufferFreeAndReset(&buf2);
302 VIR_FREE(result);
303 return ret;
306 static int
307 testBufAddBuffer2(const void *opaque ATTRIBUTE_UNUSED)
309 VIR_AUTOCLEAN(virBuffer) buf1 = VIR_BUFFER_INITIALIZER;
310 VIR_AUTOCLEAN(virBuffer) buf2 = VIR_BUFFER_INITIALIZER;
312 /* Intent of this test is to demonstrate a memleak that happen with
313 * virBufferAddBuffer */
315 virBufferAddLit(&buf1, "Hello world!\n");
316 virBufferAddLit(&buf2, "Hello world!\n");
318 /* Intentional usage error */
319 virBufferAdjustIndent(&buf2, -2);
321 virBufferAddBuffer(&buf1, &buf2);
323 if (virBufferCurrentContent(&buf1) ||
324 !virBufferCurrentContent(&buf2)) {
325 VIR_TEST_DEBUG("Unexpected buffer content");
326 return -1;
329 return 0;
332 struct testBufAddStrData {
333 const char *data;
334 const char *expect;
337 static int
338 testBufAddStr(const void *opaque ATTRIBUTE_UNUSED)
340 const struct testBufAddStrData *data = opaque;
341 virBuffer buf = VIR_BUFFER_INITIALIZER;
342 char *actual;
343 int ret = -1;
345 virBufferAddLit(&buf, "<c>\n");
346 virBufferAdjustIndent(&buf, 2);
347 virBufferAddStr(&buf, data->data);
348 virBufferAdjustIndent(&buf, -2);
349 virBufferAddLit(&buf, "</c>");
351 if (!(actual = virBufferContentAndReset(&buf))) {
352 VIR_TEST_DEBUG("buf is empty");
353 goto cleanup;
356 if (STRNEQ_NULLABLE(actual, data->expect)) {
357 VIR_TEST_DEBUG("testBufAddStr(): Strings don't match:\n");
358 virTestDifference(stderr, data->expect, actual);
359 goto cleanup;
362 ret = 0;
364 cleanup:
365 VIR_FREE(actual);
366 return ret;
370 static int
371 testBufEscapeStr(const void *opaque ATTRIBUTE_UNUSED)
373 const struct testBufAddStrData *data = opaque;
374 virBuffer buf = VIR_BUFFER_INITIALIZER;
375 char *actual;
376 int ret = -1;
378 virBufferAddLit(&buf, "<c>\n");
379 virBufferAdjustIndent(&buf, 2);
380 virBufferEscapeString(&buf, "<el>%s</el>\n", data->data);
381 virBufferAdjustIndent(&buf, -2);
382 virBufferAddLit(&buf, "</c>");
384 if (!(actual = virBufferContentAndReset(&buf))) {
385 VIR_TEST_DEBUG("buf is empty");
386 goto cleanup;
389 if (STRNEQ_NULLABLE(actual, data->expect)) {
390 VIR_TEST_DEBUG("testBufEscapeStr(): Strings don't match:\n");
391 virTestDifference(stderr, data->expect, actual);
392 goto cleanup;
395 ret = 0;
397 cleanup:
398 VIR_FREE(actual);
399 return ret;
403 static int
404 testBufEscapeRegex(const void *opaque)
406 const struct testBufAddStrData *data = opaque;
407 virBuffer buf = VIR_BUFFER_INITIALIZER;
408 char *actual;
409 int ret = -1;
411 virBufferEscapeRegex(&buf, "%s", data->data);
413 if (!(actual = virBufferContentAndReset(&buf))) {
414 VIR_TEST_DEBUG("testBufEscapeRegex: buf is empty");
415 goto cleanup;
418 if (STRNEQ_NULLABLE(actual, data->expect)) {
419 VIR_TEST_DEBUG("testBufEscapeRegex: Strings don't match:\n");
420 virTestDifference(stderr, data->expect, actual);
421 goto cleanup;
424 ret = 0;
426 cleanup:
427 VIR_FREE(actual);
428 return ret;
432 static int
433 testBufSetIndent(const void *opaque ATTRIBUTE_UNUSED)
435 virBuffer buf = VIR_BUFFER_INITIALIZER;
436 char *actual;
437 int ret = -1;
439 virBufferSetIndent(&buf, 11);
440 virBufferAddLit(&buf, "test\n");
441 virBufferSetIndent(&buf, 2);
442 virBufferAddLit(&buf, "test2\n");
444 if (!(actual = virBufferContentAndReset(&buf)))
445 goto cleanup;
447 if (STRNEQ(actual, " test\n test2\n")) {
448 VIR_TEST_DEBUG("testBufSetIndent: expected indent not set\n");
449 goto cleanup;
452 ret = 0;
454 cleanup:
455 VIR_FREE(actual);
456 return ret;
460 /* Result of this shows up only in valgrind or similar */
461 static int
462 testBufferAutoclean(const void *opaque ATTRIBUTE_UNUSED)
464 VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER;
466 virBufferAddLit(&buf, "test test test\n");
467 return 0;
471 static int
472 mymain(void)
474 int ret = 0;
477 #define DO_TEST(msg, cb, data) \
478 do { \
479 struct testInfo info = { data }; \
480 if (virTestRun("Buf: " msg, cb, &info) < 0) \
481 ret = -1; \
482 } while (0)
484 DO_TEST("EscapeString infinite loop", testBufInfiniteLoop, 1);
485 DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
486 DO_TEST("Auto-indentation", testBufAutoIndent, 0);
487 DO_TEST("Trim", testBufTrim, 0);
488 DO_TEST("AddBuffer", testBufAddBuffer, 0);
489 DO_TEST("AddBuffer2", testBufAddBuffer2, 0);
490 DO_TEST("set indent", testBufSetIndent, 0);
491 DO_TEST("autoclean", testBufferAutoclean, 0);
493 #define DO_TEST_ADD_STR(DATA, EXPECT) \
494 do { \
495 struct testBufAddStrData info = { DATA, EXPECT }; \
496 if (virTestRun("Buf: AddStr", testBufAddStr, &info) < 0) \
497 ret = -1; \
498 } while (0)
500 DO_TEST_ADD_STR("", "<c>\n</c>");
501 DO_TEST_ADD_STR("<a/>", "<c>\n <a/></c>");
502 DO_TEST_ADD_STR("<a/>\n", "<c>\n <a/>\n</c>");
503 DO_TEST_ADD_STR("<b>\n <a/>\n</b>\n", "<c>\n <b>\n <a/>\n </b>\n</c>");
505 #define DO_TEST_ESCAPE(data, expect) \
506 do { \
507 struct testBufAddStrData info = { data, expect }; \
508 if (virTestRun("Buf: EscapeStr", testBufEscapeStr, &info) < 0) \
509 ret = -1; \
510 } while (0)
512 DO_TEST_ESCAPE("<td></td><td></td>",
513 "<c>\n <el>&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;</el>\n</c>");
514 DO_TEST_ESCAPE("\007\"&&\"\x15",
515 "<c>\n <el>&quot;&amp;&amp;&quot;</el>\n</c>");
516 DO_TEST_ESCAPE(",,'..',,",
517 "<c>\n <el>,,&apos;..&apos;,,</el>\n</c>");
518 DO_TEST_ESCAPE("\x01\x01\x02\x03\x05\x08",
519 "<c>\n <el></el>\n</c>");
521 #define DO_TEST_ESCAPE_REGEX(data, expect) \
522 do { \
523 struct testBufAddStrData info = { data, expect }; \
524 if (virTestRun("Buf: EscapeRegex", testBufEscapeRegex, &info) < 0) \
525 ret = -1; \
526 } while (0)
528 DO_TEST_ESCAPE_REGEX("noescape", "noescape");
529 DO_TEST_ESCAPE_REGEX("^$.|?*+()[]{}\\",
530 "\\^\\$\\.\\|\\?\\*\\+\\(\\)\\[\\]\\{\\}\\\\");
532 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
535 VIR_TEST_MAIN(mymain)