blob: bab87351d2f7386051f630ed5732168a43860147 [file] [log] [blame]
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001/*
2 * runsuite.c: C program to run libxml2 againts external published testsuites
3 *
4 * See Copyright for the status of this software.
5 *
6 * daniel@veillard.com
7 */
8
9#include <unistd.h>
10#include <string.h>
11#include <stdio.h>
12#include <glob.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <fcntl.h>
16#include <unistd.h>
17
18#include <libxml/parser.h>
Daniel Veillarde84f2312005-07-02 07:31:28 +000019#include <libxml/parserInternals.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000020#include <libxml/tree.h>
21#include <libxml/uri.h>
22#include <libxml/xmlreader.h>
23
24#include <libxml/xpath.h>
25#include <libxml/xpathInternals.h>
26
27#include <libxml/relaxng.h>
28#include <libxml/xmlschemas.h>
29#include <libxml/xmlschemastypes.h>
30
31/************************************************************************
32 * *
33 * File name and path utilities *
34 * *
35 ************************************************************************/
36
37static int checkTestFile(const char *filename) {
38 struct stat buf;
39
40 if (stat(filename, &buf) == -1)
41 return(0);
42
43 if (!S_ISREG(buf.st_mode))
44 return(0);
45
46 return(1);
47}
Daniel Veillarde84f2312005-07-02 07:31:28 +000048static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
49 char buf[500];
50
51 if (dir == NULL) return(xmlStrdup(path));
52 if (path == NULL) return(NULL);
53
54 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
55 return(xmlStrdup((const xmlChar *) buf));
56}
Daniel Veillardf2e066a2005-06-30 13:04:44 +000057
58/************************************************************************
59 * *
60 * Libxml2 specific routines *
61 * *
62 ************************************************************************/
63
64static int nb_tests = 0;
65static int nb_errors = 0;
66static int nb_leaks = 0;
67static long libxmlMemoryAllocatedBase = 0;
68static int extraMemoryFromResolver = 0;
69
70static int
71fatalError(void) {
72 fprintf(stderr, "Exitting tests on fatal error\n");
73 exit(1);
74}
75
76/*
Daniel Veillarde84f2312005-07-02 07:31:28 +000077 * that's needed to implement <resource>
78 */
79#define MAX_ENTITIES 20
80char *testEntitiesName[MAX_ENTITIES];
81char *testEntitiesValue[MAX_ENTITIES];
82int nb_entities = 0;
83static void resetEntities(void) {
84 int i;
85
86 for (i = 0;i < nb_entities;i++) {
87 if (testEntitiesName[i] != NULL)
88 xmlFree(testEntitiesName[i]);
89 if (testEntitiesValue[i] != NULL)
90 xmlFree(testEntitiesValue[i]);
91 }
92 nb_entities = 0;
93}
94static int addEntity(char *name, char *content) {
95 if (nb_entities >= MAX_ENTITIES) {
96 fprintf(stderr, "Too many entities defined\n");
97 return(-1);
98 }
99 testEntitiesName[nb_entities] = name;
100 testEntitiesValue[nb_entities] = content;
101 nb_entities++;
102 return(0);
103}
104
105/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000106 * We need to trap calls to the resolver to not account memory for the catalog
107 * which is shared to the current running test. We also don't want to have
108 * network downloads modifying tests.
109 */
110static xmlParserInputPtr
111testExternalEntityLoader(const char *URL, const char *ID,
112 xmlParserCtxtPtr ctxt) {
113 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000114 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000115
Daniel Veillarde84f2312005-07-02 07:31:28 +0000116 for (i = 0;i < nb_entities;i++) {
117 if (!strcmp(testEntitiesName[i], URL)) {
118 ret = xmlNewStringInputStream(ctxt,
119 (const xmlChar *) testEntitiesValue[i]);
120 if (ret != NULL) {
121 ret->filename = (const char *)
122 xmlStrdup((xmlChar *)testEntitiesName[i]);
123 }
124 return(ret);
125 }
126 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000127 if (checkTestFile(URL)) {
128 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
129 } else {
130 int memused = xmlMemUsed();
131 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
132 extraMemoryFromResolver += xmlMemUsed() - memused;
133 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000134 if (ret == NULL) {
135 fprintf(stderr, "Failed to find resource %s\n", URL);
136 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000137
138 return(ret);
139}
140
141/*
142 * Trapping the error messages at the generic level to grab the equivalent of
143 * stderr messages on CLI tools.
144 */
145static char testErrors[32769];
146static int testErrorsSize = 0;
147
148static void
149testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
150 va_list args;
151 int res;
152
153 if (testErrorsSize >= 32768)
154 return;
155 va_start(args, msg);
156 res = vsnprintf(&testErrors[testErrorsSize],
157 32768 - testErrorsSize,
158 msg, args);
159 va_end(args);
160 if (testErrorsSize + res >= 32768) {
161 /* buffer is full */
162 testErrorsSize = 32768;
163 testErrors[testErrorsSize] = 0;
164 } else {
165 testErrorsSize += res;
166 }
167 testErrors[testErrorsSize] = 0;
168}
169static void
170initializeLibxml2(void) {
171 xmlGetWarningsDefaultValue = 0;
172 xmlPedanticParserDefault(0);
173
174 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
175 xmlInitParser();
176 xmlSetExternalEntityLoader(testExternalEntityLoader);
177#ifdef LIBXML_SCHEMAS_ENABLED
178 xmlSchemaInitTypes();
179 xmlRelaxNGInitTypes();
180#endif
181 libxmlMemoryAllocatedBase = xmlMemUsed();
182}
183
184static xmlNodePtr
185getNext(xmlNodePtr cur, const char *xpath) {
186 xmlNodePtr ret = NULL;
187 xmlXPathObjectPtr res;
188 xmlXPathContextPtr ctxt;
189 xmlXPathCompExprPtr comp;
190
191 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
192 return(NULL);
193 ctxt = xmlXPathNewContext(cur->doc);
194 ctxt->node = cur;
195 comp = xmlXPathCompile(BAD_CAST xpath);
196 if (comp == NULL) {
197 fprintf(stderr, "Failed to compile %s\n", xpath);
198 xmlXPathFreeContext(ctxt);
199 return(NULL);
200 }
201 res = xmlXPathCompiledEval(comp, ctxt);
202 xmlXPathFreeCompExpr(comp);
203 xmlXPathFreeContext(ctxt);
204 if (res == NULL)
205 return(NULL);
206 if ((res->type == XPATH_NODESET) &&
207 (res->nodesetval != NULL) &&
208 (res->nodesetval->nodeNr > 0) &&
209 (res->nodesetval->nodeTab != NULL))
210 ret = res->nodesetval->nodeTab[0];
211 xmlXPathFreeObject(res);
212 return(ret);
213}
214
215static xmlChar *
216getString(xmlNodePtr cur, const char *xpath) {
217 xmlChar *ret = NULL;
218 xmlXPathObjectPtr res;
219 xmlXPathContextPtr ctxt;
220 xmlXPathCompExprPtr comp;
221
222 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
223 return(NULL);
224 ctxt = xmlXPathNewContext(cur->doc);
225 ctxt->node = cur;
226 comp = xmlXPathCompile(BAD_CAST xpath);
227 if (comp == NULL) {
228 fprintf(stderr, "Failed to compile %s\n", xpath);
229 return(NULL);
230 }
231 res = xmlXPathCompiledEval(comp, ctxt);
232 xmlXPathFreeCompExpr(comp);
233 xmlXPathFreeContext(ctxt);
234 if (res == NULL)
235 return(NULL);
236 if (res->type == XPATH_STRING) {
237 ret = res->stringval;
238 res->stringval = NULL;
239 }
240 xmlXPathFreeObject(res);
241 return(ret);
242}
243
244/************************************************************************
245 * *
246 * Test test/xsdtest/xsdtestsuite.xml *
247 * *
248 ************************************************************************/
249
250static int
251xsdIncorectTestCase(int verbose, xmlNodePtr cur) {
252 xmlNodePtr test;
253 xmlBufferPtr buf;
254 xmlRelaxNGParserCtxtPtr pctxt;
255 xmlRelaxNGPtr rng = NULL;
256 int ret = 0, memt;
257
258 cur = getNext(cur, "./incorrect[1]");
259 if (cur == NULL) {
260 return(0);
261 }
262
263 test = getNext(cur, "./*");
264 if (test == NULL) {
265 fprintf(stderr, "Failed to find test in correct line %ld\n",
266 xmlGetLineNo(cur));
267 return(1);
268 }
269
270 memt = xmlMemUsed();
271 extraMemoryFromResolver = 0;
272 /*
273 * dump the schemas to a buffer, then reparse it and compile the schemas
274 */
275 buf = xmlBufferCreate();
276 if (buf == NULL) {
277 fprintf(stderr, "out of memory !\n");
278 fatalError();
279 }
280 xmlNodeDump(buf, test->doc, test, 0, 0);
281 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
282 xmlRelaxNGSetParserErrors(pctxt,
283 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
284 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
285 pctxt);
286 rng = xmlRelaxNGParse(pctxt);
287 xmlRelaxNGFreeParserCtxt(pctxt);
288 if (rng != NULL) {
289 fprintf(stderr, "Failed to detect incorect RNG line %ld\n",
290 xmlGetLineNo(test));
291 ret = 1;
292 goto done;
293 }
294
295done:
296 if (buf != NULL)
297 xmlBufferFree(buf);
298 if (rng != NULL)
299 xmlRelaxNGFree(rng);
300 xmlResetLastError();
301 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
302 fprintf(stderr, "Validation of tests starting line %ld leaked %d\n",
303 xmlGetLineNo(cur), xmlMemUsed() - memt);
304 nb_leaks++;
305 }
306 return(ret);
307}
308
Daniel Veillarde84f2312005-07-02 07:31:28 +0000309static void
310installResources(xmlNodePtr tst, const xmlChar *base) {
311 xmlNodePtr test;
312 xmlBufferPtr buf;
313 xmlChar *name, *content, *res;
314 buf = xmlBufferCreate();
315 if (buf == NULL) {
316 fprintf(stderr, "out of memory !\n");
317 fatalError();
318 }
319 xmlNodeDump(buf, tst->doc, tst, 0, 0);
320
321 while (tst != NULL) {
322 test = getNext(tst, "./*");
323 if (test != NULL) {
324 xmlBufferEmpty(buf);
325 xmlNodeDump(buf, test->doc, test, 0, 0);
326 name = getString(tst, "string(@name)");
327 content = xmlStrdup(buf->content);
328 if ((name != NULL) && (content != NULL)) {
329 res = composeDir(base, name);
330 xmlFree(name);
331 addEntity((char *) res, (char *) content);
332 } else {
333 if (name != NULL) xmlFree(name);
334 if (content != NULL) xmlFree(content);
335 }
336 }
337 tst = getNext(tst, "following-sibling::resource[1]");
338 }
339 if (buf != NULL)
340 xmlBufferFree(buf);
341}
342
343static void
344installDirs(xmlNodePtr tst, const xmlChar *base) {
345 xmlNodePtr test;
346 xmlChar *name, *res;
347
348 name = getString(tst, "string(@name)");
349 if (name == NULL)
350 return;
351 res = composeDir(base, name);
352 xmlFree(name);
353 if (res == NULL) {
354 return;
355 }
356 /* Now process resources and subdir recursively */
357 test = getNext(tst, "./resource[1]");
358 if (test != NULL) {
359 installResources(test, res);
360 }
361 test = getNext(tst, "./dir[1]");
362 while (test != NULL) {
363 installDirs(test, res);
364 test = getNext(test, "following-sibling::dir[1]");
365 }
366}
367
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000368static int
369xsdTestCase(int verbose, xmlNodePtr tst) {
370 xmlNodePtr test, tmp, cur;
371 xmlBufferPtr buf;
372 xmlDocPtr doc = NULL;
373 xmlRelaxNGParserCtxtPtr pctxt;
374 xmlRelaxNGValidCtxtPtr ctxt;
375 xmlRelaxNGPtr rng = NULL;
376 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000377 xmlChar *dtd;
378
379 resetEntities();
380
381 tmp = getNext(tst, "./dir[1]");
382 if (tmp != NULL) {
383 installDirs(tmp, NULL);
384 }
385 tmp = getNext(tst, "./resource[1]");
386 if (tmp != NULL) {
387 installResources(tmp, NULL);
388 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000389
390 cur = getNext(tst, "./correct[1]");
391 if (cur == NULL) {
392 return(xsdIncorectTestCase(verbose, tst));
393 }
394
395 test = getNext(cur, "./*");
396 if (test == NULL) {
397 fprintf(stderr, "Failed to find test in correct line %ld\n",
398 xmlGetLineNo(cur));
399 return(1);
400 }
401
402 memt = xmlMemUsed();
403 extraMemoryFromResolver = 0;
404 /*
405 * dump the schemas to a buffer, then reparse it and compile the schemas
406 */
407 buf = xmlBufferCreate();
408 if (buf == NULL) {
409 fprintf(stderr, "out of memory !\n");
410 fatalError();
411 }
412 xmlNodeDump(buf, test->doc, test, 0, 0);
413 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
414 xmlRelaxNGSetParserErrors(pctxt,
415 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
416 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
417 pctxt);
418 rng = xmlRelaxNGParse(pctxt);
419 xmlRelaxNGFreeParserCtxt(pctxt);
420 if (extraMemoryFromResolver)
421 memt = 0;
422
423 if (rng == NULL) {
424 fprintf(stderr, "Failed to parse RNGtest line %ld\n",
425 xmlGetLineNo(test));
426 nb_errors++;
427 ret = 1;
428 goto done;
429 }
430 /*
431 * now scan all the siblings of correct to process the <valid> tests
432 */
433 tmp = getNext(cur, "following-sibling::valid[1]");
434 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000435 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000436 test = getNext(tmp, "./*");
437 if (test == NULL) {
438 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
439 xmlGetLineNo(tmp));
440
441 } else {
442 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000443 if (dtd != NULL)
444 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000445 xmlNodeDump(buf, test->doc, test, 0, 0);
446
447 /*
448 * We are ready to run the test
449 */
450 mem = xmlMemUsed();
451 extraMemoryFromResolver = 0;
452 doc = xmlReadMemory((const char *)buf->content, buf->use,
453 "test", NULL, 0);
454 if (doc == NULL) {
455 fprintf(stderr,
456 "Failed to parse valid instance line %ld\n",
457 xmlGetLineNo(tmp));
458 nb_errors++;
459 } else {
460 nb_tests++;
461 ctxt = xmlRelaxNGNewValidCtxt(rng);
462 xmlRelaxNGSetValidErrors(ctxt,
463 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
464 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
465 ctxt);
466 ret = xmlRelaxNGValidateDoc(ctxt, doc);
467 xmlRelaxNGFreeValidCtxt(ctxt);
468 if (ret > 0) {
469 fprintf(stderr,
470 "Failed to validate valid instance line %ld\n",
471 xmlGetLineNo(tmp));
472 nb_errors++;
473 } else if (ret < 0) {
474 fprintf(stderr,
475 "Internal error validating instance line %ld\n",
476 xmlGetLineNo(tmp));
477 nb_errors++;
478 }
479 xmlFreeDoc(doc);
480 }
481 xmlResetLastError();
482 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
483 fprintf(stderr, "Validation of instance line %ld leaked %d\n",
484 xmlGetLineNo(tmp), xmlMemUsed() - mem);
485 xmlMemoryDump();
486 nb_leaks++;
487 }
488 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000489 if (dtd != NULL)
490 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000491 tmp = getNext(tmp, "following-sibling::valid[1]");
492 }
493 /*
494 * now scan all the siblings of correct to process the <invalid> tests
495 */
496 tmp = getNext(cur, "following-sibling::invalid[1]");
497 while (tmp != NULL) {
498 test = getNext(tmp, "./*");
499 if (test == NULL) {
500 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
501 xmlGetLineNo(tmp));
502
503 } else {
504 xmlBufferEmpty(buf);
505 xmlNodeDump(buf, test->doc, test, 0, 0);
506
507 /*
508 * We are ready to run the test
509 */
510 mem = xmlMemUsed();
511 extraMemoryFromResolver = 0;
512 doc = xmlReadMemory((const char *)buf->content, buf->use,
513 "test", NULL, 0);
514 if (doc == NULL) {
515 fprintf(stderr,
516 "Failed to parse valid instance line %ld\n",
517 xmlGetLineNo(tmp));
518 nb_errors++;
519 } else {
520 nb_tests++;
521 ctxt = xmlRelaxNGNewValidCtxt(rng);
522 xmlRelaxNGSetValidErrors(ctxt,
523 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
524 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
525 ctxt);
526 ret = xmlRelaxNGValidateDoc(ctxt, doc);
527 xmlRelaxNGFreeValidCtxt(ctxt);
528 if (ret == 0) {
529 fprintf(stderr,
530 "Failed to detect invalid instance line %ld\n",
531 xmlGetLineNo(tmp));
532 nb_errors++;
533 } else if (ret < 0) {
534 fprintf(stderr,
535 "Internal error validating instance line %ld\n",
536 xmlGetLineNo(tmp));
537 nb_errors++;
538 }
539 xmlFreeDoc(doc);
540 }
541 xmlResetLastError();
542 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
543 fprintf(stderr, "Validation of instance line %ld leaked %d\n",
544 xmlGetLineNo(tmp), xmlMemUsed() - mem);
545 xmlMemoryDump();
546 nb_leaks++;
547 }
548 }
549 tmp = getNext(tmp, "following-sibling::invalid[1]");
550 }
551
552done:
553 if (buf != NULL)
554 xmlBufferFree(buf);
555 if (rng != NULL)
556 xmlRelaxNGFree(rng);
557 xmlResetLastError();
558 if ((memt != xmlMemUsed()) && (memt != 0)) {
559 fprintf(stderr, "Validation of tests starting line %ld leaked %d\n",
560 xmlGetLineNo(cur), xmlMemUsed() - memt);
561 nb_leaks++;
562 }
563 return(ret);
564}
565
566static int
567xsdTestSuite(int verbose, xmlNodePtr cur) {
568 if (verbose) {
569 xmlChar *doc = getString(cur, "string(documentation)");
570
571 if (doc != NULL) {
572 printf("Suite %s\n", doc);
573 xmlFree(doc);
574 }
575 }
576 cur = getNext(cur, "./testCase[1]");
577 while (cur != NULL) {
578 xsdTestCase(verbose, cur);
579 cur = getNext(cur, "following-sibling::testCase[1]");
580 }
581
582 return(0);
583}
584
585static int
586xsdTest(int verbose) {
587 xmlDocPtr doc;
588 xmlNodePtr cur;
589 const char *filename = "test/xsdtest/xsdtestsuite.xml";
590 int ret = 0;
591
592 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
593 if (doc == NULL) {
594 fprintf(stderr, "Failed to parse %s\n", filename);
595 return(-1);
596 }
597 printf("## XML Schemas datatypes test suite from James Clark\n");
598
599 cur = xmlDocGetRootElement(doc);
600 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
601 fprintf(stderr, "Unexpected format %s\n", filename);
602 ret = -1;
603 goto done;
604 }
605
606 cur = getNext(cur, "./testSuite[1]");
607 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
608 fprintf(stderr, "Unexpected format %s\n", filename);
609 ret = -1;
610 goto done;
611 }
612 while (cur != NULL) {
613 xsdTestSuite(verbose, cur);
614 cur = getNext(cur, "following-sibling::testSuite[1]");
615 }
616
617done:
618 if (doc != NULL)
619 xmlFreeDoc(doc);
620 return(ret);
621}
622
623static int
624rngTestSuite(int verbose, xmlNodePtr cur) {
625 if (verbose) {
626 xmlChar *doc = getString(cur, "string(documentation)");
627
628 if (doc != NULL) {
629 printf("Suite %s\n", doc);
630 xmlFree(doc);
631 } else {
632 doc = getString(cur, "string(section)");
633 if (doc != NULL) {
634 printf("Section %s\n", doc);
635 xmlFree(doc);
636 }
637 }
638 }
639 cur = getNext(cur, "./testSuite[1]");
640 while (cur != NULL) {
641 xsdTestSuite(verbose, cur);
642 cur = getNext(cur, "following-sibling::testSuite[1]");
643 }
644
645 return(0);
646}
647
648static int
649rngTest1(int verbose) {
650 xmlDocPtr doc;
651 xmlNodePtr cur;
652 const char *filename = "test/relaxng/OASIS/spectest.xml";
653 int ret = 0;
654
655 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
656 if (doc == NULL) {
657 fprintf(stderr, "Failed to parse %s\n", filename);
658 return(-1);
659 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000660 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000661
662 cur = xmlDocGetRootElement(doc);
663 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
664 fprintf(stderr, "Unexpected format %s\n", filename);
665 ret = -1;
666 goto done;
667 }
668
669 cur = getNext(cur, "./testSuite[1]");
670 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
671 fprintf(stderr, "Unexpected format %s\n", filename);
672 ret = -1;
673 goto done;
674 }
675 while (cur != NULL) {
676 rngTestSuite(verbose, cur);
677 cur = getNext(cur, "following-sibling::testSuite[1]");
678 }
679
680done:
681 if (doc != NULL)
682 xmlFreeDoc(doc);
683 return(ret);
684}
685
Daniel Veillarde84f2312005-07-02 07:31:28 +0000686static int
687rngTest2(int verbose) {
688 xmlDocPtr doc;
689 xmlNodePtr cur;
690 const char *filename = "test/relaxng/testsuite.xml";
691 int ret = 0;
692
693 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
694 if (doc == NULL) {
695 fprintf(stderr, "Failed to parse %s\n", filename);
696 return(-1);
697 }
698 printf("## Relax NG test suite for libxml2\n");
699
700 cur = xmlDocGetRootElement(doc);
701 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
702 fprintf(stderr, "Unexpected format %s\n", filename);
703 ret = -1;
704 goto done;
705 }
706
707 cur = getNext(cur, "./testSuite[1]");
708 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
709 fprintf(stderr, "Unexpected format %s\n", filename);
710 ret = -1;
711 goto done;
712 }
713 while (cur != NULL) {
714 xsdTestSuite(verbose, cur);
715 cur = getNext(cur, "following-sibling::testSuite[1]");
716 }
717
718done:
719 if (doc != NULL)
720 xmlFreeDoc(doc);
721 return(ret);
722}
723
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000724/************************************************************************
725 * *
726 * Libxml2 specific routines *
727 * *
728 ************************************************************************/
729
730int
731main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
732 int res, ret = 0;
733 int verbose = 0;
734 int old_errors, old_tests, old_leaks;
735
736 initializeLibxml2();
737
738 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
739 verbose = 1;
740
741
Daniel Veillarde84f2312005-07-02 07:31:28 +0000742 old_errors = nb_errors;
743 old_tests = nb_tests;
744 old_leaks = nb_leaks;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000745 res = xsdTest(verbose);
746 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
747 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
748 else
749 printf("Ran %d tests, %d errors, %d leaks\n",
750 nb_tests - old_tests,
751 nb_errors - old_errors,
752 nb_leaks - old_leaks);
753 old_errors = nb_errors;
754 old_tests = nb_tests;
755 old_leaks = nb_leaks;
756 res = rngTest1(verbose);
757 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
758 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
759 else
760 printf("Ran %d tests, %d errors, %d leaks\n",
761 nb_tests - old_tests,
762 nb_errors - old_errors,
763 nb_leaks - old_leaks);
764 old_errors = nb_errors;
765 old_tests = nb_tests;
766 old_leaks = nb_leaks;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000767 res = rngTest2(verbose);
768 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
769 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
770 else
771 printf("Ran %d tests, %d errors, %d leaks\n",
772 nb_tests - old_tests,
773 nb_errors - old_errors,
774 nb_leaks - old_leaks);
775 old_errors = nb_errors;
776 old_tests = nb_tests;
777 old_leaks = nb_leaks;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000778
779 if ((nb_errors == 0) && (nb_leaks == 0)) {
780 ret = 0;
781 printf("Total %d tests, no errors\n",
782 nb_tests);
783 } else {
784 ret = 1;
785 printf("Total %d tests, %d errors, %d leaks\n",
786 nb_tests, nb_errors, nb_leaks);
787 }
788 xmlCleanupParser();
789 xmlMemoryDump();
790
791 return(ret);
792}