2 * @file sipe-xml-tests.c
6 * Copyright (C) 2010-2016 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* Tests for sipe-xml.c */
33 #include "sip-transport.h"
34 #include "sipe-common.h"
35 #include "sipe-backend.h"
36 #include "sipe-digest.h"
38 #include "sipe-utils.h"
41 /* stub functions for backend API */
42 void sipe_backend_debug_literal(sipe_debug_level level
,
45 printf("DEBUG %d: %s", level
, msg
);
47 void sipe_backend_debug(sipe_debug_level level
,
53 va_start(args
, format
);
54 msg
= g_strdup_vprintf(format
, args
);
57 sipe_backend_debug_literal(level
, msg
);
60 gboolean
sipe_backend_debug_enabled(void)
65 void sipe_digest_sha1(SIPE_UNUSED_PARAMETER
const guchar
*data
,
66 SIPE_UNUSED_PARAMETER gsize length
,
67 SIPE_UNUSED_PARAMETER guchar
*digest
) {}
68 const gchar
*sip_transport_epid(SIPE_UNUSED_PARAMETER
struct sipe_core_private
*sipe_private
) { return(NULL
); }
69 const gchar
*sip_transport_ip_address(SIPE_UNUSED_PARAMETER
struct sipe_core_private
*sipe_private
) { return(NULL
); }
70 char *generateUUIDfromEPID(SIPE_UNUSED_PARAMETER
const gchar
*epid
) { return(NULL
); }
71 char *sipe_get_epid(SIPE_UNUSED_PARAMETER
const char *self_sip_uri
,
72 SIPE_UNUSED_PARAMETER
const char *hostname
,
73 SIPE_UNUSED_PARAMETER
const char *ip_address
) { return(NULL
); }
76 static guint succeeded
= 0;
77 static guint failed
= 0;
78 static const gchar
*teststring
;
80 static sipe_xml
*assert_parse(const gchar
*s
, gboolean ok
)
82 sipe_xml
*xml
= sipe_xml_parse(s
, s
? strlen(s
) : 0);
84 teststring
= s
? s
: "(nil)";
86 if ((ok
&& xml
) || (!ok
&& !xml
)) {
89 printf("[%s]\nXML parse FAILED: %p\n",
96 static void assert_name(const sipe_xml
*xml
, const gchar
*s
)
98 const gchar
*name
= sipe_xml_name(xml
);
100 if (sipe_strequal(name
, s
)) {
103 printf("[%s]\nXML name FAILED: '%s' expected: '%s'\n",
104 teststring
, name
? name
: "(nil)", s
? s
: "(nil)");
110 static const sipe_xml
*assert_child(const sipe_xml
*xml
, const gchar
*s
, gboolean ok
)
112 const sipe_xml
*child
= sipe_xml_child(xml
, s
);
114 if ((ok
&& child
) || (!ok
&& !child
)) {
117 printf("[%s]\nXML child FAILED: %p '%s'\n",
118 teststring
, xml
, s
? s
: "(nil)");
124 static void assert_data(const sipe_xml
*xml
, const gchar
*s
)
126 gchar
*data
= sipe_xml_data(xml
);
128 if (sipe_strequal(s
, data
)) {
131 printf("[%s]\nXML data FAILED: '%s' expected: '%s'\n",
132 teststring
, data
? data
: "(nil)", s
? s
: "(nil)");
138 static void assert_attribute(const sipe_xml
*xml
,
139 const gchar
*key
, const gchar
*value
)
141 const gchar
*attr
= sipe_xml_attribute(xml
, key
);
143 if (sipe_strequal(value
, attr
)) {
146 printf("[%s]\nXML attr FAILED: '%s': '%s' expected: '%s'\n",
147 teststring
, key
? key
: "(nil)",
148 attr
? attr
: "(nil)", value
? value
: "(nil)");
153 static void assert_int_attribute(const sipe_xml
*xml
,
154 const gchar
*key
, gint value
, gint fallback
)
156 gint attr
= sipe_xml_int_attribute(xml
, key
, fallback
);
158 if ((attr
== value
) || (attr
== fallback
)) {
161 printf("[%s]\nXML int attr FAILED: '%s': %d expected: %d/%d\n",
162 teststring
, key
? key
: "(nil)",
163 attr
, value
, fallback
);
168 static void assert_stringify(const sipe_xml
*xml
,
172 gchar
*string
= sipe_xml_stringify(xml
);
174 va_start(args
, expected
);
175 while (expected
-- > 0) {
176 const gchar
*alternative
= va_arg(args
, const gchar
*);
177 if (sipe_strequal(string
, alternative
)) {
181 printf("XML stringify alternative FAILED: '%s' (trying next...)\n",
182 alternative
? alternative
: "(nil)");
188 printf("[%s]\nXML stringify all alternatives FAILED: '%s'\n",
189 teststring
, string
? string
: "(nil)");
196 static void assert_raw(const gchar
*raw
,
198 gboolean include_tag
,
199 const char *expected
)
201 gchar
*string
= sipe_xml_extract_raw(raw
, tag
, include_tag
);
204 if (sipe_strequal(string
, expected
)) {
207 printf("[%s]\nXML raw extract FAILED: '%s' expected: '%s'\n",
208 raw
, string
, expected
);
212 printf("[%s]\nXML raw extract not found FAILED: '%s' expected: '%s'\n",
218 printf("[%s]\nXML raw extract no match FAILED: '%s' matched: '%s'\n",
230 /* memory leak check */
231 static gsize allocated
= 0;
233 static gpointer
test_malloc(gsize n_bytes
)
235 gsize
*m
= malloc(sizeof(gsize
) + n_bytes
);
236 if (!m
) return(NULL
);
237 allocated
+= n_bytes
;
242 static void test_free(gpointer mem
)
251 static gpointer
test_realloc(gpointer mem
, gsize n_bytes
)
255 n
= test_malloc(n_bytes
);
257 memcpy(n
, mem
, n_bytes
);
264 static GMemVTable memory_leak_check
= {
273 int main(SIPE_UNUSED_PARAMETER
int argc
, SIPE_UNUSED_PARAMETER
char **argv
)
276 const sipe_xml
*child1
, *child2
;
280 * No idea why the memory leak checks work on some platforms
281 * but fail on others :-( Disable for now...
283 g_mem_set_vtable(&memory_leak_check
);
285 (void) memory_leak_check
;
289 xml
= assert_parse(NULL
, FALSE
);
290 assert_stringify(xml
, 1, NULL
);
292 xml
= assert_parse("", FALSE
);
294 xml
= assert_parse("<?xml version=\"1.0\" ?>", FALSE
);
298 xml
= assert_parse("<test></test>", TRUE
);
299 assert_name(xml
, "test");
300 assert_data(xml
, NULL
);
301 assert_stringify(xml
, 1, "<test/>");
303 xml
= assert_parse("<test/>", TRUE
);
304 assert_name(xml
, "test");
305 assert_data(xml
, NULL
);
306 assert_stringify(xml
, 1, teststring
);
308 xml
= assert_parse("<test>a</test>", TRUE
);
309 assert_name(xml
, "test");
310 assert_data(xml
, "a");
311 assert_stringify(xml
, 1, teststring
);
313 xml
= assert_parse("<test>a\nb</test>", TRUE
);
314 assert_name(xml
, "test");
315 assert_data(xml
, "a\nb");
316 assert_stringify(xml
, 1, teststring
);
320 xml
= assert_parse("<test>a<child>b</child></test>", TRUE
);
321 assert_name(xml
, "test");
322 assert_data(xml
, "a");
323 child1
= assert_child(xml
, NULL
, FALSE
);
324 child1
= assert_child(xml
, "child", TRUE
);
325 assert_name(child1
, "child");
326 assert_data(child1
, "b");
327 child1
= assert_child(xml
, "shouldnotmatch", FALSE
);
328 assert_data(child1
, NULL
);
329 assert_stringify(xml
, 1, teststring
);
332 xml
= assert_parse("<test>a<child/></test>", TRUE
);
333 assert_name(xml
, "test");
334 assert_data(xml
, "a");
335 child1
= assert_child(xml
, "child", TRUE
);
336 assert_name(child1
, "child");
337 assert_data(child1
, NULL
);
338 child1
= assert_child(xml
, "shouldnotmatch", FALSE
);
339 assert_data(child1
, NULL
);
340 assert_stringify(xml
, 1, teststring
);
343 xml
= assert_parse("<test>a<child>b<inner>c</inner></child></test>", TRUE
);
344 assert_name(xml
, "test");
345 assert_data(xml
, "a");
346 child1
= assert_child(xml
, "child", TRUE
);
347 assert_name(child1
, "child");
348 assert_data(child1
, "b");
349 child1
= assert_child(child1
, "inner", TRUE
);
350 assert_name(child1
, "inner");
351 assert_data(child1
, "c");
352 child1
= assert_child(xml
, "child/inner", TRUE
);
353 assert_name(child1
, "inner");
354 assert_data(child1
, "c");
355 assert_stringify(xml
, 1, teststring
);
358 xml
= assert_parse("<test>a<child>b<inner>c<innerinner>d</innerinner></inner></child></test>", TRUE
);
359 assert_name(xml
, "test");
360 assert_data(xml
, "a");
361 child1
= assert_child(xml
, "child", TRUE
);
362 assert_name(child1
, "child");
363 assert_data(child1
, "b");
364 child2
= assert_child(child1
, "inner/innerinner", TRUE
);
365 assert_name(child2
, "innerinner");
366 assert_data(child2
, "d");
367 child1
= assert_child(child1
, "inner", TRUE
);
368 assert_name(child1
, "inner");
369 assert_data(child1
, "c");
370 child1
= assert_child(child1
, "innerinner", TRUE
);
371 assert_name(child1
, "innerinner");
372 assert_data(child1
, "d");
373 child1
= assert_child(xml
, "child/inner", TRUE
);
374 assert_name(child1
, "inner");
375 assert_data(child1
, "c");
376 child1
= assert_child(xml
, "child/inner/innerinner", TRUE
);
377 assert_name(child1
, "innerinner");
378 assert_data(child1
, "d");
379 assert_stringify(xml
, 1, teststring
);
383 xml
= assert_parse("<test a=\"\">a</test>", TRUE
);
384 assert_name(xml
, "test");
385 assert_data(xml
, "a");
386 assert_attribute(xml
, NULL
, NULL
);
387 assert_attribute(xml
, "a", "");
388 assert_attribute(xml
, "b", NULL
);
389 assert_stringify(xml
, 1, teststring
);
392 xml
= assert_parse("<test a=\"1\" b=\"abc\">a</test>", TRUE
);
393 assert_name(xml
, "test");
394 assert_data(xml
, "a");
395 assert_attribute(xml
, "a", "1");
396 assert_int_attribute(xml
, "a", 1, 0);
397 assert_attribute(xml
, "b", "abc");
398 assert_attribute(xml
, "c", NULL
);
399 assert_int_attribute(xml
, "d", 100, 200);
400 /* the attribute order depends on glib hashing :-( */
401 assert_stringify(xml
, 2, teststring
, "<test b=\"abc\" a=\"1\">a</test>");
404 /* attributes with namespace */
405 xml
= assert_parse("<m:row m:uri=\"sip:\" m:displayName=\"X\" m:title=\"Y\" m:office=\"Z\" m:phone=\"0\" m:company=\"A\" m:city=\"B\" m:state=\"C\" m:country=\"D\" m:email=\"E\" />", TRUE
);
406 assert_name(xml
, "row");
407 assert_data(xml
, NULL
);
408 assert_attribute(xml
, "uri", "sip:");
409 assert_attribute(xml
, "displayName", "X");
410 assert_attribute(xml
, "title", "Y");
411 assert_attribute(xml
, "office", "Z");
412 assert_attribute(xml
, "phone", "0");
413 assert_attribute(xml
, "company", "A");
414 assert_attribute(xml
, "city", "B");
415 assert_attribute(xml
, "state", "C");
416 assert_attribute(xml
, "country", "D");
417 assert_attribute(xml
, "email", "E");
420 xml
= assert_parse("<state xsi:type=\"aggregateState\" lastActive=\"date\" xmlns:xsi=\"http://one\" xmlns=\"http://two\"><availability>15500</availability></state>", TRUE
);
421 assert_name(xml
, "state");
422 assert_data(xml
, NULL
);
423 assert_attribute(xml
, "type", "aggregateState");
424 assert_attribute(xml
, "lastActive", "date");
425 assert_attribute(xml
, "xsi", "http://one");
426 assert_attribute(xml
, "xmlns", "http://two");
427 child1
= assert_child(xml
, "availability", TRUE
);
428 assert_name(child1
, "availability");
429 assert_data(child1
, "15500");
433 xml
= assert_parse("t", FALSE
);
435 xml
= assert_parse("<>", FALSE
);
437 xml
= assert_parse("<></>", FALSE
);
439 xml
= assert_parse("<test>", FALSE
);
441 xml
= assert_parse("<a a=\"1\" a=\"2\"></a>", FALSE
);
444 /* XML raw extract */
445 assert_raw("<tag>data</tag>", "tag", FALSE
, "data");
446 assert_raw("<tag>data</tag>", "tag", TRUE
, "<tag>data</tag>");
447 assert_raw("<tag>data</tag>", "tag1", FALSE
, NULL
);
448 assert_raw("<tag>data</tag>", "tag1", TRUE
, NULL
);
449 assert_raw("<ns:tag>data</ns:tag>", "tag", FALSE
, "data");
450 assert_raw("<ns:tag>data</ns:tag>", "tag", TRUE
, "<ns:tag>data</ns:tag>");
451 assert_raw("<ns:tag>data</ns:tag>", "tag1", FALSE
, NULL
);
452 assert_raw("<ns:tag>data</ns:tag>", "tag1", TRUE
, NULL
);
453 assert_raw("<ns:tag>data</ns:tag>", "ns:tag", FALSE
, "data");
454 assert_raw("<ns:tag>data</ns:tag>", "ns:tag", TRUE
, "<ns:tag>data</ns:tag>");
455 assert_raw("<ns:tag>data</ns:tag>", "ns:tag1", FALSE
, NULL
);
456 assert_raw("<ns:tag>data</ns:tag>", "ns:tag1", TRUE
, NULL
);
458 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag", FALSE
, "data");
459 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag", TRUE
, "<tag>data</tag>");
460 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag", FALSE
, "data");
461 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag", TRUE
, "<tag>data</tag>");
462 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag1", FALSE
, NULL
);
463 assert_raw("<othertag>data</othertag><tag>data</tag>", "tag1", TRUE
, NULL
);
464 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag1", FALSE
, NULL
);
465 assert_raw("<othertag>data</othertag><tag>data</tag><othertag>data</othertag>", "tag1", TRUE
, NULL
);
466 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag", FALSE
, "data");
467 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag", TRUE
, "<ns:tag>data</ns:tag>");
468 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag", FALSE
, "data");
469 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag", TRUE
, "<ns:tag>data</ns:tag>");
470 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag1", FALSE
, NULL
);
471 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag>", "tag1", TRUE
, NULL
);
472 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag1", FALSE
, NULL
);
473 assert_raw("<othertag>data</othertag><ns:tag>data</ns:tag><othertag>data</othertag>", "tag1", TRUE
, NULL
);
475 /* broken XML raw extract */
476 assert_raw("tag>data</tag>", "tag", FALSE
, NULL
);
477 assert_raw(":tag>data</tag>", "tag", FALSE
, NULL
);
478 assert_raw("<tag>data</tag", "tag", FALSE
, NULL
);
479 assert_raw("<tag>data</tag1>", "tag", FALSE
, NULL
);
480 assert_raw("<ns:tag>data</tag1>", "tag", FALSE
, NULL
);
481 assert_raw("<ns:tag>data</ns:tag1>", "tag", FALSE
, NULL
);
484 printf("MEMORY LEAK: %" G_GSIZE_FORMAT
" still allocated\n", allocated
);
487 printf("MEMORY LEAK CHECK OK\n");
491 printf("Result: %d PASSED %d FAILED\n", succeeded
, failed
);