blob: 3d9d6b72b9da9b229d44034bd0f7326c92f54c52 [file] [log] [blame]
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001/*
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00002 * runsuite.c: C program to run libxml2 againts published testsuites
Daniel Veillardf2e066a2005-06-30 13:04:44 +00003 *
4 * See Copyright for the status of this software.
5 *
6 * daniel@veillard.com
7 */
8
Daniel Veillardc9352532005-07-04 14:25:34 +00009#if !defined(_WIN32) || defined(__CYGWIN__)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000010#include <unistd.h>
Daniel Veillardc9352532005-07-04 14:25:34 +000011#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000012#include <string.h>
13#include <stdio.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000014#include <sys/types.h>
15#include <sys/stat.h>
16#include <fcntl.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000017
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>
Daniel Veillard95175012005-07-03 16:09:51 +000022#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000023#include <libxml/xmlreader.h>
24
25#include <libxml/xpath.h>
26#include <libxml/xpathInternals.h>
27
28#include <libxml/relaxng.h>
29#include <libxml/xmlschemas.h>
30#include <libxml/xmlschemastypes.h>
31
Daniel Veillardc9352532005-07-04 14:25:34 +000032#define LOGFILE "runsuite.log"
33FILE *logfile = NULL;
34int verbose = 0;
35
Daniel Veillardf2e066a2005-06-30 13:04:44 +000036/************************************************************************
37 * *
38 * File name and path utilities *
39 * *
40 ************************************************************************/
41
42static int checkTestFile(const char *filename) {
43 struct stat buf;
44
45 if (stat(filename, &buf) == -1)
46 return(0);
47
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000048#if defined(_WIN32) && !defined(__CYGWIN__)
49 if (!(buf.st_mode & _S_IFREG))
50 return(0);
51#else
Daniel Veillardf2e066a2005-06-30 13:04:44 +000052 if (!S_ISREG(buf.st_mode))
53 return(0);
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000054#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000055
56 return(1);
57}
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000058
Daniel Veillarde84f2312005-07-02 07:31:28 +000059static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
60 char buf[500];
61
62 if (dir == NULL) return(xmlStrdup(path));
63 if (path == NULL) return(NULL);
64
65 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
66 return(xmlStrdup((const xmlChar *) buf));
67}
Daniel Veillardf2e066a2005-06-30 13:04:44 +000068
69/************************************************************************
70 * *
71 * Libxml2 specific routines *
72 * *
73 ************************************************************************/
74
75static int nb_tests = 0;
76static int nb_errors = 0;
Daniel Veillardc9352532005-07-04 14:25:34 +000077static int nb_internals = 0;
78static int nb_schematas = 0;
Daniel Veillard90837782005-07-04 15:45:10 +000079static int nb_unimplemented = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000080static int nb_leaks = 0;
81static long libxmlMemoryAllocatedBase = 0;
82static int extraMemoryFromResolver = 0;
83
84static int
85fatalError(void) {
86 fprintf(stderr, "Exitting tests on fatal error\n");
87 exit(1);
88}
89
90/*
Daniel Veillarde84f2312005-07-02 07:31:28 +000091 * that's needed to implement <resource>
92 */
93#define MAX_ENTITIES 20
94char *testEntitiesName[MAX_ENTITIES];
95char *testEntitiesValue[MAX_ENTITIES];
96int nb_entities = 0;
97static void resetEntities(void) {
98 int i;
99
100 for (i = 0;i < nb_entities;i++) {
101 if (testEntitiesName[i] != NULL)
102 xmlFree(testEntitiesName[i]);
103 if (testEntitiesValue[i] != NULL)
104 xmlFree(testEntitiesValue[i]);
105 }
106 nb_entities = 0;
107}
108static int addEntity(char *name, char *content) {
109 if (nb_entities >= MAX_ENTITIES) {
110 fprintf(stderr, "Too many entities defined\n");
111 return(-1);
112 }
113 testEntitiesName[nb_entities] = name;
114 testEntitiesValue[nb_entities] = content;
115 nb_entities++;
116 return(0);
117}
118
119/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000120 * We need to trap calls to the resolver to not account memory for the catalog
121 * which is shared to the current running test. We also don't want to have
122 * network downloads modifying tests.
123 */
124static xmlParserInputPtr
125testExternalEntityLoader(const char *URL, const char *ID,
126 xmlParserCtxtPtr ctxt) {
127 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000128 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000129
Daniel Veillarde84f2312005-07-02 07:31:28 +0000130 for (i = 0;i < nb_entities;i++) {
131 if (!strcmp(testEntitiesName[i], URL)) {
132 ret = xmlNewStringInputStream(ctxt,
133 (const xmlChar *) testEntitiesValue[i]);
134 if (ret != NULL) {
135 ret->filename = (const char *)
136 xmlStrdup((xmlChar *)testEntitiesName[i]);
137 }
138 return(ret);
139 }
140 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000141 if (checkTestFile(URL)) {
142 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
143 } else {
144 int memused = xmlMemUsed();
145 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
146 extraMemoryFromResolver += xmlMemUsed() - memused;
147 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000148#if 0
Daniel Veillarde84f2312005-07-02 07:31:28 +0000149 if (ret == NULL) {
150 fprintf(stderr, "Failed to find resource %s\n", URL);
151 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000152#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000153
154 return(ret);
155}
156
157/*
158 * Trapping the error messages at the generic level to grab the equivalent of
159 * stderr messages on CLI tools.
160 */
161static char testErrors[32769];
162static int testErrorsSize = 0;
163
Daniel Veillardc9352532005-07-04 14:25:34 +0000164static void test_log(const char *msg, ...) {
165 va_list args;
166 if (logfile != NULL) {
167 fprintf(logfile, "\n------------\n");
168 va_start(args, msg);
169 vfprintf(logfile, msg, args);
170 va_end(args);
171 fprintf(logfile, "%s", testErrors);
172 testErrorsSize = 0; testErrors[0] = 0;
173 }
174 if (verbose) {
175 va_start(args, msg);
176 vfprintf(stderr, msg, args);
177 va_end(args);
178 }
179}
180
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000181static void
182testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
183 va_list args;
184 int res;
185
186 if (testErrorsSize >= 32768)
187 return;
188 va_start(args, msg);
189 res = vsnprintf(&testErrors[testErrorsSize],
190 32768 - testErrorsSize,
191 msg, args);
192 va_end(args);
193 if (testErrorsSize + res >= 32768) {
194 /* buffer is full */
195 testErrorsSize = 32768;
196 testErrors[testErrorsSize] = 0;
197 } else {
198 testErrorsSize += res;
199 }
200 testErrors[testErrorsSize] = 0;
201}
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000202
203xmlXPathContextPtr ctxtXPath;
204
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000205static void
206initializeLibxml2(void) {
207 xmlGetWarningsDefaultValue = 0;
208 xmlPedanticParserDefault(0);
209
210 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
211 xmlInitParser();
212 xmlSetExternalEntityLoader(testExternalEntityLoader);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000213 ctxtXPath = xmlXPathNewContext(NULL);
214 /* used as default nanemspace in xstc tests */
215 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
216 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
217 BAD_CAST "http://www.w3.org/1999/xlink");
218 xmlSetGenericErrorFunc(NULL, testErrorHandler);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000219#ifdef LIBXML_SCHEMAS_ENABLED
220 xmlSchemaInitTypes();
221 xmlRelaxNGInitTypes();
222#endif
223 libxmlMemoryAllocatedBase = xmlMemUsed();
224}
225
226static xmlNodePtr
227getNext(xmlNodePtr cur, const char *xpath) {
228 xmlNodePtr ret = NULL;
229 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000230 xmlXPathCompExprPtr comp;
231
232 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
233 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000234 ctxtXPath->doc = cur->doc;
235 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000236 comp = xmlXPathCompile(BAD_CAST xpath);
237 if (comp == NULL) {
238 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000239 return(NULL);
240 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000241 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000242 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000243 if (res == NULL)
244 return(NULL);
245 if ((res->type == XPATH_NODESET) &&
246 (res->nodesetval != NULL) &&
247 (res->nodesetval->nodeNr > 0) &&
248 (res->nodesetval->nodeTab != NULL))
249 ret = res->nodesetval->nodeTab[0];
250 xmlXPathFreeObject(res);
251 return(ret);
252}
253
254static xmlChar *
255getString(xmlNodePtr cur, const char *xpath) {
256 xmlChar *ret = NULL;
257 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000258 xmlXPathCompExprPtr comp;
259
260 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
261 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000262 ctxtXPath->doc = cur->doc;
263 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000264 comp = xmlXPathCompile(BAD_CAST xpath);
265 if (comp == NULL) {
266 fprintf(stderr, "Failed to compile %s\n", xpath);
267 return(NULL);
268 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000269 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000270 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000271 if (res == NULL)
272 return(NULL);
273 if (res->type == XPATH_STRING) {
274 ret = res->stringval;
275 res->stringval = NULL;
276 }
277 xmlXPathFreeObject(res);
278 return(ret);
279}
280
281/************************************************************************
282 * *
283 * Test test/xsdtest/xsdtestsuite.xml *
284 * *
285 ************************************************************************/
286
287static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000288xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000289 xmlNodePtr test;
290 xmlBufferPtr buf;
291 xmlRelaxNGParserCtxtPtr pctxt;
292 xmlRelaxNGPtr rng = NULL;
293 int ret = 0, memt;
294
295 cur = getNext(cur, "./incorrect[1]");
296 if (cur == NULL) {
297 return(0);
298 }
299
300 test = getNext(cur, "./*");
301 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000302 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000303 xmlGetLineNo(cur));
304 return(1);
305 }
306
307 memt = xmlMemUsed();
308 extraMemoryFromResolver = 0;
309 /*
310 * dump the schemas to a buffer, then reparse it and compile the schemas
311 */
312 buf = xmlBufferCreate();
313 if (buf == NULL) {
314 fprintf(stderr, "out of memory !\n");
315 fatalError();
316 }
317 xmlNodeDump(buf, test->doc, test, 0, 0);
318 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
319 xmlRelaxNGSetParserErrors(pctxt,
320 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
321 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
322 pctxt);
323 rng = xmlRelaxNGParse(pctxt);
324 xmlRelaxNGFreeParserCtxt(pctxt);
325 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000326 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000327 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000328 ret = 1;
329 goto done;
330 }
331
332done:
333 if (buf != NULL)
334 xmlBufferFree(buf);
335 if (rng != NULL)
336 xmlRelaxNGFree(rng);
337 xmlResetLastError();
338 if ((memt != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000339 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000340 xmlGetLineNo(cur), xmlMemUsed() - memt);
341 nb_leaks++;
342 }
343 return(ret);
344}
345
Daniel Veillarde84f2312005-07-02 07:31:28 +0000346static void
347installResources(xmlNodePtr tst, const xmlChar *base) {
348 xmlNodePtr test;
349 xmlBufferPtr buf;
350 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000351
Daniel Veillarde84f2312005-07-02 07:31:28 +0000352 buf = xmlBufferCreate();
353 if (buf == NULL) {
354 fprintf(stderr, "out of memory !\n");
355 fatalError();
356 }
357 xmlNodeDump(buf, tst->doc, tst, 0, 0);
358
359 while (tst != NULL) {
360 test = getNext(tst, "./*");
361 if (test != NULL) {
362 xmlBufferEmpty(buf);
363 xmlNodeDump(buf, test->doc, test, 0, 0);
364 name = getString(tst, "string(@name)");
365 content = xmlStrdup(buf->content);
366 if ((name != NULL) && (content != NULL)) {
367 res = composeDir(base, name);
368 xmlFree(name);
369 addEntity((char *) res, (char *) content);
370 } else {
371 if (name != NULL) xmlFree(name);
372 if (content != NULL) xmlFree(content);
373 }
374 }
375 tst = getNext(tst, "following-sibling::resource[1]");
376 }
377 if (buf != NULL)
378 xmlBufferFree(buf);
379}
380
381static void
382installDirs(xmlNodePtr tst, const xmlChar *base) {
383 xmlNodePtr test;
384 xmlChar *name, *res;
385
386 name = getString(tst, "string(@name)");
387 if (name == NULL)
388 return;
389 res = composeDir(base, name);
390 xmlFree(name);
391 if (res == NULL) {
392 return;
393 }
394 /* Now process resources and subdir recursively */
395 test = getNext(tst, "./resource[1]");
396 if (test != NULL) {
397 installResources(test, res);
398 }
399 test = getNext(tst, "./dir[1]");
400 while (test != NULL) {
401 installDirs(test, res);
402 test = getNext(test, "following-sibling::dir[1]");
403 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000404 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000405}
406
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000407static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000408xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000409 xmlNodePtr test, tmp, cur;
410 xmlBufferPtr buf;
411 xmlDocPtr doc = NULL;
412 xmlRelaxNGParserCtxtPtr pctxt;
413 xmlRelaxNGValidCtxtPtr ctxt;
414 xmlRelaxNGPtr rng = NULL;
415 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000416 xmlChar *dtd;
417
418 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000419 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000420
421 tmp = getNext(tst, "./dir[1]");
422 if (tmp != NULL) {
423 installDirs(tmp, NULL);
424 }
425 tmp = getNext(tst, "./resource[1]");
426 if (tmp != NULL) {
427 installResources(tmp, NULL);
428 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000429
430 cur = getNext(tst, "./correct[1]");
431 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000432 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000433 }
434
435 test = getNext(cur, "./*");
436 if (test == NULL) {
437 fprintf(stderr, "Failed to find test in correct line %ld\n",
438 xmlGetLineNo(cur));
439 return(1);
440 }
441
442 memt = xmlMemUsed();
443 extraMemoryFromResolver = 0;
444 /*
445 * dump the schemas to a buffer, then reparse it and compile the schemas
446 */
447 buf = xmlBufferCreate();
448 if (buf == NULL) {
449 fprintf(stderr, "out of memory !\n");
450 fatalError();
451 }
452 xmlNodeDump(buf, test->doc, test, 0, 0);
453 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
454 xmlRelaxNGSetParserErrors(pctxt,
455 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
456 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
457 pctxt);
458 rng = xmlRelaxNGParse(pctxt);
459 xmlRelaxNGFreeParserCtxt(pctxt);
460 if (extraMemoryFromResolver)
461 memt = 0;
462
463 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000464 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000465 xmlGetLineNo(test));
466 nb_errors++;
467 ret = 1;
468 goto done;
469 }
470 /*
471 * now scan all the siblings of correct to process the <valid> tests
472 */
473 tmp = getNext(cur, "following-sibling::valid[1]");
474 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000475 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000476 test = getNext(tmp, "./*");
477 if (test == NULL) {
478 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
479 xmlGetLineNo(tmp));
480
481 } else {
482 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000483 if (dtd != NULL)
484 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000485 xmlNodeDump(buf, test->doc, test, 0, 0);
486
487 /*
488 * We are ready to run the test
489 */
490 mem = xmlMemUsed();
491 extraMemoryFromResolver = 0;
492 doc = xmlReadMemory((const char *)buf->content, buf->use,
493 "test", NULL, 0);
494 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000495 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000496 xmlGetLineNo(tmp));
497 nb_errors++;
498 } else {
499 nb_tests++;
500 ctxt = xmlRelaxNGNewValidCtxt(rng);
501 xmlRelaxNGSetValidErrors(ctxt,
502 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
503 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
504 ctxt);
505 ret = xmlRelaxNGValidateDoc(ctxt, doc);
506 xmlRelaxNGFreeValidCtxt(ctxt);
507 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000508 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000509 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000510 nb_errors++;
511 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000512 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000513 xmlGetLineNo(tmp));
514 nb_errors++;
515 }
516 xmlFreeDoc(doc);
517 }
518 xmlResetLastError();
519 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000520 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000521 xmlGetLineNo(tmp), xmlMemUsed() - mem);
522 xmlMemoryDump();
523 nb_leaks++;
524 }
525 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000526 if (dtd != NULL)
527 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000528 tmp = getNext(tmp, "following-sibling::valid[1]");
529 }
530 /*
531 * now scan all the siblings of correct to process the <invalid> tests
532 */
533 tmp = getNext(cur, "following-sibling::invalid[1]");
534 while (tmp != NULL) {
535 test = getNext(tmp, "./*");
536 if (test == NULL) {
537 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
538 xmlGetLineNo(tmp));
539
540 } else {
541 xmlBufferEmpty(buf);
542 xmlNodeDump(buf, test->doc, test, 0, 0);
543
544 /*
545 * We are ready to run the test
546 */
547 mem = xmlMemUsed();
548 extraMemoryFromResolver = 0;
549 doc = xmlReadMemory((const char *)buf->content, buf->use,
550 "test", NULL, 0);
551 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000552 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000553 xmlGetLineNo(tmp));
554 nb_errors++;
555 } else {
556 nb_tests++;
557 ctxt = xmlRelaxNGNewValidCtxt(rng);
558 xmlRelaxNGSetValidErrors(ctxt,
559 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
560 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
561 ctxt);
562 ret = xmlRelaxNGValidateDoc(ctxt, doc);
563 xmlRelaxNGFreeValidCtxt(ctxt);
564 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000565 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000566 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000567 nb_errors++;
568 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000569 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000570 xmlGetLineNo(tmp));
571 nb_errors++;
572 }
573 xmlFreeDoc(doc);
574 }
575 xmlResetLastError();
576 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000577 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000578 xmlGetLineNo(tmp), xmlMemUsed() - mem);
579 xmlMemoryDump();
580 nb_leaks++;
581 }
582 }
583 tmp = getNext(tmp, "following-sibling::invalid[1]");
584 }
585
586done:
587 if (buf != NULL)
588 xmlBufferFree(buf);
589 if (rng != NULL)
590 xmlRelaxNGFree(rng);
591 xmlResetLastError();
592 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000593 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000594 xmlGetLineNo(cur), xmlMemUsed() - memt);
595 nb_leaks++;
596 }
597 return(ret);
598}
599
600static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000601xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000602 if (verbose) {
603 xmlChar *doc = getString(cur, "string(documentation)");
604
605 if (doc != NULL) {
606 printf("Suite %s\n", doc);
607 xmlFree(doc);
608 }
609 }
610 cur = getNext(cur, "./testCase[1]");
611 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000612 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000613 cur = getNext(cur, "following-sibling::testCase[1]");
614 }
615
616 return(0);
617}
618
619static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000620xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000621 xmlDocPtr doc;
622 xmlNodePtr cur;
623 const char *filename = "test/xsdtest/xsdtestsuite.xml";
624 int ret = 0;
625
626 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
627 if (doc == NULL) {
628 fprintf(stderr, "Failed to parse %s\n", filename);
629 return(-1);
630 }
631 printf("## XML Schemas datatypes test suite from James Clark\n");
632
633 cur = xmlDocGetRootElement(doc);
634 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
635 fprintf(stderr, "Unexpected format %s\n", filename);
636 ret = -1;
637 goto done;
638 }
639
640 cur = getNext(cur, "./testSuite[1]");
641 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
642 fprintf(stderr, "Unexpected format %s\n", filename);
643 ret = -1;
644 goto done;
645 }
646 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000647 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000648 cur = getNext(cur, "following-sibling::testSuite[1]");
649 }
650
651done:
652 if (doc != NULL)
653 xmlFreeDoc(doc);
654 return(ret);
655}
656
657static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000658rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000659 if (verbose) {
660 xmlChar *doc = getString(cur, "string(documentation)");
661
662 if (doc != NULL) {
663 printf("Suite %s\n", doc);
664 xmlFree(doc);
665 } else {
666 doc = getString(cur, "string(section)");
667 if (doc != NULL) {
668 printf("Section %s\n", doc);
669 xmlFree(doc);
670 }
671 }
672 }
673 cur = getNext(cur, "./testSuite[1]");
674 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000675 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000676 cur = getNext(cur, "following-sibling::testSuite[1]");
677 }
678
679 return(0);
680}
681
682static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000683rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000684 xmlDocPtr doc;
685 xmlNodePtr cur;
686 const char *filename = "test/relaxng/OASIS/spectest.xml";
687 int ret = 0;
688
689 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
690 if (doc == NULL) {
691 fprintf(stderr, "Failed to parse %s\n", filename);
692 return(-1);
693 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000694 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000695
696 cur = xmlDocGetRootElement(doc);
697 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
698 fprintf(stderr, "Unexpected format %s\n", filename);
699 ret = -1;
700 goto done;
701 }
702
703 cur = getNext(cur, "./testSuite[1]");
704 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
705 fprintf(stderr, "Unexpected format %s\n", filename);
706 ret = -1;
707 goto done;
708 }
709 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000710 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000711 cur = getNext(cur, "following-sibling::testSuite[1]");
712 }
713
714done:
715 if (doc != NULL)
716 xmlFreeDoc(doc);
717 return(ret);
718}
719
Daniel Veillarde84f2312005-07-02 07:31:28 +0000720static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000721rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000722 xmlDocPtr doc;
723 xmlNodePtr cur;
724 const char *filename = "test/relaxng/testsuite.xml";
725 int ret = 0;
726
727 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
728 if (doc == NULL) {
729 fprintf(stderr, "Failed to parse %s\n", filename);
730 return(-1);
731 }
732 printf("## Relax NG test suite for libxml2\n");
733
734 cur = xmlDocGetRootElement(doc);
735 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
736 fprintf(stderr, "Unexpected format %s\n", filename);
737 ret = -1;
738 goto done;
739 }
740
741 cur = getNext(cur, "./testSuite[1]");
742 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
743 fprintf(stderr, "Unexpected format %s\n", filename);
744 ret = -1;
745 goto done;
746 }
747 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000748 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000749 cur = getNext(cur, "following-sibling::testSuite[1]");
750 }
751
752done:
753 if (doc != NULL)
754 xmlFreeDoc(doc);
755 return(ret);
756}
757
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000758/************************************************************************
759 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000760 * Schemas test suites from W3C/NIST/MS/Sun *
761 * *
762 ************************************************************************/
763
764static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000765xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000766 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000767 xmlChar *href = NULL;
768 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000769 xmlChar *validity = NULL;
770 xmlSchemaValidCtxtPtr ctxt = NULL;
771 xmlDocPtr doc = NULL;
772 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000773
Daniel Veillardde0e4982005-07-03 14:35:44 +0000774 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000775 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000776 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000777 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000778 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000779 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000780 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000781 xmlGetLineNo(cur));
782 ret = -1;
783 goto done;
784 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000785 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000786 if (path == NULL) {
787 fprintf(stderr,
788 "Failed to build path to schemas testGroup line %ld : %s\n",
789 xmlGetLineNo(cur), href);
790 ret = -1;
791 goto done;
792 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000793 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000794 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000795 xmlGetLineNo(cur), path);
796 ret = -1;
797 goto done;
798 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000799 validity = getString(cur,
800 "string(ts:expected/@validity)");
801 if (validity == NULL) {
802 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
803 xmlGetLineNo(cur));
804 ret = -1;
805 goto done;
806 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000807 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000808 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
809 if (doc == NULL) {
810 fprintf(stderr, "instance %s fails to parse\n", path);
811 ret = -1;
812 nb_errors++;
813 goto done;
814 }
815
816 ctxt = xmlSchemaNewValidCtxt(schemas);
817 xmlSchemaSetValidErrors(ctxt,
818 (xmlSchemaValidityErrorFunc) testErrorHandler,
819 (xmlSchemaValidityWarningFunc) testErrorHandler,
820 ctxt);
821 ret = xmlSchemaValidateDoc(ctxt, doc);
822
823 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000824 if (ret > 0) {
825 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000826 path, spath);
827 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000828 } else if (ret < 0) {
829 test_log("valid instance %s got internal error validating %s\n",
830 path, spath);
831 nb_internals++;
832 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000833 }
834 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
835 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000836 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000837 path, spath);
838 nb_errors++;
839 }
840 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000841 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000842 xmlGetLineNo(cur), validity);
843 ret = -1;
844 goto done;
845 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000846
847done:
848 if (href != NULL) xmlFree(href);
849 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000850 if (validity != NULL) xmlFree(validity);
851 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
852 if (doc != NULL) xmlFreeDoc(doc);
853 xmlResetLastError();
854 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000855 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000856 xmlGetLineNo(cur), xmlMemUsed() - mem);
857 nb_leaks++;
858 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000859 return(ret);
860}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000861
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000862static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000863xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000864 xmlChar *href = NULL;
865 xmlChar *path = NULL;
866 xmlChar *validity = NULL;
867 xmlSchemaPtr schemas = NULL;
868 xmlSchemaParserCtxtPtr ctxt;
869 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000870 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000871
Daniel Veillardde0e4982005-07-03 14:35:44 +0000872 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000873 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000874 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000875 href = getString(cur,
876 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
877 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000878 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000879 xmlGetLineNo(cur));
880 ret = -1;
881 goto done;
882 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000883 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000884 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000885 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000886 xmlGetLineNo(cur), href);
887 ret = -1;
888 goto done;
889 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000890 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000891 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000892 xmlGetLineNo(cur), path);
893 ret = -1;
894 goto done;
895 }
896 validity = getString(cur,
897 "string(ts:schemaTest/ts:expected/@validity)");
898 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000899 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000900 xmlGetLineNo(cur));
901 ret = -1;
902 goto done;
903 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000904 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000905 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000906 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000907 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000908 xmlSchemaSetParserErrors(ctxt,
909 (xmlSchemaValidityErrorFunc) testErrorHandler,
910 (xmlSchemaValidityWarningFunc) testErrorHandler,
911 ctxt);
912 schemas = xmlSchemaParse(ctxt);
913 xmlSchemaFreeParserCtxt(ctxt);
914 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000915 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000916 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000917 ret = 1;
918 nb_errors++;
919 }
920 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
921 test_log("valid schemas %s hit an unimplemented block\n",
922 path);
923 ret = 1;
924 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000925 nb_errors++;
926 }
927 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000928 while (instance != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000929 xstcTestInstance(instance, schemas, path, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000930 instance = getNext(instance,
931 "following-sibling::ts:instanceTest[1]");
932 }
933 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000934 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000935 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000936 xmlSchemaSetParserErrors(ctxt,
937 (xmlSchemaValidityErrorFunc) testErrorHandler,
938 (xmlSchemaValidityWarningFunc) testErrorHandler,
939 ctxt);
940 schemas = xmlSchemaParse(ctxt);
941 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000942 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000943 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000944 path);
945 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000946 ret = 1;
947 }
948 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
949 nb_unimplemented++;
950 test_log("invalid schemas %s hit an unimplemented block\n",
951 path);
952 ret = 1;
953 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000954 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000955 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000956 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000957 xmlGetLineNo(cur), validity);
958 ret = -1;
959 goto done;
960 }
961
962done:
963 if (href != NULL) xmlFree(href);
964 if (path != NULL) xmlFree(path);
965 if (validity != NULL) xmlFree(validity);
966 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000967 xmlResetLastError();
968 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000969 test_log("Processing test line %ld %s leaked %d\n",
970 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000971 nb_leaks++;
972 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000973 return(ret);
974}
975
976static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000977xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000978 xmlDocPtr doc;
979 xmlNodePtr cur;
980 xmlChar *contributor;
981 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000982 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000983
984 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
985 if (doc == NULL) {
986 fprintf(stderr, "Failed to parse %s\n", metadata);
987 return(-1);
988 }
989
990 cur = xmlDocGetRootElement(doc);
991 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
992 fprintf(stderr, "Unexpected format %s\n", metadata);
993 return(-1);
994 }
995 contributor = xmlGetProp(cur, BAD_CAST "contributor");
996 if (contributor == NULL) {
997 contributor = xmlStrdup(BAD_CAST "Unknown");
998 }
999 name = xmlGetProp(cur, BAD_CAST "name");
1000 if (name == NULL) {
1001 name = xmlStrdup(BAD_CAST "Unknown");
1002 }
1003 printf("## %s test suite for Schemas version %s\n", contributor, name);
1004 xmlFree(contributor);
1005 xmlFree(name);
1006
1007 cur = getNext(cur, "./ts:testGroup[1]");
1008 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1009 fprintf(stderr, "Unexpected format %s\n", metadata);
1010 ret = -1;
1011 goto done;
1012 }
1013 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001014 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001015 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1016 }
1017
1018done:
1019 xmlFreeDoc(doc);
1020 return(ret);
1021}
1022
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001023/************************************************************************
1024 * *
1025 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001026 * *
1027 ************************************************************************/
1028
1029int
1030main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1031 int res, ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001032 int old_errors, old_tests, old_leaks;
1033
Daniel Veillardc9352532005-07-04 14:25:34 +00001034 logfile = fopen(LOGFILE, "w");
1035 if (logfile == NULL) {
1036 fprintf(stderr,
1037 "Could not open the log file, running in verbose mode\n");
1038 verbose = 1;
1039 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001040 initializeLibxml2();
1041
1042 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1043 verbose = 1;
1044
1045
Daniel Veillarde84f2312005-07-02 07:31:28 +00001046 old_errors = nb_errors;
1047 old_tests = nb_tests;
1048 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001049 res = xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001050 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1051 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1052 else
1053 printf("Ran %d tests, %d errors, %d leaks\n",
1054 nb_tests - old_tests,
1055 nb_errors - old_errors,
1056 nb_leaks - old_leaks);
1057 old_errors = nb_errors;
1058 old_tests = nb_tests;
1059 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001060 res = rngTest1();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001061 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1062 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1063 else
1064 printf("Ran %d tests, %d errors, %d leaks\n",
1065 nb_tests - old_tests,
1066 nb_errors - old_errors,
1067 nb_leaks - old_leaks);
1068 old_errors = nb_errors;
1069 old_tests = nb_tests;
1070 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001071 res = rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +00001072 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1073 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1074 else
1075 printf("Ran %d tests, %d errors, %d leaks\n",
1076 nb_tests - old_tests,
1077 nb_errors - old_errors,
1078 nb_leaks - old_leaks);
1079 old_errors = nb_errors;
1080 old_tests = nb_tests;
1081 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001082 nb_internals = 0;
1083 nb_schematas = 0;
1084 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001085 "xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
1086 "xstc/Tests/Metadata/");
1087 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001088 printf("Ran %d tests (%d schemata), no errors\n",
1089 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001090 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001091 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001092 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001093 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001094 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001095 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001096 nb_leaks - old_leaks);
1097 old_errors = nb_errors;
1098 old_tests = nb_tests;
1099 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001100 nb_internals = 0;
1101 nb_schematas = 0;
1102 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001103 "xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001104 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001105 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001106 printf("Ran %d tests (%d schemata), no errors\n",
1107 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001108 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001109 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001110 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001111 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001112 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001113 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001114 nb_leaks - old_leaks);
1115 old_errors = nb_errors;
1116 old_tests = nb_tests;
1117 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001118 nb_internals = 0;
1119 nb_schematas = 0;
1120 res = xstcMetadata(
Daniel Veillardde0e4982005-07-03 14:35:44 +00001121 "xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
1122 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001123 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001124 printf("Ran %d tests (%d schemata), no errors\n",
1125 nb_tests - old_tests, nb_schematas);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001126 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001127 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001128 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001129 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001130 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001131 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001132 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001133
1134 if ((nb_errors == 0) && (nb_leaks == 0)) {
1135 ret = 0;
1136 printf("Total %d tests, no errors\n",
1137 nb_tests);
1138 } else {
1139 ret = 1;
1140 printf("Total %d tests, %d errors, %d leaks\n",
1141 nb_tests, nb_errors, nb_leaks);
1142 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001143
1144 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001145 xmlCleanupParser();
1146 xmlMemoryDump();
1147
Daniel Veillardc9352532005-07-04 14:25:34 +00001148 if (logfile != NULL)
1149 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001150 return(ret);
1151}
Daniel Veillard95175012005-07-03 16:09:51 +00001152#else /* !SCHEMAS */
1153int
1154main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1155 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1156}
1157#endif