OLD | NEW |
1 /* | 1 /* |
2 * runsuite.c: C program to run libxml2 againts published testsuites | 2 * runsuite.c: C program to run libxml2 againts published testsuites |
3 * | 3 * |
4 * See Copyright for the status of this software. | 4 * See Copyright for the status of this software. |
5 * | 5 * |
6 * daniel@veillard.com | 6 * daniel@veillard.com |
7 */ | 7 */ |
8 | 8 |
9 #ifdef HAVE_CONFIG_H | |
10 #include "libxml.h" | 9 #include "libxml.h" |
11 #else | |
12 #include <stdio.h> | 10 #include <stdio.h> |
13 #endif | |
14 | 11 |
15 #if !defined(_WIN32) || defined(__CYGWIN__) | 12 #if !defined(_WIN32) || defined(__CYGWIN__) |
16 #include <unistd.h> | 13 #include <unistd.h> |
17 #endif | 14 #endif |
18 #include <string.h> | 15 #include <string.h> |
19 #include <sys/types.h> | 16 #include <sys/types.h> |
20 #include <sys/stat.h> | 17 #include <sys/stat.h> |
21 #include <fcntl.h> | 18 #include <fcntl.h> |
22 | 19 |
23 #include <libxml/parser.h> | 20 #include <libxml/parser.h> |
24 #include <libxml/parserInternals.h> | 21 #include <libxml/parserInternals.h> |
25 #include <libxml/tree.h> | 22 #include <libxml/tree.h> |
26 #include <libxml/uri.h> | 23 #include <libxml/uri.h> |
27 #if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED) | 24 #if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED) |
28 #include <libxml/xmlreader.h> | 25 #include <libxml/xmlreader.h> |
29 | 26 |
30 #include <libxml/xpath.h> | 27 #include <libxml/xpath.h> |
31 #include <libxml/xpathInternals.h> | 28 #include <libxml/xpathInternals.h> |
32 | 29 |
33 #include <libxml/relaxng.h> | 30 #include <libxml/relaxng.h> |
34 #include <libxml/xmlschemas.h> | 31 #include <libxml/xmlschemas.h> |
35 #include <libxml/xmlschemastypes.h> | 32 #include <libxml/xmlschemastypes.h> |
36 | 33 |
37 #define LOGFILE "runsuite.log" | 34 #define LOGFILE "runsuite.log" |
38 static FILE *logfile = NULL; | 35 static FILE *logfile = NULL; |
39 static int verbose = 0; | 36 static int verbose = 0; |
40 | 37 |
41 | 38 |
42 | |
43 #if defined(_WIN32) && !defined(__CYGWIN__) | |
44 | |
45 #define vsnprintf _vsnprintf | |
46 | |
47 #define snprintf _snprintf | |
48 | |
49 #endif | |
50 | |
51 /************************************************************************ | 39 /************************************************************************ |
52 * * | 40 * * |
53 * File name and path utilities * | 41 * File name and path utilities * |
54 * * | 42 * * |
55 ************************************************************************/ | 43 ************************************************************************/ |
56 | 44 |
57 static int checkTestFile(const char *filename) { | 45 static int checkTestFile(const char *filename) { |
58 struct stat buf; | 46 struct stat buf; |
59 | 47 |
60 if (stat(filename, &buf) == -1) | 48 if (stat(filename, &buf) == -1) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 testEntitiesValue[nb_entities] = content; | 116 testEntitiesValue[nb_entities] = content; |
129 nb_entities++; | 117 nb_entities++; |
130 return(0); | 118 return(0); |
131 } | 119 } |
132 | 120 |
133 /* | 121 /* |
134 * We need to trap calls to the resolver to not account memory for the catalog | 122 * We need to trap calls to the resolver to not account memory for the catalog |
135 * which is shared to the current running test. We also don't want to have | 123 * which is shared to the current running test. We also don't want to have |
136 * network downloads modifying tests. | 124 * network downloads modifying tests. |
137 */ | 125 */ |
138 static xmlParserInputPtr | 126 static xmlParserInputPtr |
139 testExternalEntityLoader(const char *URL, const char *ID, | 127 testExternalEntityLoader(const char *URL, const char *ID, |
140 xmlParserCtxtPtr ctxt) { | 128 xmlParserCtxtPtr ctxt) { |
141 xmlParserInputPtr ret; | 129 xmlParserInputPtr ret; |
142 int i; | 130 int i; |
143 | 131 |
144 for (i = 0;i < nb_entities;i++) { | 132 for (i = 0;i < nb_entities;i++) { |
145 if (!strcmp(testEntitiesName[i], URL)) { | 133 if (!strcmp(testEntitiesName[i], URL)) { |
146 ret = xmlNewStringInputStream(ctxt, | 134 ret = xmlNewStringInputStream(ctxt, |
147 (const xmlChar *) testEntitiesValue[i]); | 135 (const xmlChar *) testEntitiesValue[i]); |
148 if (ret != NULL) { | 136 if (ret != NULL) { |
149 ret->filename = (const char *) | 137 ret->filename = (const char *) |
150 xmlStrdup((xmlChar *)testEntitiesName[i]); | 138 xmlStrdup((xmlChar *)testEntitiesName[i]); |
151 } | 139 } |
152 return(ret); | 140 return(ret); |
153 } | 141 } |
154 } | 142 } |
155 if (checkTestFile(URL)) { | 143 if (checkTestFile(URL)) { |
156 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt); | 144 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt); |
157 } else { | 145 } else { |
158 int memused = xmlMemUsed(); | 146 int memused = xmlMemUsed(); |
159 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt); | 147 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt); |
160 extraMemoryFromResolver += xmlMemUsed() - memused; | 148 extraMemoryFromResolver += xmlMemUsed() - memused; |
161 } | 149 } |
162 #if 0 | 150 #if 0 |
163 if (ret == NULL) { | 151 if (ret == NULL) { |
164 fprintf(stderr, "Failed to find resource %s\n", URL); | 152 fprintf(stderr, "Failed to find resource %s\n", URL); |
165 } | 153 } |
166 #endif | 154 #endif |
167 | 155 |
168 return(ret); | 156 return(ret); |
169 } | 157 } |
170 | 158 |
171 /* | 159 /* |
172 * Trapping the error messages at the generic level to grab the equivalent of | 160 * Trapping the error messages at the generic level to grab the equivalent of |
173 * stderr messages on CLI tools. | 161 * stderr messages on CLI tools. |
174 */ | 162 */ |
175 static char testErrors[32769]; | 163 static char testErrors[32769]; |
176 static int testErrorsSize = 0; | 164 static int testErrorsSize = 0; |
177 | 165 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 installResources(test, res); | 408 installResources(test, res); |
421 } | 409 } |
422 test = getNext(tst, "./dir[1]"); | 410 test = getNext(tst, "./dir[1]"); |
423 while (test != NULL) { | 411 while (test != NULL) { |
424 installDirs(test, res); | 412 installDirs(test, res); |
425 test = getNext(test, "following-sibling::dir[1]"); | 413 test = getNext(test, "following-sibling::dir[1]"); |
426 } | 414 } |
427 xmlFree(res); | 415 xmlFree(res); |
428 } | 416 } |
429 | 417 |
430 static int | 418 static int |
431 xsdTestCase(xmlNodePtr tst) { | 419 xsdTestCase(xmlNodePtr tst) { |
432 xmlNodePtr test, tmp, cur; | 420 xmlNodePtr test, tmp, cur; |
433 xmlBufferPtr buf; | 421 xmlBufferPtr buf; |
434 xmlDocPtr doc = NULL; | 422 xmlDocPtr doc = NULL; |
435 xmlRelaxNGParserCtxtPtr pctxt; | 423 xmlRelaxNGParserCtxtPtr pctxt; |
436 xmlRelaxNGValidCtxtPtr ctxt; | 424 xmlRelaxNGValidCtxtPtr ctxt; |
437 xmlRelaxNGPtr rng = NULL; | 425 xmlRelaxNGPtr rng = NULL; |
438 int ret = 0, mem, memt; | 426 int ret = 0, mem, memt; |
439 xmlChar *dtd; | 427 xmlChar *dtd; |
440 | 428 |
441 resetEntities(); | 429 resetEntities(); |
442 testErrorsSize = 0; testErrors[0] = 0; | 430 testErrorsSize = 0; testErrors[0] = 0; |
443 | 431 |
444 tmp = getNext(tst, "./dir[1]"); | 432 tmp = getNext(tst, "./dir[1]"); |
445 if (tmp != NULL) { | 433 if (tmp != NULL) { |
446 installDirs(tmp, NULL); | 434 installDirs(tmp, NULL); |
447 } | 435 } |
448 tmp = getNext(tst, "./resource[1]"); | 436 tmp = getNext(tst, "./resource[1]"); |
449 if (tmp != NULL) { | 437 if (tmp != NULL) { |
450 installResources(tmp, NULL); | 438 installResources(tmp, NULL); |
451 } | 439 } |
452 | 440 |
453 cur = getNext(tst, "./correct[1]"); | 441 cur = getNext(tst, "./correct[1]"); |
454 if (cur == NULL) { | 442 if (cur == NULL) { |
455 return(xsdIncorectTestCase(tst)); | 443 return(xsdIncorectTestCase(tst)); |
456 } | 444 } |
457 | 445 |
458 test = getNext(cur, "./*"); | 446 test = getNext(cur, "./*"); |
459 if (test == NULL) { | 447 if (test == NULL) { |
460 fprintf(stderr, "Failed to find test in correct line %ld\n", | 448 fprintf(stderr, "Failed to find test in correct line %ld\n", |
461 xmlGetLineNo(cur)); | 449 xmlGetLineNo(cur)); |
462 return(1); | 450 return(1); |
463 } | 451 } |
464 | 452 |
465 memt = xmlMemUsed(); | 453 memt = xmlMemUsed(); |
466 extraMemoryFromResolver = 0; | 454 extraMemoryFromResolver = 0; |
467 /* | 455 /* |
(...skipping 25 matching lines...) Expand all Loading... |
493 /* | 481 /* |
494 * now scan all the siblings of correct to process the <valid> tests | 482 * now scan all the siblings of correct to process the <valid> tests |
495 */ | 483 */ |
496 tmp = getNext(cur, "following-sibling::valid[1]"); | 484 tmp = getNext(cur, "following-sibling::valid[1]"); |
497 while (tmp != NULL) { | 485 while (tmp != NULL) { |
498 dtd = xmlGetProp(tmp, BAD_CAST "dtd"); | 486 dtd = xmlGetProp(tmp, BAD_CAST "dtd"); |
499 test = getNext(tmp, "./*"); | 487 test = getNext(tmp, "./*"); |
500 if (test == NULL) { | 488 if (test == NULL) { |
501 fprintf(stderr, "Failed to find test in <valid> line %ld\n", | 489 fprintf(stderr, "Failed to find test in <valid> line %ld\n", |
502 xmlGetLineNo(tmp)); | 490 xmlGetLineNo(tmp)); |
503 » | 491 |
504 } else { | 492 } else { |
505 xmlBufferEmpty(buf); | 493 xmlBufferEmpty(buf); |
506 if (dtd != NULL) | 494 if (dtd != NULL) |
507 xmlBufferAdd(buf, dtd, -1); | 495 xmlBufferAdd(buf, dtd, -1); |
508 xmlNodeDump(buf, test->doc, test, 0, 0); | 496 xmlNodeDump(buf, test->doc, test, 0, 0); |
509 | 497 |
510 /* | 498 /* |
511 * We are ready to run the test | 499 * We are ready to run the test |
512 */ | 500 */ |
513 mem = xmlMemUsed(); | 501 mem = xmlMemUsed(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 } | 540 } |
553 /* | 541 /* |
554 * now scan all the siblings of correct to process the <invalid> tests | 542 * now scan all the siblings of correct to process the <invalid> tests |
555 */ | 543 */ |
556 tmp = getNext(cur, "following-sibling::invalid[1]"); | 544 tmp = getNext(cur, "following-sibling::invalid[1]"); |
557 while (tmp != NULL) { | 545 while (tmp != NULL) { |
558 test = getNext(tmp, "./*"); | 546 test = getNext(tmp, "./*"); |
559 if (test == NULL) { | 547 if (test == NULL) { |
560 fprintf(stderr, "Failed to find test in <invalid> line %ld\n", | 548 fprintf(stderr, "Failed to find test in <invalid> line %ld\n", |
561 xmlGetLineNo(tmp)); | 549 xmlGetLineNo(tmp)); |
562 » | 550 |
563 } else { | 551 } else { |
564 xmlBufferEmpty(buf); | 552 xmlBufferEmpty(buf); |
565 xmlNodeDump(buf, test->doc, test, 0, 0); | 553 xmlNodeDump(buf, test->doc, test, 0, 0); |
566 | 554 |
567 /* | 555 /* |
568 * We are ready to run the test | 556 * We are ready to run the test |
569 */ | 557 */ |
570 mem = xmlMemUsed(); | 558 mem = xmlMemUsed(); |
571 extraMemoryFromResolver = 0; | 559 extraMemoryFromResolver = 0; |
572 doc = xmlReadMemory((const char *)buf->content, buf->use, | 560 doc = xmlReadMemory((const char *)buf->content, buf->use, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 xmlRelaxNGFree(rng); | 601 xmlRelaxNGFree(rng); |
614 xmlResetLastError(); | 602 xmlResetLastError(); |
615 if ((memt != xmlMemUsed()) && (memt != 0)) { | 603 if ((memt != xmlMemUsed()) && (memt != 0)) { |
616 test_log("Validation of tests starting line %ld leaked %d\n", | 604 test_log("Validation of tests starting line %ld leaked %d\n", |
617 xmlGetLineNo(cur), xmlMemUsed() - memt); | 605 xmlGetLineNo(cur), xmlMemUsed() - memt); |
618 nb_leaks++; | 606 nb_leaks++; |
619 } | 607 } |
620 return(ret); | 608 return(ret); |
621 } | 609 } |
622 | 610 |
623 static int | 611 static int |
624 xsdTestSuite(xmlNodePtr cur) { | 612 xsdTestSuite(xmlNodePtr cur) { |
625 if (verbose) { | 613 if (verbose) { |
626 xmlChar *doc = getString(cur, "string(documentation)"); | 614 xmlChar *doc = getString(cur, "string(documentation)"); |
627 | 615 |
628 if (doc != NULL) { | 616 if (doc != NULL) { |
629 printf("Suite %s\n", doc); | 617 printf("Suite %s\n", doc); |
630 xmlFree(doc); | 618 xmlFree(doc); |
631 } | 619 } |
632 } | 620 } |
633 cur = getNext(cur, "./testCase[1]"); | 621 cur = getNext(cur, "./testCase[1]"); |
634 while (cur != NULL) { | 622 while (cur != NULL) { |
635 xsdTestCase(cur); | 623 xsdTestCase(cur); |
636 cur = getNext(cur, "following-sibling::testCase[1]"); | 624 cur = getNext(cur, "following-sibling::testCase[1]"); |
637 } | 625 } |
638 | 626 |
639 return(0); | 627 return(0); |
640 } | 628 } |
641 | 629 |
642 static int | 630 static int |
643 xsdTest(void) { | 631 xsdTest(void) { |
644 xmlDocPtr doc; | 632 xmlDocPtr doc; |
645 xmlNodePtr cur; | 633 xmlNodePtr cur; |
646 const char *filename = "test/xsdtest/xsdtestsuite.xml"; | 634 const char *filename = "test/xsdtest/xsdtestsuite.xml"; |
647 int ret = 0; | 635 int ret = 0; |
648 | 636 |
649 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT); | 637 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT); |
650 if (doc == NULL) { | 638 if (doc == NULL) { |
651 fprintf(stderr, "Failed to parse %s\n", filename); | 639 fprintf(stderr, "Failed to parse %s\n", filename); |
652 return(-1); | 640 return(-1); |
(...skipping 17 matching lines...) Expand all Loading... |
670 xsdTestSuite(cur); | 658 xsdTestSuite(cur); |
671 cur = getNext(cur, "following-sibling::testSuite[1]"); | 659 cur = getNext(cur, "following-sibling::testSuite[1]"); |
672 } | 660 } |
673 | 661 |
674 done: | 662 done: |
675 if (doc != NULL) | 663 if (doc != NULL) |
676 xmlFreeDoc(doc); | 664 xmlFreeDoc(doc); |
677 return(ret); | 665 return(ret); |
678 } | 666 } |
679 | 667 |
680 static int | 668 static int |
681 rngTestSuite(xmlNodePtr cur) { | 669 rngTestSuite(xmlNodePtr cur) { |
682 if (verbose) { | 670 if (verbose) { |
683 xmlChar *doc = getString(cur, "string(documentation)"); | 671 xmlChar *doc = getString(cur, "string(documentation)"); |
684 | 672 |
685 if (doc != NULL) { | 673 if (doc != NULL) { |
686 printf("Suite %s\n", doc); | 674 printf("Suite %s\n", doc); |
687 xmlFree(doc); | 675 xmlFree(doc); |
688 } else { | 676 } else { |
689 doc = getString(cur, "string(section)"); | 677 doc = getString(cur, "string(section)"); |
690 if (doc != NULL) { | 678 if (doc != NULL) { |
691 printf("Section %s\n", doc); | 679 printf("Section %s\n", doc); |
692 xmlFree(doc); | 680 xmlFree(doc); |
693 } | 681 } |
694 } | 682 } |
695 } | 683 } |
696 cur = getNext(cur, "./testSuite[1]"); | 684 cur = getNext(cur, "./testSuite[1]"); |
697 while (cur != NULL) { | 685 while (cur != NULL) { |
698 xsdTestSuite(cur); | 686 xsdTestSuite(cur); |
699 cur = getNext(cur, "following-sibling::testSuite[1]"); | 687 cur = getNext(cur, "following-sibling::testSuite[1]"); |
700 } | 688 } |
701 | 689 |
702 return(0); | 690 return(0); |
703 } | 691 } |
704 | 692 |
705 static int | 693 static int |
706 rngTest1(void) { | 694 rngTest1(void) { |
707 xmlDocPtr doc; | 695 xmlDocPtr doc; |
708 xmlNodePtr cur; | 696 xmlNodePtr cur; |
709 const char *filename = "test/relaxng/OASIS/spectest.xml"; | 697 const char *filename = "test/relaxng/OASIS/spectest.xml"; |
710 int ret = 0; | 698 int ret = 0; |
711 | 699 |
712 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT); | 700 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT); |
713 if (doc == NULL) { | 701 if (doc == NULL) { |
714 fprintf(stderr, "Failed to parse %s\n", filename); | 702 fprintf(stderr, "Failed to parse %s\n", filename); |
715 return(-1); | 703 return(-1); |
(...skipping 17 matching lines...) Expand all Loading... |
733 rngTestSuite(cur); | 721 rngTestSuite(cur); |
734 cur = getNext(cur, "following-sibling::testSuite[1]"); | 722 cur = getNext(cur, "following-sibling::testSuite[1]"); |
735 } | 723 } |
736 | 724 |
737 done: | 725 done: |
738 if (doc != NULL) | 726 if (doc != NULL) |
739 xmlFreeDoc(doc); | 727 xmlFreeDoc(doc); |
740 return(ret); | 728 return(ret); |
741 } | 729 } |
742 | 730 |
743 static int | 731 static int |
744 rngTest2(void) { | 732 rngTest2(void) { |
745 xmlDocPtr doc; | 733 xmlDocPtr doc; |
746 xmlNodePtr cur; | 734 xmlNodePtr cur; |
747 const char *filename = "test/relaxng/testsuite.xml"; | 735 const char *filename = "test/relaxng/testsuite.xml"; |
748 int ret = 0; | 736 int ret = 0; |
749 | 737 |
750 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT); | 738 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT); |
751 if (doc == NULL) { | 739 if (doc == NULL) { |
752 fprintf(stderr, "Failed to parse %s\n", filename); | 740 fprintf(stderr, "Failed to parse %s\n", filename); |
753 return(-1); | 741 return(-1); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) { | 931 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) { |
944 test_log("valid schemas %s hit an unimplemented block\n", | 932 test_log("valid schemas %s hit an unimplemented block\n", |
945 path); | 933 path); |
946 ret = 1; | 934 ret = 1; |
947 nb_unimplemented++; | 935 nb_unimplemented++; |
948 nb_errors++; | 936 nb_errors++; |
949 } | 937 } |
950 instance = getNext(cur, "./ts:instanceTest[1]"); | 938 instance = getNext(cur, "./ts:instanceTest[1]"); |
951 while (instance != NULL) { | 939 while (instance != NULL) { |
952 if (schemas != NULL) { | 940 if (schemas != NULL) { |
953 » » xstcTestInstance(instance, schemas, path, base);» » | 941 » » xstcTestInstance(instance, schemas, path, base); |
954 } else { | 942 } else { |
955 /* | 943 /* |
956 * We'll automatically mark the instances as failed | 944 * We'll automatically mark the instances as failed |
957 * if the schema was broken. | 945 * if the schema was broken. |
958 */ | 946 */ |
959 nb_errors++; | 947 nb_errors++; |
960 } | 948 } |
961 instance = getNext(instance, | 949 instance = getNext(instance, |
962 "following-sibling::ts:instanceTest[1]"); | 950 "following-sibling::ts:instanceTest[1]"); |
963 } | 951 } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1175 if (logfile != NULL) | 1163 if (logfile != NULL) |
1176 fclose(logfile); | 1164 fclose(logfile); |
1177 return(ret); | 1165 return(ret); |
1178 } | 1166 } |
1179 #else /* !SCHEMAS */ | 1167 #else /* !SCHEMAS */ |
1180 int | 1168 int |
1181 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { | 1169 main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { |
1182 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\
n"); | 1170 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\
n"); |
1183 } | 1171 } |
1184 #endif | 1172 #endif |
OLD | NEW |