blob: d1dc2ca920c26443473912f1dd8ac82e2d320bd8 [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 Veillardf93a67e2005-10-28 16:37:05 +00009#ifdef HAVE_CONFIG_H
10#include "libxml.h"
11#else
12#include <stdio.h>
13#endif
14
Daniel Veillardc9352532005-07-04 14:25:34 +000015#if !defined(_WIN32) || defined(__CYGWIN__)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000016#include <unistd.h>
Daniel Veillardc9352532005-07-04 14:25:34 +000017#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000018#include <string.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000019#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000022
23#include <libxml/parser.h>
Daniel Veillarde84f2312005-07-02 07:31:28 +000024#include <libxml/parserInternals.h>
Daniel Veillardf2e066a2005-06-30 13:04:44 +000025#include <libxml/tree.h>
26#include <libxml/uri.h>
Daniel Veillard95175012005-07-03 16:09:51 +000027#if defined(LIBXML_SCHEMAS_ENABLED) && defined(LIBXML_XPATH_ENABLED)
Daniel Veillardf2e066a2005-06-30 13:04:44 +000028#include <libxml/xmlreader.h>
29
30#include <libxml/xpath.h>
31#include <libxml/xpathInternals.h>
32
33#include <libxml/relaxng.h>
34#include <libxml/xmlschemas.h>
35#include <libxml/xmlschemastypes.h>
36
Daniel Veillardc9352532005-07-04 14:25:34 +000037#define LOGFILE "runsuite.log"
Daniel Veillard24505b02005-07-28 23:49:35 +000038static FILE *logfile = NULL;
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +000039static int verbose = 0;
40
Daniel Veillard22030ef2012-05-23 15:52:45 +080041#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
42#define vsnprintf _vsnprintf
43#define snprintf _snprintf
44#endif
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +000045
Daniel Veillardf2e066a2005-06-30 13:04:44 +000046/************************************************************************
47 * *
48 * File name and path utilities *
49 * *
50 ************************************************************************/
51
52static int checkTestFile(const char *filename) {
53 struct stat buf;
54
55 if (stat(filename, &buf) == -1)
56 return(0);
57
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000058#if defined(_WIN32) && !defined(__CYGWIN__)
59 if (!(buf.st_mode & _S_IFREG))
60 return(0);
61#else
Daniel Veillardf2e066a2005-06-30 13:04:44 +000062 if (!S_ISREG(buf.st_mode))
63 return(0);
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000064#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +000065
66 return(1);
67}
Daniel Veillardcfbb0dd2005-07-04 17:12:01 +000068
Daniel Veillarde84f2312005-07-02 07:31:28 +000069static xmlChar *composeDir(const xmlChar *dir, const xmlChar *path) {
70 char buf[500];
71
72 if (dir == NULL) return(xmlStrdup(path));
73 if (path == NULL) return(NULL);
74
75 snprintf(buf, 500, "%s/%s", (const char *) dir, (const char *) path);
76 return(xmlStrdup((const xmlChar *) buf));
77}
Daniel Veillardf2e066a2005-06-30 13:04:44 +000078
79/************************************************************************
80 * *
81 * Libxml2 specific routines *
82 * *
83 ************************************************************************/
84
85static int nb_tests = 0;
86static int nb_errors = 0;
Daniel Veillardc9352532005-07-04 14:25:34 +000087static int nb_internals = 0;
88static int nb_schematas = 0;
Daniel Veillard90837782005-07-04 15:45:10 +000089static int nb_unimplemented = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000090static int nb_leaks = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +000091static int extraMemoryFromResolver = 0;
92
93static int
94fatalError(void) {
95 fprintf(stderr, "Exitting tests on fatal error\n");
96 exit(1);
97}
98
99/*
Daniel Veillarde84f2312005-07-02 07:31:28 +0000100 * that's needed to implement <resource>
101 */
102#define MAX_ENTITIES 20
Daniel Veillard24505b02005-07-28 23:49:35 +0000103static char *testEntitiesName[MAX_ENTITIES];
104static char *testEntitiesValue[MAX_ENTITIES];
105static int nb_entities = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000106static void resetEntities(void) {
107 int i;
108
109 for (i = 0;i < nb_entities;i++) {
110 if (testEntitiesName[i] != NULL)
111 xmlFree(testEntitiesName[i]);
112 if (testEntitiesValue[i] != NULL)
113 xmlFree(testEntitiesValue[i]);
114 }
115 nb_entities = 0;
116}
117static int addEntity(char *name, char *content) {
118 if (nb_entities >= MAX_ENTITIES) {
119 fprintf(stderr, "Too many entities defined\n");
120 return(-1);
121 }
122 testEntitiesName[nb_entities] = name;
123 testEntitiesValue[nb_entities] = content;
124 nb_entities++;
125 return(0);
126}
127
128/*
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000129 * We need to trap calls to the resolver to not account memory for the catalog
130 * which is shared to the current running test. We also don't want to have
131 * network downloads modifying tests.
132 */
133static xmlParserInputPtr
134testExternalEntityLoader(const char *URL, const char *ID,
135 xmlParserCtxtPtr ctxt) {
136 xmlParserInputPtr ret;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000137 int i;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000138
Daniel Veillarde84f2312005-07-02 07:31:28 +0000139 for (i = 0;i < nb_entities;i++) {
140 if (!strcmp(testEntitiesName[i], URL)) {
141 ret = xmlNewStringInputStream(ctxt,
142 (const xmlChar *) testEntitiesValue[i]);
143 if (ret != NULL) {
144 ret->filename = (const char *)
145 xmlStrdup((xmlChar *)testEntitiesName[i]);
146 }
147 return(ret);
148 }
149 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000150 if (checkTestFile(URL)) {
151 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
152 } else {
153 int memused = xmlMemUsed();
154 ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
155 extraMemoryFromResolver += xmlMemUsed() - memused;
156 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000157#if 0
Daniel Veillarde84f2312005-07-02 07:31:28 +0000158 if (ret == NULL) {
159 fprintf(stderr, "Failed to find resource %s\n", URL);
160 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000161#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000162
163 return(ret);
164}
165
166/*
167 * Trapping the error messages at the generic level to grab the equivalent of
168 * stderr messages on CLI tools.
169 */
170static char testErrors[32769];
171static int testErrorsSize = 0;
172
Daniel Veillardc9352532005-07-04 14:25:34 +0000173static void test_log(const char *msg, ...) {
174 va_list args;
175 if (logfile != NULL) {
176 fprintf(logfile, "\n------------\n");
177 va_start(args, msg);
178 vfprintf(logfile, msg, args);
179 va_end(args);
180 fprintf(logfile, "%s", testErrors);
181 testErrorsSize = 0; testErrors[0] = 0;
182 }
183 if (verbose) {
184 va_start(args, msg);
185 vfprintf(stderr, msg, args);
186 va_end(args);
187 }
188}
189
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000190static void
191testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
192 va_list args;
193 int res;
194
195 if (testErrorsSize >= 32768)
196 return;
197 va_start(args, msg);
198 res = vsnprintf(&testErrors[testErrorsSize],
199 32768 - testErrorsSize,
200 msg, args);
201 va_end(args);
202 if (testErrorsSize + res >= 32768) {
203 /* buffer is full */
204 testErrorsSize = 32768;
205 testErrors[testErrorsSize] = 0;
206 } else {
207 testErrorsSize += res;
208 }
209 testErrors[testErrorsSize] = 0;
210}
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000211
Daniel Veillard24505b02005-07-28 23:49:35 +0000212static xmlXPathContextPtr ctxtXPath;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000213
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000214static void
215initializeLibxml2(void) {
216 xmlGetWarningsDefaultValue = 0;
217 xmlPedanticParserDefault(0);
218
219 xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
220 xmlInitParser();
221 xmlSetExternalEntityLoader(testExternalEntityLoader);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000222 ctxtXPath = xmlXPathNewContext(NULL);
Kasimier T. Buchcika7248442006-05-29 16:15:36 +0000223 /*
224 * Deactivate the cache if created; otherwise we have to create/free it
225 * for every test, since it will confuse the memory leak detection.
226 * Note that normally this need not be done, since the cache is not
Kasimier T. Buchcik58694692006-05-31 12:37:28 +0000227 * created until set explicitely with xmlXPathContextSetCache();
Kasimier T. Buchcika7248442006-05-29 16:15:36 +0000228 * but for test purposes it is sometimes usefull to activate the
229 * cache by default for the whole library.
230 */
Kasimier T. Buchcik58694692006-05-31 12:37:28 +0000231 if (ctxtXPath->cache != NULL)
232 xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000233 /* used as default nanemspace in xstc tests */
234 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
235 xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
236 BAD_CAST "http://www.w3.org/1999/xlink");
237 xmlSetGenericErrorFunc(NULL, testErrorHandler);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000238#ifdef LIBXML_SCHEMAS_ENABLED
239 xmlSchemaInitTypes();
240 xmlRelaxNGInitTypes();
241#endif
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000242}
243
244static xmlNodePtr
245getNext(xmlNodePtr cur, const char *xpath) {
246 xmlNodePtr ret = NULL;
247 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000248 xmlXPathCompExprPtr comp;
249
250 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
251 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000252 ctxtXPath->doc = cur->doc;
253 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000254 comp = xmlXPathCompile(BAD_CAST xpath);
255 if (comp == NULL) {
256 fprintf(stderr, "Failed to compile %s\n", xpath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000257 return(NULL);
258 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000259 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000260 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000261 if (res == NULL)
262 return(NULL);
263 if ((res->type == XPATH_NODESET) &&
264 (res->nodesetval != NULL) &&
265 (res->nodesetval->nodeNr > 0) &&
266 (res->nodesetval->nodeTab != NULL))
267 ret = res->nodesetval->nodeTab[0];
268 xmlXPathFreeObject(res);
269 return(ret);
270}
271
272static xmlChar *
273getString(xmlNodePtr cur, const char *xpath) {
274 xmlChar *ret = NULL;
275 xmlXPathObjectPtr res;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000276 xmlXPathCompExprPtr comp;
277
278 if ((cur == NULL) || (cur->doc == NULL) || (xpath == NULL))
279 return(NULL);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000280 ctxtXPath->doc = cur->doc;
281 ctxtXPath->node = cur;
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000282 comp = xmlXPathCompile(BAD_CAST xpath);
283 if (comp == NULL) {
284 fprintf(stderr, "Failed to compile %s\n", xpath);
285 return(NULL);
286 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000287 res = xmlXPathCompiledEval(comp, ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000288 xmlXPathFreeCompExpr(comp);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000289 if (res == NULL)
290 return(NULL);
291 if (res->type == XPATH_STRING) {
292 ret = res->stringval;
293 res->stringval = NULL;
294 }
295 xmlXPathFreeObject(res);
296 return(ret);
297}
298
299/************************************************************************
300 * *
301 * Test test/xsdtest/xsdtestsuite.xml *
302 * *
303 ************************************************************************/
304
Daniel Veillard76d36452009-09-07 11:19:33 +0200305static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000306xsdIncorectTestCase(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000307 xmlNodePtr test;
308 xmlBufferPtr buf;
309 xmlRelaxNGParserCtxtPtr pctxt;
310 xmlRelaxNGPtr rng = NULL;
311 int ret = 0, memt;
312
313 cur = getNext(cur, "./incorrect[1]");
314 if (cur == NULL) {
315 return(0);
316 }
Daniel Veillard76d36452009-09-07 11:19:33 +0200317
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000318 test = getNext(cur, "./*");
319 if (test == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000320 test_log("Failed to find test in correct line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000321 xmlGetLineNo(cur));
322 return(1);
323 }
324
325 memt = xmlMemUsed();
326 extraMemoryFromResolver = 0;
327 /*
328 * dump the schemas to a buffer, then reparse it and compile the schemas
329 */
330 buf = xmlBufferCreate();
331 if (buf == NULL) {
332 fprintf(stderr, "out of memory !\n");
333 fatalError();
334 }
335 xmlNodeDump(buf, test->doc, test, 0, 0);
336 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
337 xmlRelaxNGSetParserErrors(pctxt,
338 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
339 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
340 pctxt);
341 rng = xmlRelaxNGParse(pctxt);
342 xmlRelaxNGFreeParserCtxt(pctxt);
343 if (rng != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000344 test_log("Failed to detect incorect RNG line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000345 xmlGetLineNo(test));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000346 ret = 1;
347 goto done;
348 }
349
350done:
351 if (buf != NULL)
352 xmlBufferFree(buf);
353 if (rng != NULL)
354 xmlRelaxNGFree(rng);
355 xmlResetLastError();
Daniel Veillardae0765b2008-07-31 19:54:59 +0000356 if ((memt < xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000357 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000358 xmlGetLineNo(cur), xmlMemUsed() - memt);
359 nb_leaks++;
360 }
361 return(ret);
362}
363
Daniel Veillarde84f2312005-07-02 07:31:28 +0000364static void
365installResources(xmlNodePtr tst, const xmlChar *base) {
366 xmlNodePtr test;
367 xmlBufferPtr buf;
368 xmlChar *name, *content, *res;
Daniel Veillardc9352532005-07-04 14:25:34 +0000369
Daniel Veillarde84f2312005-07-02 07:31:28 +0000370 buf = xmlBufferCreate();
371 if (buf == NULL) {
372 fprintf(stderr, "out of memory !\n");
373 fatalError();
374 }
375 xmlNodeDump(buf, tst->doc, tst, 0, 0);
376
377 while (tst != NULL) {
378 test = getNext(tst, "./*");
379 if (test != NULL) {
380 xmlBufferEmpty(buf);
381 xmlNodeDump(buf, test->doc, test, 0, 0);
382 name = getString(tst, "string(@name)");
383 content = xmlStrdup(buf->content);
384 if ((name != NULL) && (content != NULL)) {
385 res = composeDir(base, name);
386 xmlFree(name);
387 addEntity((char *) res, (char *) content);
388 } else {
389 if (name != NULL) xmlFree(name);
390 if (content != NULL) xmlFree(content);
391 }
392 }
393 tst = getNext(tst, "following-sibling::resource[1]");
394 }
395 if (buf != NULL)
396 xmlBufferFree(buf);
397}
398
399static void
400installDirs(xmlNodePtr tst, const xmlChar *base) {
401 xmlNodePtr test;
402 xmlChar *name, *res;
403
404 name = getString(tst, "string(@name)");
405 if (name == NULL)
406 return;
407 res = composeDir(base, name);
408 xmlFree(name);
409 if (res == NULL) {
410 return;
411 }
412 /* Now process resources and subdir recursively */
413 test = getNext(tst, "./resource[1]");
414 if (test != NULL) {
415 installResources(test, res);
416 }
417 test = getNext(tst, "./dir[1]");
418 while (test != NULL) {
419 installDirs(test, res);
420 test = getNext(test, "following-sibling::dir[1]");
421 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000422 xmlFree(res);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000423}
424
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000425static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000426xsdTestCase(xmlNodePtr tst) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000427 xmlNodePtr test, tmp, cur;
428 xmlBufferPtr buf;
429 xmlDocPtr doc = NULL;
430 xmlRelaxNGParserCtxtPtr pctxt;
431 xmlRelaxNGValidCtxtPtr ctxt;
432 xmlRelaxNGPtr rng = NULL;
433 int ret = 0, mem, memt;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000434 xmlChar *dtd;
435
436 resetEntities();
Daniel Veillardc9352532005-07-04 14:25:34 +0000437 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillarde84f2312005-07-02 07:31:28 +0000438
439 tmp = getNext(tst, "./dir[1]");
440 if (tmp != NULL) {
441 installDirs(tmp, NULL);
442 }
443 tmp = getNext(tst, "./resource[1]");
444 if (tmp != NULL) {
445 installResources(tmp, NULL);
446 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000447
448 cur = getNext(tst, "./correct[1]");
449 if (cur == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000450 return(xsdIncorectTestCase(tst));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000451 }
452
453 test = getNext(cur, "./*");
454 if (test == NULL) {
455 fprintf(stderr, "Failed to find test in correct line %ld\n",
456 xmlGetLineNo(cur));
457 return(1);
458 }
459
460 memt = xmlMemUsed();
461 extraMemoryFromResolver = 0;
462 /*
463 * dump the schemas to a buffer, then reparse it and compile the schemas
464 */
465 buf = xmlBufferCreate();
466 if (buf == NULL) {
467 fprintf(stderr, "out of memory !\n");
468 fatalError();
469 }
470 xmlNodeDump(buf, test->doc, test, 0, 0);
471 pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
472 xmlRelaxNGSetParserErrors(pctxt,
473 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
474 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
475 pctxt);
476 rng = xmlRelaxNGParse(pctxt);
477 xmlRelaxNGFreeParserCtxt(pctxt);
478 if (extraMemoryFromResolver)
479 memt = 0;
480
481 if (rng == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000482 test_log("Failed to parse RNGtest line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000483 xmlGetLineNo(test));
484 nb_errors++;
485 ret = 1;
486 goto done;
487 }
488 /*
489 * now scan all the siblings of correct to process the <valid> tests
490 */
491 tmp = getNext(cur, "following-sibling::valid[1]");
492 while (tmp != NULL) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000493 dtd = xmlGetProp(tmp, BAD_CAST "dtd");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000494 test = getNext(tmp, "./*");
495 if (test == NULL) {
496 fprintf(stderr, "Failed to find test in <valid> line %ld\n",
497 xmlGetLineNo(tmp));
498
499 } else {
500 xmlBufferEmpty(buf);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000501 if (dtd != NULL)
502 xmlBufferAdd(buf, dtd, -1);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000503 xmlNodeDump(buf, test->doc, test, 0, 0);
504
505 /*
506 * We are ready to run the test
507 */
508 mem = xmlMemUsed();
509 extraMemoryFromResolver = 0;
510 doc = xmlReadMemory((const char *)buf->content, buf->use,
511 "test", NULL, 0);
512 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000513 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000514 xmlGetLineNo(tmp));
515 nb_errors++;
516 } else {
517 nb_tests++;
518 ctxt = xmlRelaxNGNewValidCtxt(rng);
519 xmlRelaxNGSetValidErrors(ctxt,
520 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
521 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
522 ctxt);
523 ret = xmlRelaxNGValidateDoc(ctxt, doc);
524 xmlRelaxNGFreeValidCtxt(ctxt);
525 if (ret > 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000526 test_log("Failed to validate valid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000527 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000528 nb_errors++;
529 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000530 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000531 xmlGetLineNo(tmp));
532 nb_errors++;
533 }
534 xmlFreeDoc(doc);
535 }
536 xmlResetLastError();
537 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000538 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000539 xmlGetLineNo(tmp), xmlMemUsed() - mem);
540 xmlMemoryDump();
541 nb_leaks++;
542 }
543 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000544 if (dtd != NULL)
545 xmlFree(dtd);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000546 tmp = getNext(tmp, "following-sibling::valid[1]");
547 }
548 /*
549 * now scan all the siblings of correct to process the <invalid> tests
550 */
551 tmp = getNext(cur, "following-sibling::invalid[1]");
552 while (tmp != NULL) {
553 test = getNext(tmp, "./*");
554 if (test == NULL) {
555 fprintf(stderr, "Failed to find test in <invalid> line %ld\n",
556 xmlGetLineNo(tmp));
557
558 } else {
559 xmlBufferEmpty(buf);
560 xmlNodeDump(buf, test->doc, test, 0, 0);
561
562 /*
563 * We are ready to run the test
564 */
565 mem = xmlMemUsed();
566 extraMemoryFromResolver = 0;
567 doc = xmlReadMemory((const char *)buf->content, buf->use,
568 "test", NULL, 0);
569 if (doc == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000570 test_log("Failed to parse valid instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000571 xmlGetLineNo(tmp));
572 nb_errors++;
573 } else {
574 nb_tests++;
575 ctxt = xmlRelaxNGNewValidCtxt(rng);
576 xmlRelaxNGSetValidErrors(ctxt,
577 (xmlRelaxNGValidityErrorFunc) testErrorHandler,
578 (xmlRelaxNGValidityWarningFunc) testErrorHandler,
579 ctxt);
580 ret = xmlRelaxNGValidateDoc(ctxt, doc);
581 xmlRelaxNGFreeValidCtxt(ctxt);
582 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000583 test_log("Failed to detect invalid instance line %ld\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000584 xmlGetLineNo(tmp));
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000585 nb_errors++;
586 } else if (ret < 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000587 test_log("Internal error validating instance line %ld\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000588 xmlGetLineNo(tmp));
589 nb_errors++;
590 }
591 xmlFreeDoc(doc);
592 }
593 xmlResetLastError();
594 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000595 test_log("Validation of instance line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000596 xmlGetLineNo(tmp), xmlMemUsed() - mem);
597 xmlMemoryDump();
598 nb_leaks++;
599 }
600 }
601 tmp = getNext(tmp, "following-sibling::invalid[1]");
602 }
603
604done:
605 if (buf != NULL)
606 xmlBufferFree(buf);
607 if (rng != NULL)
608 xmlRelaxNGFree(rng);
609 xmlResetLastError();
610 if ((memt != xmlMemUsed()) && (memt != 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000611 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000612 xmlGetLineNo(cur), xmlMemUsed() - memt);
613 nb_leaks++;
614 }
615 return(ret);
616}
617
618static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000619xsdTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000620 if (verbose) {
621 xmlChar *doc = getString(cur, "string(documentation)");
622
623 if (doc != NULL) {
624 printf("Suite %s\n", doc);
625 xmlFree(doc);
626 }
627 }
628 cur = getNext(cur, "./testCase[1]");
629 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000630 xsdTestCase(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000631 cur = getNext(cur, "following-sibling::testCase[1]");
632 }
633
634 return(0);
635}
636
637static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000638xsdTest(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000639 xmlDocPtr doc;
640 xmlNodePtr cur;
641 const char *filename = "test/xsdtest/xsdtestsuite.xml";
642 int ret = 0;
643
644 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
645 if (doc == NULL) {
646 fprintf(stderr, "Failed to parse %s\n", filename);
647 return(-1);
648 }
649 printf("## XML Schemas datatypes test suite from James Clark\n");
650
651 cur = xmlDocGetRootElement(doc);
652 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
653 fprintf(stderr, "Unexpected format %s\n", filename);
654 ret = -1;
655 goto done;
656 }
657
658 cur = getNext(cur, "./testSuite[1]");
659 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
660 fprintf(stderr, "Unexpected format %s\n", filename);
661 ret = -1;
662 goto done;
663 }
664 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000665 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000666 cur = getNext(cur, "following-sibling::testSuite[1]");
667 }
668
669done:
670 if (doc != NULL)
671 xmlFreeDoc(doc);
672 return(ret);
673}
674
675static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000676rngTestSuite(xmlNodePtr cur) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000677 if (verbose) {
678 xmlChar *doc = getString(cur, "string(documentation)");
679
680 if (doc != NULL) {
681 printf("Suite %s\n", doc);
682 xmlFree(doc);
683 } else {
684 doc = getString(cur, "string(section)");
685 if (doc != NULL) {
686 printf("Section %s\n", doc);
687 xmlFree(doc);
688 }
689 }
690 }
691 cur = getNext(cur, "./testSuite[1]");
692 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000693 xsdTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000694 cur = getNext(cur, "following-sibling::testSuite[1]");
695 }
696
697 return(0);
698}
699
700static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000701rngTest1(void) {
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000702 xmlDocPtr doc;
703 xmlNodePtr cur;
704 const char *filename = "test/relaxng/OASIS/spectest.xml";
705 int ret = 0;
706
707 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
708 if (doc == NULL) {
709 fprintf(stderr, "Failed to parse %s\n", filename);
710 return(-1);
711 }
Daniel Veillarde84f2312005-07-02 07:31:28 +0000712 printf("## Relax NG test suite from James Clark\n");
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000713
714 cur = xmlDocGetRootElement(doc);
715 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
716 fprintf(stderr, "Unexpected format %s\n", filename);
717 ret = -1;
718 goto done;
719 }
720
721 cur = getNext(cur, "./testSuite[1]");
722 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
723 fprintf(stderr, "Unexpected format %s\n", filename);
724 ret = -1;
725 goto done;
726 }
727 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000728 rngTestSuite(cur);
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000729 cur = getNext(cur, "following-sibling::testSuite[1]");
730 }
731
732done:
733 if (doc != NULL)
734 xmlFreeDoc(doc);
735 return(ret);
736}
737
Daniel Veillarde84f2312005-07-02 07:31:28 +0000738static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000739rngTest2(void) {
Daniel Veillarde84f2312005-07-02 07:31:28 +0000740 xmlDocPtr doc;
741 xmlNodePtr cur;
742 const char *filename = "test/relaxng/testsuite.xml";
743 int ret = 0;
744
745 doc = xmlReadFile(filename, NULL, XML_PARSE_NOENT);
746 if (doc == NULL) {
747 fprintf(stderr, "Failed to parse %s\n", filename);
748 return(-1);
749 }
750 printf("## Relax NG test suite for libxml2\n");
751
752 cur = xmlDocGetRootElement(doc);
753 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
754 fprintf(stderr, "Unexpected format %s\n", filename);
755 ret = -1;
756 goto done;
757 }
758
759 cur = getNext(cur, "./testSuite[1]");
760 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSuite"))) {
761 fprintf(stderr, "Unexpected format %s\n", filename);
762 ret = -1;
763 goto done;
764 }
765 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000766 xsdTestSuite(cur);
Daniel Veillarde84f2312005-07-02 07:31:28 +0000767 cur = getNext(cur, "following-sibling::testSuite[1]");
768 }
769
770done:
771 if (doc != NULL)
772 xmlFreeDoc(doc);
773 return(ret);
774}
775
Daniel Veillardf2e066a2005-06-30 13:04:44 +0000776/************************************************************************
777 * *
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000778 * Schemas test suites from W3C/NIST/MS/Sun *
779 * *
780 ************************************************************************/
781
782static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000783xstcTestInstance(xmlNodePtr cur, xmlSchemaPtr schemas,
Daniel Veillard6b6d6802005-07-03 21:00:34 +0000784 const xmlChar *spath, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000785 xmlChar *href = NULL;
786 xmlChar *path = NULL;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000787 xmlChar *validity = NULL;
788 xmlSchemaValidCtxtPtr ctxt = NULL;
789 xmlDocPtr doc = NULL;
790 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000791
Daniel Veillardde0e4982005-07-03 14:35:44 +0000792 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000793 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000794 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000795 href = getString(cur,
Daniel Veillardde0e4982005-07-03 14:35:44 +0000796 "string(ts:instanceDocument/@xlink:href)");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000797 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000798 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000799 xmlGetLineNo(cur));
800 ret = -1;
801 goto done;
802 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000803 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000804 if (path == NULL) {
805 fprintf(stderr,
806 "Failed to build path to schemas testGroup line %ld : %s\n",
807 xmlGetLineNo(cur), href);
808 ret = -1;
809 goto done;
810 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000811 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000812 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000813 xmlGetLineNo(cur), path);
814 ret = -1;
815 goto done;
816 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000817 validity = getString(cur,
818 "string(ts:expected/@validity)");
819 if (validity == NULL) {
820 fprintf(stderr, "instanceDocument line %ld misses expected validity\n",
821 xmlGetLineNo(cur));
822 ret = -1;
823 goto done;
824 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000825 nb_tests++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000826 doc = xmlReadFile((const char *) path, NULL, XML_PARSE_NOENT);
827 if (doc == NULL) {
828 fprintf(stderr, "instance %s fails to parse\n", path);
829 ret = -1;
830 nb_errors++;
831 goto done;
832 }
833
834 ctxt = xmlSchemaNewValidCtxt(schemas);
835 xmlSchemaSetValidErrors(ctxt,
836 (xmlSchemaValidityErrorFunc) testErrorHandler,
837 (xmlSchemaValidityWarningFunc) testErrorHandler,
838 ctxt);
839 ret = xmlSchemaValidateDoc(ctxt, doc);
840
841 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000842 if (ret > 0) {
843 test_log("valid instance %s failed to validate against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000844 path, spath);
845 nb_errors++;
Daniel Veillardc9352532005-07-04 14:25:34 +0000846 } else if (ret < 0) {
847 test_log("valid instance %s got internal error validating %s\n",
848 path, spath);
849 nb_internals++;
850 nb_errors++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000851 }
852 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
853 if (ret == 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000854 test_log("Failed to detect invalid instance %s against %s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000855 path, spath);
856 nb_errors++;
857 }
858 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000859 test_log("instanceDocument line %ld has unexpected validity value%s\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000860 xmlGetLineNo(cur), validity);
861 ret = -1;
862 goto done;
863 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000864
865done:
866 if (href != NULL) xmlFree(href);
867 if (path != NULL) xmlFree(path);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000868 if (validity != NULL) xmlFree(validity);
869 if (ctxt != NULL) xmlSchemaFreeValidCtxt(ctxt);
870 if (doc != NULL) xmlFreeDoc(doc);
871 xmlResetLastError();
872 if (mem != xmlMemUsed()) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000873 test_log("Validation of tests starting line %ld leaked %d\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +0000874 xmlGetLineNo(cur), xmlMemUsed() - mem);
875 nb_leaks++;
876 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000877 return(ret);
878}
Daniel Veillardde0e4982005-07-03 14:35:44 +0000879
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000880static int
Daniel Veillardc9352532005-07-04 14:25:34 +0000881xstcTestGroup(xmlNodePtr cur, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000882 xmlChar *href = NULL;
883 xmlChar *path = NULL;
884 xmlChar *validity = NULL;
885 xmlSchemaPtr schemas = NULL;
886 xmlSchemaParserCtxtPtr ctxt;
887 xmlNodePtr instance;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000888 int ret = 0, mem;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000889
Daniel Veillardde0e4982005-07-03 14:35:44 +0000890 xmlResetLastError();
Daniel Veillardc9352532005-07-04 14:25:34 +0000891 testErrorsSize = 0; testErrors[0] = 0;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000892 mem = xmlMemUsed();
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000893 href = getString(cur,
894 "string(ts:schemaTest/ts:schemaDocument/@xlink:href)");
895 if ((href == NULL) || (href[0] == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000896 test_log("testGroup line %ld misses href for schemaDocument\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000897 xmlGetLineNo(cur));
898 ret = -1;
899 goto done;
900 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000901 path = xmlBuildURI(href, BAD_CAST base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000902 if (path == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000903 test_log("Failed to build path to schemas testGroup line %ld : %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000904 xmlGetLineNo(cur), href);
905 ret = -1;
906 goto done;
907 }
Daniel Veillardde0e4982005-07-03 14:35:44 +0000908 if (checkTestFile((const char *) path) <= 0) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000909 test_log("schemas for testGroup line %ld is missing: %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000910 xmlGetLineNo(cur), path);
911 ret = -1;
912 goto done;
913 }
914 validity = getString(cur,
915 "string(ts:schemaTest/ts:expected/@validity)");
916 if (validity == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000917 test_log("testGroup line %ld misses expected validity\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000918 xmlGetLineNo(cur));
919 ret = -1;
920 goto done;
921 }
Daniel Veillardc9352532005-07-04 14:25:34 +0000922 nb_tests++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000923 if (xmlStrEqual(validity, BAD_CAST "valid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000924 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000925 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000926 xmlSchemaSetParserErrors(ctxt,
927 (xmlSchemaValidityErrorFunc) testErrorHandler,
928 (xmlSchemaValidityWarningFunc) testErrorHandler,
929 ctxt);
930 schemas = xmlSchemaParse(ctxt);
931 xmlSchemaFreeParserCtxt(ctxt);
932 if (schemas == NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000933 test_log("valid schemas %s failed to parse\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000934 path);
Daniel Veillard90837782005-07-04 15:45:10 +0000935 ret = 1;
936 nb_errors++;
937 }
938 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
939 test_log("valid schemas %s hit an unimplemented block\n",
940 path);
941 ret = 1;
942 nb_unimplemented++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000943 nb_errors++;
944 }
945 instance = getNext(cur, "./ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000946 while (instance != NULL) {
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000947 if (schemas != NULL) {
948 xstcTestInstance(instance, schemas, path, base);
949 } else {
950 /*
951 * We'll automatically mark the instances as failed
952 * if the schema was broken.
953 */
954 nb_errors++;
955 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000956 instance = getNext(instance,
Kasimier T. Buchcikdcac4fc2005-12-09 10:03:27 +0000957 "following-sibling::ts:instanceTest[1]");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000958 }
959 } else if (xmlStrEqual(validity, BAD_CAST "invalid")) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000960 nb_schematas++;
Daniel Veillardde0e4982005-07-03 14:35:44 +0000961 ctxt = xmlSchemaNewParserCtxt((const char *) path);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000962 xmlSchemaSetParserErrors(ctxt,
963 (xmlSchemaValidityErrorFunc) testErrorHandler,
964 (xmlSchemaValidityWarningFunc) testErrorHandler,
965 ctxt);
966 schemas = xmlSchemaParse(ctxt);
967 xmlSchemaFreeParserCtxt(ctxt);
Daniel Veillard4ac5f9a2005-07-04 15:20:27 +0000968 if (schemas != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000969 test_log("Failed to detect error in schemas %s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000970 path);
971 nb_errors++;
Daniel Veillard90837782005-07-04 15:45:10 +0000972 ret = 1;
973 }
974 if ((ret == 0) && (strstr(testErrors, "nimplemented") != NULL)) {
975 nb_unimplemented++;
976 test_log("invalid schemas %s hit an unimplemented block\n",
977 path);
978 ret = 1;
979 nb_errors++;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000980 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000981 } else {
Daniel Veillardc9352532005-07-04 14:25:34 +0000982 test_log("testGroup line %ld misses unexpected validity value%s\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000983 xmlGetLineNo(cur), validity);
984 ret = -1;
985 goto done;
986 }
987
988done:
989 if (href != NULL) xmlFree(href);
990 if (path != NULL) xmlFree(path);
991 if (validity != NULL) xmlFree(validity);
992 if (schemas != NULL) xmlSchemaFree(schemas);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000993 xmlResetLastError();
994 if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
Daniel Veillardc9352532005-07-04 14:25:34 +0000995 test_log("Processing test line %ld %s leaked %d\n",
996 xmlGetLineNo(cur), path, xmlMemUsed() - mem);
Daniel Veillardde0e4982005-07-03 14:35:44 +0000997 nb_leaks++;
998 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +0000999 return(ret);
1000}
1001
1002static int
Daniel Veillardc9352532005-07-04 14:25:34 +00001003xstcMetadata(const char *metadata, const char *base) {
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001004 xmlDocPtr doc;
1005 xmlNodePtr cur;
1006 xmlChar *contributor;
1007 xmlChar *name;
Daniel Veillard6b6d6802005-07-03 21:00:34 +00001008 int ret = 0;
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001009
1010 doc = xmlReadFile(metadata, NULL, XML_PARSE_NOENT);
1011 if (doc == NULL) {
1012 fprintf(stderr, "Failed to parse %s\n", metadata);
1013 return(-1);
1014 }
1015
1016 cur = xmlDocGetRootElement(doc);
1017 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testSet"))) {
1018 fprintf(stderr, "Unexpected format %s\n", metadata);
1019 return(-1);
1020 }
1021 contributor = xmlGetProp(cur, BAD_CAST "contributor");
1022 if (contributor == NULL) {
1023 contributor = xmlStrdup(BAD_CAST "Unknown");
1024 }
1025 name = xmlGetProp(cur, BAD_CAST "name");
1026 if (name == NULL) {
1027 name = xmlStrdup(BAD_CAST "Unknown");
1028 }
1029 printf("## %s test suite for Schemas version %s\n", contributor, name);
1030 xmlFree(contributor);
1031 xmlFree(name);
1032
1033 cur = getNext(cur, "./ts:testGroup[1]");
1034 if ((cur == NULL) || (!xmlStrEqual(cur->name, BAD_CAST "testGroup"))) {
1035 fprintf(stderr, "Unexpected format %s\n", metadata);
1036 ret = -1;
1037 goto done;
1038 }
1039 while (cur != NULL) {
Daniel Veillardc9352532005-07-04 14:25:34 +00001040 xstcTestGroup(cur, base);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001041 cur = getNext(cur, "following-sibling::ts:testGroup[1]");
1042 }
1043
1044done:
1045 xmlFreeDoc(doc);
1046 return(ret);
1047}
1048
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001049/************************************************************************
1050 * *
1051 * The driver for the tests *
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001052 * *
1053 ************************************************************************/
1054
1055int
1056main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001057 int ret = 0;
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001058 int old_errors, old_tests, old_leaks;
1059
Daniel Veillardc9352532005-07-04 14:25:34 +00001060 logfile = fopen(LOGFILE, "w");
1061 if (logfile == NULL) {
1062 fprintf(stderr,
1063 "Could not open the log file, running in verbose mode\n");
1064 verbose = 1;
1065 }
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001066 initializeLibxml2();
1067
1068 if ((argc >= 2) && (!strcmp(argv[1], "-v")))
1069 verbose = 1;
1070
1071
Daniel Veillarde84f2312005-07-02 07:31:28 +00001072 old_errors = nb_errors;
1073 old_tests = nb_tests;
1074 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001075 xsdTest();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001076 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1077 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1078 else
1079 printf("Ran %d tests, %d errors, %d leaks\n",
1080 nb_tests - old_tests,
1081 nb_errors - old_errors,
1082 nb_leaks - old_leaks);
1083 old_errors = nb_errors;
1084 old_tests = nb_tests;
1085 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001086 rngTest1();
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001087 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1088 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1089 else
1090 printf("Ran %d tests, %d errors, %d leaks\n",
1091 nb_tests - old_tests,
1092 nb_errors - old_errors,
1093 nb_leaks - old_leaks);
1094 old_errors = nb_errors;
1095 old_tests = nb_tests;
1096 old_leaks = nb_leaks;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001097 rngTest2();
Daniel Veillarde84f2312005-07-02 07:31:28 +00001098 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
1099 printf("Ran %d tests, no errors\n", nb_tests - old_tests);
1100 else
1101 printf("Ran %d tests, %d errors, %d leaks\n",
1102 nb_tests - old_tests,
1103 nb_errors - old_errors,
1104 nb_leaks - old_leaks);
1105 old_errors = nb_errors;
1106 old_tests = nb_tests;
1107 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001108 nb_internals = 0;
1109 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001110 xstcMetadata("xstc/Tests/Metadata/NISTXMLSchemaDatatypes.testSet",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001111 "xstc/Tests/Metadata/");
1112 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001113 printf("Ran %d tests (%d schemata), no errors\n",
1114 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001115 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001116 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001117 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001118 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001119 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001120 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001121 nb_leaks - old_leaks);
1122 old_errors = nb_errors;
1123 old_tests = nb_tests;
1124 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001125 nb_internals = 0;
1126 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001127 xstcMetadata("xstc/Tests/Metadata/SunXMLSchema1-0-20020116.testSet",
Daniel Veillardc9352532005-07-04 14:25:34 +00001128 "xstc/Tests/");
Daniel Veillardde0e4982005-07-03 14:35:44 +00001129 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001130 printf("Ran %d tests (%d schemata), no errors\n",
1131 nb_tests - old_tests, nb_schematas);
Daniel Veillardde0e4982005-07-03 14:35:44 +00001132 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001133 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001134 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001135 nb_schematas,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001136 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001137 nb_internals,
Daniel Veillardde0e4982005-07-03 14:35:44 +00001138 nb_leaks - old_leaks);
1139 old_errors = nb_errors;
1140 old_tests = nb_tests;
1141 old_leaks = nb_leaks;
Daniel Veillardc9352532005-07-04 14:25:34 +00001142 nb_internals = 0;
1143 nb_schematas = 0;
Daniel Veillard6a0baa02005-12-10 11:11:12 +00001144 xstcMetadata("xstc/Tests/Metadata/MSXMLSchema1-0-20020116.testSet",
Daniel Veillardde0e4982005-07-03 14:35:44 +00001145 "xstc/Tests/");
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001146 if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
Daniel Veillardc9352532005-07-04 14:25:34 +00001147 printf("Ran %d tests (%d schemata), no errors\n",
1148 nb_tests - old_tests, nb_schematas);
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001149 else
Daniel Veillardc9352532005-07-04 14:25:34 +00001150 printf("Ran %d tests (%d schemata), %d errors (%d internals), %d leaks\n",
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001151 nb_tests - old_tests,
Daniel Veillardc9352532005-07-04 14:25:34 +00001152 nb_schematas,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001153 nb_errors - old_errors,
Daniel Veillardc9352532005-07-04 14:25:34 +00001154 nb_internals,
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001155 nb_leaks - old_leaks);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001156
1157 if ((nb_errors == 0) && (nb_leaks == 0)) {
1158 ret = 0;
1159 printf("Total %d tests, no errors\n",
1160 nb_tests);
1161 } else {
1162 ret = 1;
1163 printf("Total %d tests, %d errors, %d leaks\n",
1164 nb_tests, nb_errors, nb_leaks);
1165 }
Daniel Veillard3fe1e8a2005-07-02 21:39:06 +00001166 xmlXPathFreeContext(ctxtXPath);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001167 xmlCleanupParser();
1168 xmlMemoryDump();
1169
Daniel Veillardc9352532005-07-04 14:25:34 +00001170 if (logfile != NULL)
1171 fclose(logfile);
Daniel Veillardf2e066a2005-06-30 13:04:44 +00001172 return(ret);
1173}
Daniel Veillard95175012005-07-03 16:09:51 +00001174#else /* !SCHEMAS */
1175int
1176main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
1177 fprintf(stderr, "runsuite requires support for schemas and xpath in libxml2\n");
1178}
1179#endif