1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx>
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/queue.h>
23 #define MARSHAL_EXPORT
24 #include "check-compat.h"
25 #include "../src/marshal.h"
26 #include "../src/log.h"
28 /* This suite can be run in valgrind for memory leaks:
29 CK_FORK=no valgrind -v --leak-check=yes ./tests/check_marshal
32 /* Use this callback to avoid some logs */
33 void donothing(int pri
, const char *msg
) {};
35 struct struct_simple
{
42 MARSHAL(struct_simple
);
44 START_TEST(test_simple_structure
) {
45 struct struct_simple source
= {
50 .a5
= { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
52 struct struct_simple
*destination
;
56 len
= struct_simple_serialize(&source
, &buffer
);
57 fail_unless(len
> 0, "Unable to serialize");
58 memset(&source
, 0, sizeof(struct struct_simple
));
59 len2
= struct_simple_unserialize(buffer
, len
, &destination
);
60 fail_unless(len2
> 0, "Unable to deserialize");
62 ck_assert_int_eq(len
, len2
);
63 ck_assert_int_eq(destination
->a1
, 78452);
64 ck_assert_int_eq(destination
->a2
, 48751424);
65 ck_assert_int_eq(destination
->a3
, 'h');
66 ck_assert_int_eq(destination
->a4
, 784254);
67 ck_assert_int_eq(destination
->a5
[0], 'A');
68 ck_assert_int_eq(destination
->a5
[1], 'B');
69 ck_assert_int_eq(destination
->a5
[2], 'C');
70 ck_assert_int_eq(destination
->a5
[3], 'D');
71 ck_assert_int_eq(destination
->a5
[4], 'E');
72 ck_assert_int_eq(destination
->a5
[5], 'F');
73 ck_assert_int_eq(destination
->a5
[6], 'G');
80 struct struct_simple e2
;
83 MARSHAL_BEGIN(struct_sub
)
84 MARSHAL_SUBSTRUCT(struct_sub
, struct_simple
, e2
)
85 MARSHAL_END(struct_sub
);
87 START_TEST(test_substruct_structure
) {
88 struct struct_sub source
= {
95 .a5
= { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
100 struct struct_sub
*destination
;
104 len
= struct_sub_serialize(&source
, &buffer
);
105 fail_unless(len
> 0, "Unable to serialize");
106 memset(&source
, 0, sizeof(struct struct_sub
));
107 len2
= struct_sub_unserialize(buffer
, len
, &destination
);
108 fail_unless(len2
> 0, "Unable to deserialize");
110 ck_assert_int_eq(len
, len2
);
111 ck_assert_int_eq(destination
->e1
, -5122);
112 ck_assert_int_eq(destination
->e2
.a1
, 78452);
113 ck_assert_int_eq(destination
->e2
.a2
, 48751424);
114 ck_assert_int_eq(destination
->e2
.a3
, 'h');
115 ck_assert_int_eq(destination
->e2
.a4
, 784254);
116 ck_assert_int_eq(destination
->e2
.a5
[0], 'A');
117 ck_assert_int_eq(destination
->e2
.a5
[1], 'B');
118 ck_assert_int_eq(destination
->e2
.a5
[2], 'C');
119 ck_assert_int_eq(destination
->e2
.a5
[3], 'D');
120 ck_assert_int_eq(destination
->e2
.a5
[4], 'E');
121 ck_assert_int_eq(destination
->e2
.a5
[5], 'F');
122 ck_assert_int_eq(destination
->e2
.a5
[6], 'G');
123 ck_assert_int_eq(destination
->e3
, 'a');
128 struct struct_onepointer
{
132 struct struct_simple
*b4
;
135 MARSHAL_BEGIN(struct_onepointer
)
136 MARSHAL_POINTER(struct_onepointer
, struct_simple
, b4
)
137 MARSHAL_END(struct_onepointer
);
139 START_TEST(test_pointer_structure
) {
140 struct struct_simple source_simple
= {
145 .a5
= { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
147 struct struct_onepointer source
= {
151 .b4
= &source_simple
,
155 struct struct_onepointer
*destination
;
159 len
= struct_onepointer_serialize(&source
, &buffer
);
160 fail_unless(len
> 0, "Unable to serialize");
161 memset(&source_simple
, 0, sizeof(struct struct_simple
));
162 memset(&source
, 0, sizeof(struct struct_onepointer
));
163 len2
= struct_onepointer_unserialize(buffer
, len
, &destination
);
164 fail_unless(len2
> 0, "Unable to deserialize");
166 ck_assert_int_eq(len
, len2
);
167 ck_assert_int_eq(destination
->b1
, 18);
168 ck_assert_int_eq(destination
->b2
, 15454);
169 ck_assert_int_eq(destination
->b3
, 'o');
170 ck_assert_int_eq(destination
->b4
->a1
, 78452);
171 ck_assert_int_eq(destination
->b4
->a2
, 48751424);
172 ck_assert_int_eq(destination
->b4
->a3
, 'h');
173 ck_assert_int_eq(destination
->b4
->a4
, 784254);
174 ck_assert_int_eq(destination
->b4
->a5
[0], 'A');
175 ck_assert_int_eq(destination
->b4
->a5
[1], 'B');
176 ck_assert_int_eq(destination
->b4
->a5
[2], 'C');
177 ck_assert_int_eq(destination
->b4
->a5
[3], 'D');
178 ck_assert_int_eq(destination
->b4
->a5
[4], 'E');
179 ck_assert_int_eq(destination
->b4
->a5
[5], 'F');
180 ck_assert_int_eq(destination
->b4
->a5
[6], 'G');
181 ck_assert_int_eq(destination
->b5
, 333333);
182 free(destination
->b4
); free(destination
);
186 struct struct_nestedpointers
{
189 struct struct_simple
*c3
;
190 struct struct_onepointer
*c4
;
193 MARSHAL_BEGIN(struct_nestedpointers
)
194 MARSHAL_POINTER(struct_nestedpointers
, struct_simple
, c3
)
195 MARSHAL_POINTER(struct_nestedpointers
, struct_onepointer
, c4
)
196 MARSHAL_END(struct_nestedpointers
);
198 START_TEST(test_several_pointers_structure
) {
199 struct struct_simple source_simple1
= {
204 .a5
= { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
206 struct struct_simple source_simple2
= {
211 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
213 struct struct_onepointer source_onepointer
= {
217 .b4
= &source_simple1
,
220 struct struct_nestedpointers source
= {
223 .c3
= &source_simple2
,
224 .c4
= &source_onepointer
,
228 struct struct_nestedpointers
*destination
;
232 len
= struct_nestedpointers_serialize(&source
, &buffer
);
233 fail_unless(len
> 0, "Unable to serialize");
234 memset(&source_simple1
, 0, sizeof(struct struct_simple
));
235 memset(&source_simple2
, 0, sizeof(struct struct_simple
));
236 memset(&source_onepointer
, 0, sizeof(struct struct_onepointer
));
237 memset(&source
, 0, sizeof(struct struct_nestedpointers
));
238 len2
= struct_nestedpointers_unserialize(buffer
, len
, &destination
);
239 fail_unless(len2
> 0, "Unable to deserialize");
241 ck_assert_int_eq(len
, len2
);
242 ck_assert_int_eq(destination
->c1
, 4542);
243 ck_assert_int_eq(destination
->c2
, 5665454);
244 ck_assert_int_eq(destination
->c3
->a1
, 451);
245 ck_assert_int_eq(destination
->c3
->a2
, 451424);
246 ck_assert_int_eq(destination
->c3
->a3
, 'o');
247 ck_assert_int_eq(destination
->c3
->a4
, 74);
248 ck_assert_int_eq(destination
->c3
->a5
[3], 'd');
249 ck_assert_int_eq(destination
->c3
->a5
[4], 'e');
250 ck_assert_int_eq(destination
->c3
->a5
[6], 'g');
251 ck_assert_int_eq(destination
->c4
->b1
, 18);
252 ck_assert_int_eq(destination
->c4
->b2
, 15454);
253 ck_assert_int_eq(destination
->c4
->b3
, 'o');
254 ck_assert_int_eq(destination
->c4
->b4
->a1
, 78452);
255 ck_assert_int_eq(destination
->c4
->b4
->a2
, 48751424);
256 ck_assert_int_eq(destination
->c4
->b4
->a3
, 'h');
257 ck_assert_int_eq(destination
->c4
->b4
->a4
, 784254);
258 ck_assert_int_eq(destination
->c4
->b4
->a5
[0], 'A');
259 ck_assert_int_eq(destination
->c4
->b4
->a5
[1], 'B');
260 ck_assert_int_eq(destination
->c4
->b4
->a5
[2], 'C');
261 ck_assert_int_eq(destination
->c4
->b4
->a5
[3], 'D');
262 ck_assert_int_eq(destination
->c4
->b4
->a5
[4], 'E');
263 ck_assert_int_eq(destination
->c4
->b4
->a5
[5], 'F');
264 ck_assert_int_eq(destination
->c4
->b4
->a5
[6], 'G');
265 ck_assert_int_eq(destination
->c4
->b5
, 333333);
266 free(destination
->c3
); free(destination
->c4
->b4
);
267 free(destination
->c4
); free(destination
);
271 START_TEST(test_null_pointers
) {
272 struct struct_simple source_simple2
= {
277 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
279 struct struct_nestedpointers source
= {
282 .c3
= &source_simple2
,
287 struct struct_nestedpointers
*destination
;
291 len
= struct_nestedpointers_serialize(&source
, &buffer
);
292 fail_unless(len
> 0, "Unable to serialize");
293 memset(&source_simple2
, 0, sizeof(struct struct_simple
));
294 memset(&source
, 0, sizeof(struct struct_nestedpointers
));
295 len2
= struct_nestedpointers_unserialize(buffer
, len
, &destination
);
296 fail_unless(len2
> 0, "Unable to deserialize");
298 ck_assert_int_eq(len
, len2
);
299 ck_assert_int_eq(destination
->c1
, 4542);
300 ck_assert_int_eq(destination
->c2
, 5665454);
301 ck_assert_int_eq(destination
->c3
->a1
, 451);
302 ck_assert_int_eq(destination
->c3
->a2
, 451424);
303 ck_assert_int_eq(destination
->c3
->a3
, 'o');
304 ck_assert_int_eq(destination
->c3
->a4
, 74);
305 ck_assert_int_eq(destination
->c3
->a5
[3], 'd');
306 ck_assert_int_eq(destination
->c3
->a5
[4], 'e');
307 ck_assert_int_eq(destination
->c3
->a5
[6], 'g');
308 ck_assert_ptr_eq(destination
->c4
, NULL
);
309 free(destination
->c3
); free(destination
);
313 struct struct_multipleref
{
315 struct struct_simple
* f2
;
316 struct struct_simple
* f3
;
317 struct struct_nestedpointers
* f4
;
319 MARSHAL_BEGIN(struct_multipleref
)
320 MARSHAL_POINTER(struct_multipleref
, struct_simple
, f2
)
321 MARSHAL_POINTER(struct_multipleref
, struct_simple
, f3
)
322 MARSHAL_POINTER(struct_multipleref
, struct_nestedpointers
, f4
)
323 MARSHAL_END(struct_multipleref
);
325 START_TEST(test_multiple_references
) {
326 struct struct_simple source_simple
= {
331 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
333 struct struct_nestedpointers source_nested
= {
334 .c3
= &source_simple
,
337 struct struct_multipleref source
= {
339 .f2
= &source_simple
,
340 .f3
= &source_simple
,
341 .f4
= &source_nested
,
344 struct struct_multipleref
*destination
;
348 len
= struct_multipleref_serialize(&source
, &buffer
);
349 fail_unless(buffer
!= NULL
, "Buffer is empty");
350 fail_unless(len
> 0, "Unable to serialize");
351 memset(&source_simple
, 0, sizeof(struct struct_simple
));
352 memset(&source_nested
, 0, sizeof(struct struct_nestedpointers
));
353 memset(&source
, 0, sizeof(struct struct_multipleref
));
354 len2
= struct_multipleref_unserialize(buffer
, len
, &destination
);
355 fail_unless(len2
> 0, "Unable to deserialize");
357 ck_assert_int_eq(len
, len2
);
358 ck_assert_int_eq(destination
->f1
, 15);
359 ck_assert_ptr_eq(destination
->f2
, destination
->f3
);
360 ck_assert_ptr_eq(destination
->f2
, destination
->f4
->c3
);
361 ck_assert_int_eq(destination
->f2
->a1
, 451);
362 ck_assert_int_eq(destination
->f2
->a2
, 451424);
363 ck_assert_int_eq(destination
->f2
->a3
, 'o');
364 ck_assert_int_eq(destination
->f2
->a4
, 74);
365 ck_assert_ptr_eq(destination
->f4
->c4
, NULL
);
366 free(destination
->f2
); free(destination
->f4
); free(destination
);
370 struct struct_circularref
{
372 struct struct_circularref
* g2
;
374 MARSHAL_BEGIN(struct_circularref
)
375 MARSHAL_POINTER(struct_circularref
, struct_circularref
, g2
)
376 MARSHAL_END(struct_circularref
);
378 START_TEST(test_circular_references
) {
379 struct struct_circularref source
= {
384 struct struct_circularref
*destination
;
388 len
= struct_circularref_serialize(&source
, &buffer
);
389 fail_unless(len
> 0, "Unable to serialize");
390 memset(&source
, 0, sizeof(struct struct_circularref
));
391 len2
= struct_circularref_unserialize(buffer
, len
, &destination
);
392 fail_unless(len2
> 0, "Unable to deserialize");
394 ck_assert_int_eq(len
, len2
);
395 ck_assert_int_eq(destination
->g1
, 42);
396 ck_assert_int_eq(destination
->g2
->g1
, 42);
397 ck_assert_ptr_eq(destination
->g2
, destination
->g2
->g2
);
402 START_TEST(test_too_small_unmarshal
) {
403 struct struct_simple source_simple1
;
404 struct struct_onepointer source_onepointer
= {
405 .b4
= &source_simple1
,
407 struct struct_nestedpointers source
= {
408 .c3
= &source_simple1
,
409 .c4
= &source_onepointer
,
412 struct struct_nestedpointers
*destination
;
417 log_register(donothing
);
419 len
= struct_nestedpointers_serialize(&source
, &buffer
);
420 fail_unless(len
> 0, "Unable to serialize");
421 memset(&source_simple1
, 0, sizeof(struct struct_simple
));
422 memset(&source_onepointer
, 0, sizeof(struct struct_onepointer
));
423 memset(&source
, 0, sizeof(struct struct_nestedpointers
));
424 /* Loop 30 times to ease debugging leaks with valgrind */
425 for (j
= 0; j
< 30; j
++) {
426 for (i
= 0; i
< len
; i
++) {
427 len2
= struct_nestedpointers_unserialize(buffer
, 1, &destination
);
428 fail_unless(len2
== 0,
429 "Should not be able to deserialize, too small (%d<%d)",
433 len2
= struct_nestedpointers_unserialize(buffer
, len
+ 5, &destination
);
434 fail_unless(len2
== len
, "Deserialized too much");
435 free(destination
->c3
);
436 free(destination
->c4
); free(destination
); free(buffer
);
442 struct struct_simpleentry
{
443 TAILQ_ENTRY(struct_simpleentry
) s_entries
;
445 struct struct_simple
*g2
;
447 MARSHAL_BEGIN(struct_simpleentry
)
448 MARSHAL_TQE(struct_simpleentry
, s_entries
)
449 MARSHAL_POINTER(struct_simpleentry
, struct_simple
, g2
)
450 MARSHAL_END(struct_simpleentry
);
452 TAILQ_HEAD(list_simple
, struct_simpleentry
);
453 MARSHAL_TQ(list_simple
, struct_simpleentry
);
455 START_TEST(test_simple_list
) {
456 struct struct_simple source_simple
= {
461 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
463 struct list_simple source
;
464 struct struct_simpleentry entry1
= {
466 .g2
= &source_simple
,
468 struct struct_simpleentry entry2
= {
470 .g2
= &source_simple
,
472 struct struct_simpleentry entry3
= {
476 struct struct_simpleentry entry4
= {
478 .g2
= &source_simple
,
480 struct list_simple
*destination
;
483 struct struct_simpleentry
*e1
, *e2
;
484 struct struct_simple
*s
;
487 TAILQ_INSERT_TAIL(&source
, &entry1
, s_entries
);
488 TAILQ_INSERT_TAIL(&source
, &entry2
, s_entries
);
489 TAILQ_INSERT_TAIL(&source
, &entry3
, s_entries
);
490 TAILQ_INSERT_TAIL(&source
, &entry4
, s_entries
);
492 len
= list_simple_serialize(&source
, &buffer
);
493 fail_unless(len
> 0, "Unable to serialize");
494 memset(&source
, 0, sizeof(struct list_simple
));
495 memset(&entry1
, 0, sizeof(struct struct_simpleentry
));
496 memset(&entry2
, 0, sizeof(struct struct_simpleentry
));
497 memset(&entry3
, 0, sizeof(struct struct_simpleentry
));
498 memset(&entry4
, 0, sizeof(struct struct_simpleentry
));
499 len2
= list_simple_unserialize(buffer
, len
, &destination
);
500 fail_unless(len2
> 0, "Unable to deserialize");
503 e1
= TAILQ_FIRST(destination
);
504 ck_assert_int_eq(e1
->g1
, 47);
506 e2
= TAILQ_NEXT(e1
, s_entries
);
508 ck_assert_int_eq(e2
->g1
, 49);
509 ck_assert_ptr_eq(e2
->g2
, s
);
510 e1
= TAILQ_NEXT(e2
, s_entries
);
512 ck_assert_int_eq(e1
->g1
, 4700);
513 ck_assert_ptr_eq(e1
->g2
, NULL
);
514 e2
= TAILQ_NEXT(e1
, s_entries
);
516 ck_assert_int_eq(e2
->g1
, -47);
517 ck_assert_ptr_eq(e2
->g2
, s
);
518 e1
= TAILQ_NEXT(e2
, s_entries
);
520 ck_assert_ptr_eq(e1
, NULL
);
526 START_TEST(test_simple_repaired_list
) {
527 struct struct_simple source_simple
= {
532 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
534 struct list_simple source
;
535 struct struct_simpleentry entry1
= {
537 .g2
= &source_simple
,
539 struct struct_simpleentry entry2
= {
541 .g2
= &source_simple
,
543 struct struct_simpleentry entry3
= {
547 struct struct_simpleentry entry4
= {
549 .g2
= &source_simple
,
551 struct struct_simpleentry entry5
= {
555 struct list_simple
*destination
;
558 struct struct_simpleentry
*e1
, *e2
, *e3
, *e4
;
561 TAILQ_INSERT_TAIL(&source
, &entry1
, s_entries
);
562 TAILQ_INSERT_TAIL(&source
, &entry2
, s_entries
);
563 TAILQ_INSERT_TAIL(&source
, &entry3
, s_entries
);
564 TAILQ_INSERT_TAIL(&source
, &entry4
, s_entries
);
566 len
= list_simple_serialize(&source
, &buffer
);
567 fail_unless(len
> 0, "Unable to serialize");
568 memset(&source
, 0, sizeof(struct list_simple
));
569 memset(&entry1
, 0, sizeof(struct struct_simpleentry
));
570 memset(&entry2
, 0, sizeof(struct struct_simpleentry
));
571 memset(&entry3
, 0, sizeof(struct struct_simpleentry
));
572 memset(&entry4
, 0, sizeof(struct struct_simpleentry
));
573 len2
= list_simple_unserialize(buffer
, len
, &destination
);
574 fail_unless(len2
> 0, "Unable to deserialize");
577 marshal_repair_tailq(struct_simpleentry
, destination
, s_entries
);
579 e1
= TAILQ_FIRST(destination
);
580 ck_assert_int_eq(e1
->g1
, 47);
581 e4
= TAILQ_LAST(destination
, list_simple
);
582 ck_assert_int_eq(e4
->g1
, -47);
583 e3
= TAILQ_PREV(e4
, list_simple
, s_entries
);
584 ck_assert_int_eq(e3
->g1
, 4700);
585 e2
= TAILQ_PREV(e3
, list_simple
, s_entries
);
586 ck_assert_int_eq(e2
->g1
, 49);
588 TAILQ_INSERT_TAIL(destination
, &entry5
, s_entries
);
598 START_TEST(test_empty_repaired_list
) {
599 struct list_simple source
;
601 struct list_simple
*destination
;
603 struct struct_simpleentry
*e1
;
604 struct struct_simpleentry entry5
= {
610 len
= list_simple_serialize(&source
, &buffer
);
611 fail_unless(len
> 0, "Unable to serialize");
612 memset(&source
, 0, sizeof(struct list_simple
));
613 len2
= list_simple_unserialize(buffer
, len
, &destination
);
614 fail_unless(len2
> 0, "Unable to deserialize");
617 marshal_repair_tailq(struct_simpleentry
, destination
, s_entries
);
619 e1
= TAILQ_FIRST(destination
);
620 ck_assert_ptr_eq(e1
, NULL
);
621 e1
= TAILQ_LAST(destination
, list_simple
);
622 ck_assert_ptr_eq(e1
, NULL
);
624 TAILQ_INSERT_TAIL(destination
, &entry5
, s_entries
);
630 struct struct_withlist
{
632 TAILQ_HEAD(, struct_simpleentry
) i2
;
635 MARSHAL_BEGIN(struct_withlist
)
636 MARSHAL_SUBTQ(struct_withlist
, struct_simpleentry
, i2
)
637 MARSHAL_END(struct_withlist
);
639 START_TEST(test_embedded_list
) {
640 struct struct_withlist source
= {
644 struct struct_simple source_simple
= {
649 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
651 struct struct_simpleentry entry1
= {
653 .g2
= &source_simple
,
655 struct struct_simpleentry entry2
= {
657 .g2
= &source_simple
,
659 struct struct_simpleentry entry3
= {
663 struct struct_simpleentry entry4
= {
665 .g2
= &source_simple
,
667 struct struct_withlist
*destination
;
670 struct struct_simpleentry
*e1
, *e2
;
671 struct struct_simple
*s
;
673 TAILQ_INIT(&source
.i2
);
674 TAILQ_INSERT_TAIL(&source
.i2
, &entry1
, s_entries
);
675 TAILQ_INSERT_TAIL(&source
.i2
, &entry2
, s_entries
);
676 TAILQ_INSERT_TAIL(&source
.i2
, &entry3
, s_entries
);
677 TAILQ_INSERT_TAIL(&source
.i2
, &entry4
, s_entries
);
679 len
= struct_withlist_serialize(&source
, &buffer
);
680 fail_unless(len
> 0, "Unable to serialize");
681 memset(&source
, 0, sizeof(struct list_simple
));
682 memset(&entry1
, 0, sizeof(struct struct_simpleentry
));
683 memset(&entry2
, 0, sizeof(struct struct_simpleentry
));
684 memset(&entry3
, 0, sizeof(struct struct_simpleentry
));
685 memset(&entry4
, 0, sizeof(struct struct_simpleentry
));
686 len2
= struct_withlist_unserialize(buffer
, len
, &destination
);
687 fail_unless(len2
> 0, "Unable to deserialize");
690 ck_assert_int_eq(destination
->i1
, 45424);
691 ck_assert_int_eq(destination
->i3
, 4542);
692 e1
= TAILQ_FIRST(&destination
->i2
);
693 ck_assert_int_eq(e1
->g1
, 47);
694 ck_assert_int_eq(e1
->g2
->a4
, 74);
696 e2
= TAILQ_NEXT(e1
, s_entries
);
698 ck_assert_int_eq(e2
->g1
, 49);
699 ck_assert_ptr_eq(e2
->g2
, s
);
700 e1
= TAILQ_NEXT(e2
, s_entries
);
702 ck_assert_int_eq(e1
->g1
, 4700);
703 ck_assert_ptr_eq(e1
->g2
, NULL
);
704 e2
= TAILQ_NEXT(e1
, s_entries
);
706 ck_assert_int_eq(e2
->g1
, -47);
707 ck_assert_ptr_eq(e2
->g2
, s
);
708 e1
= TAILQ_NEXT(e2
, s_entries
);
710 ck_assert_ptr_eq(e1
, NULL
);
716 struct struct_string
{
721 MARSHAL_BEGIN(struct_string
)
722 MARSHAL_STR(struct_string
, s2
)
723 MARSHAL_STR(struct_string
, s3
)
724 MARSHAL_END(struct_string
);
726 START_TEST(test_string
) {
727 struct struct_string source
= {
732 struct struct_string
*destination
;
736 len
= struct_string_serialize(&source
, &buffer
);
737 fail_unless(len
> 0, "Unable to serialize");
738 memset(&source
, 0, sizeof(struct struct_string
));
739 len2
= struct_string_unserialize(buffer
, len
, &destination
);
740 fail_unless(len2
> 0, "Unable to deserialize");
742 ck_assert_int_eq(len
, len2
);
743 ck_assert_int_eq(destination
->s1
, 44444);
744 ck_assert_str_eq(destination
->s2
, "String 2");
745 ck_assert_str_eq(destination
->s3
, "String 3");
746 free(destination
->s2
); free(destination
->s3
);
751 struct struct_fixedstring
{
757 MARSHAL_BEGIN(struct_fixedstring
)
758 MARSHAL_FSTR(struct_fixedstring
, s2
, s2_len
)
759 MARSHAL_STR(struct_fixedstring
, s3
)
760 MARSHAL_END(struct_fixedstring
);
762 START_TEST(test_fixed_string
) {
763 struct struct_fixedstring source
= {
765 .s2
= "String 2 Bla",
766 .s2_len
= 8, /* Not 12! */
769 struct struct_fixedstring
*destination
;
773 len
= struct_fixedstring_serialize(&source
, &buffer
);
774 fail_unless(len
> 0, "Unable to serialize");
775 memset(&source
, 0, sizeof(struct struct_fixedstring
));
776 len2
= struct_fixedstring_unserialize(buffer
, len
, &destination
);
777 fail_unless(len2
> 0, "Unable to deserialize");
779 ck_assert_int_eq(len
, len2
);
780 ck_assert_int_eq(destination
->s1
, 44444);
781 ck_assert_int_eq(destination
->s2_len
, 8);
782 ck_assert_int_eq(destination
->s2
[0], 'S');
783 ck_assert_int_eq(destination
->s2
[2], 'r');
784 ck_assert_int_eq(destination
->s2
[4], 'n');
785 ck_assert_int_eq(destination
->s2
[5], 'g');
786 ck_assert_int_eq(destination
->s2
[6], ' ');
787 ck_assert_int_eq(destination
->s2
[7], '2');
788 ck_assert_int_eq(destination
->s2
[8], '\0'); /* fixed string are null-terminated too */
789 ck_assert_str_eq(destination
->s3
, "String 3");
790 free(destination
->s2
); free(destination
->s3
);
795 struct struct_ignore
{
800 MARSHAL_BEGIN(struct_ignore
)
801 MARSHAL_IGNORE(struct_ignore
, t2
)
802 MARSHAL_END(struct_ignore
);
804 START_TEST(test_ignore
) {
805 struct struct_ignore source
= {
807 .t2
= (void *)"String 2 Bla",
810 struct struct_ignore
*destination
;
814 len
= struct_ignore_serialize(&source
, &buffer
);
815 fail_unless(len
> 0, "Unable to serialize");
816 memset(&source
, 0, sizeof(struct struct_ignore
));
817 len2
= struct_ignore_unserialize(buffer
, len
, &destination
);
818 fail_unless(len2
> 0, "Unable to deserialize");
820 ck_assert_int_eq(len
, len2
);
821 ck_assert_int_eq(destination
->t1
, 4544);
822 ck_assert_ptr_eq(destination
->t2
, NULL
);
823 ck_assert_int_eq(destination
->t3
, 11111);
828 START_TEST(test_equality
) {
829 struct struct_simple source_simple1
= {
834 .a5
= { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
836 struct struct_simpleentry entry1
= {
838 .g2
= &source_simple1
,
841 struct struct_simple source_simple2
;
842 struct struct_simpleentry entry2
;
844 void *buffer1
, *buffer2
;
845 memcpy(&source_simple2
, &source_simple1
, sizeof(source_simple1
));
846 memcpy(&entry2
, &entry1
, sizeof(entry1
));
847 entry2
.g2
= &source_simple2
;
848 ssize_t len1
= struct_simpleentry_serialize(&entry1
, &buffer1
);
849 ssize_t len2
= struct_simpleentry_serialize(&entry2
, &buffer2
);
850 fail_unless(len1
> 0, "Unable to serialize");
851 fail_unless(len2
> 0, "Unable to serialize");
852 ck_assert_int_eq(len1
, len2
);
853 fail_unless(!memcmp(buffer1
, buffer2
, len1
), "Same content should give the same serialization");
854 free(buffer1
); free(buffer2
);
861 Suite
*s
= suite_create("Marshalling");
863 TCase
*tc_marshal
= tcase_create("Marshalling");
864 tcase_add_test(tc_marshal
, test_simple_structure
);
865 tcase_add_test(tc_marshal
, test_substruct_structure
);
866 tcase_add_test(tc_marshal
, test_pointer_structure
);
867 tcase_add_test(tc_marshal
, test_several_pointers_structure
);
868 tcase_add_test(tc_marshal
, test_null_pointers
);
869 tcase_add_test(tc_marshal
, test_multiple_references
);
870 tcase_add_test(tc_marshal
, test_circular_references
);
871 tcase_add_test(tc_marshal
, test_too_small_unmarshal
);
872 tcase_add_test(tc_marshal
, test_simple_list
);
873 tcase_add_test(tc_marshal
, test_simple_repaired_list
);
874 tcase_add_test(tc_marshal
, test_empty_repaired_list
);
875 tcase_add_test(tc_marshal
, test_embedded_list
);
876 tcase_add_test(tc_marshal
, test_string
);
877 tcase_add_test(tc_marshal
, test_fixed_string
);
878 tcase_add_test(tc_marshal
, test_ignore
);
879 tcase_add_test(tc_marshal
, test_equality
);
880 suite_add_tcase(s
, tc_marshal
);
889 Suite
*s
= marshal_suite();
890 SRunner
*sr
= srunner_create(s
);
891 srunner_run_all(sr
, CK_ENV
);
892 number_failed
= srunner_ntests_failed(sr
);
894 return (number_failed
== 0) ? EXIT_SUCCESS
: EXIT_FAILURE
;