]> git.ipfire.org Git - thirdparty/lldpd.git/blob - tests/check_marshal.c
tests: display tests/test-suite.log on errors
[thirdparty/lldpd.git] / tests / check_marshal.c
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3 * Copyright (c) 2015 Vincent Bernat <bernat@luffy.cx>
4 *
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.
8 *
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.
16 */
17
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <check.h>
21 #include <sys/queue.h>
22
23 #define MARSHAL_EXPORT
24 #include "check-compat.h"
25 #include "../src/marshal.h"
26 #include "../src/log.h"
27
28 /* This suite can be run in valgrind for memory leaks:
29 CK_FORK=no valgrind -v --leak-check=yes ./tests/check_marshal
30 */
31
32 /* Use this callback to avoid some logs */
33 void donothing(int pri, const char *msg) {};
34
35 struct struct_simple {
36 int a1;
37 long a2;
38 char a3;
39 time_t a4;
40 char a5[7];
41 };
42 MARSHAL(struct_simple);
43
44 START_TEST(test_simple_structure) {
45 struct struct_simple source = {
46 .a1 = 78452,
47 .a2 = 48751424,
48 .a3 = 'h',
49 .a4 = 784254,
50 .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
51 };
52 struct struct_simple *destination;
53 void *buffer;
54 size_t len, len2;
55
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");
61 free(buffer);
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');
74 free(destination);
75 }
76 END_TEST
77
78 struct struct_sub {
79 int e1;
80 struct struct_simple e2;
81 char e3;
82 };
83 MARSHAL_BEGIN(struct_sub)
84 MARSHAL_SUBSTRUCT(struct_sub, struct_simple, e2)
85 MARSHAL_END(struct_sub);
86
87 START_TEST(test_substruct_structure) {
88 struct struct_sub source = {
89 .e1 = -5122,
90 .e2 = {
91 .a1 = 78452,
92 .a2 = 48751424,
93 .a3 = 'h',
94 .a4 = 784254,
95 .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
96 },
97 .e3 = 'a',
98 };
99
100 struct struct_sub *destination;
101 void *buffer;
102 size_t len, len2;
103
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");
109 free(buffer);
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');
124 free(destination);
125 }
126 END_TEST
127
128 struct struct_onepointer {
129 int b1;
130 long b2;
131 char b3;
132 struct struct_simple *b4;
133 int b5;
134 };
135 MARSHAL_BEGIN(struct_onepointer)
136 MARSHAL_POINTER(struct_onepointer, struct_simple, b4)
137 MARSHAL_END(struct_onepointer);
138
139 START_TEST(test_pointer_structure) {
140 struct struct_simple source_simple = {
141 .a1 = 78452,
142 .a2 = 48751424,
143 .a3 = 'h',
144 .a4 = 784254,
145 .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
146 };
147 struct struct_onepointer source = {
148 .b1 = 18,
149 .b2 = 15454,
150 .b3 = 'o',
151 .b4 = &source_simple,
152 .b5 = 333333,
153 };
154
155 struct struct_onepointer *destination;
156 void *buffer;
157 size_t len, len2;
158
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");
165 free(buffer);
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);
183 }
184 END_TEST
185
186 struct struct_nestedpointers {
187 int c1;
188 long c2;
189 struct struct_simple *c3;
190 struct struct_onepointer *c4;
191 int c5;
192 };
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);
197
198 START_TEST(test_several_pointers_structure) {
199 struct struct_simple source_simple1 = {
200 .a1 = 78452,
201 .a2 = 48751424,
202 .a3 = 'h',
203 .a4 = 784254,
204 .a5 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G'},
205 };
206 struct struct_simple source_simple2 = {
207 .a1 = 451,
208 .a2 = 451424,
209 .a3 = 'o',
210 .a4 = 74,
211 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
212 };
213 struct struct_onepointer source_onepointer = {
214 .b1 = 18,
215 .b2 = 15454,
216 .b3 = 'o',
217 .b4 = &source_simple1,
218 .b5 = 333333,
219 };
220 struct struct_nestedpointers source = {
221 .c1 = 4542,
222 .c2 = 5665454,
223 .c3 = &source_simple2,
224 .c4 = &source_onepointer,
225 .c5 = -545424,
226 };
227
228 struct struct_nestedpointers *destination;
229 void *buffer;
230 size_t len, len2;
231
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");
240 free(buffer);
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);
268 }
269 END_TEST
270
271 START_TEST(test_null_pointers) {
272 struct struct_simple source_simple2 = {
273 .a1 = 451,
274 .a2 = 451424,
275 .a3 = 'o',
276 .a4 = 74,
277 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
278 };
279 struct struct_nestedpointers source = {
280 .c1 = 4542,
281 .c2 = 5665454,
282 .c3 = &source_simple2,
283 .c4 = NULL,
284 .c5 = -545424,
285 };
286
287 struct struct_nestedpointers *destination;
288 void *buffer;
289 size_t len, len2;
290
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");
297 free(buffer);
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);
310 }
311 END_TEST
312
313 struct struct_multipleref {
314 int f1;
315 struct struct_simple* f2;
316 struct struct_simple* f3;
317 struct struct_nestedpointers* f4;
318 };
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);
324
325 START_TEST(test_multiple_references) {
326 struct struct_simple source_simple = {
327 .a1 = 451,
328 .a2 = 451424,
329 .a3 = 'o',
330 .a4 = 74,
331 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
332 };
333 struct struct_nestedpointers source_nested = {
334 .c3 = &source_simple,
335 .c4 = NULL,
336 };
337 struct struct_multipleref source = {
338 .f1 = 15,
339 .f2 = &source_simple,
340 .f3 = &source_simple,
341 .f4 = &source_nested,
342 };
343
344 struct struct_multipleref *destination;
345 void *buffer = NULL;
346 size_t len, len2;
347
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");
356 free(buffer);
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);
367 }
368 END_TEST
369
370 struct struct_circularref {
371 int g1;
372 struct struct_circularref* g2;
373 };
374 MARSHAL_BEGIN(struct_circularref)
375 MARSHAL_POINTER(struct_circularref, struct_circularref, g2)
376 MARSHAL_END(struct_circularref);
377
378 START_TEST(test_circular_references) {
379 struct struct_circularref source = {
380 .g1 = 42,
381 .g2 = &source,
382 };
383
384 struct struct_circularref *destination;
385 void *buffer = NULL;
386 size_t len, len2;
387
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");
393 free(buffer);
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);
398 free(destination);
399 }
400 END_TEST
401
402 START_TEST(test_too_small_unmarshal) {
403 struct struct_simple source_simple1;
404 struct struct_onepointer source_onepointer = {
405 .b4 = &source_simple1,
406 };
407 struct struct_nestedpointers source = {
408 .c3 = &source_simple1,
409 .c4 = &source_onepointer,
410 };
411
412 struct struct_nestedpointers *destination;
413 void *buffer;
414 size_t len, len2;
415 int i, j;
416
417 log_register(donothing);
418
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)",
430 i, len);
431 }
432 }
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);
437
438 log_register(NULL);
439 }
440 END_TEST
441
442 struct struct_simpleentry {
443 TAILQ_ENTRY(struct_simpleentry) s_entries;
444 int g1;
445 struct struct_simple *g2;
446 };
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);
451
452 TAILQ_HEAD(list_simple, struct_simpleentry);
453 MARSHAL_TQ(list_simple, struct_simpleentry);
454
455 START_TEST(test_simple_list) {
456 struct struct_simple source_simple = {
457 .a1 = 451,
458 .a2 = 451424,
459 .a3 = 'o',
460 .a4 = 74,
461 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
462 };
463 struct list_simple source;
464 struct struct_simpleentry entry1 = {
465 .g1 = 47,
466 .g2 = &source_simple,
467 };
468 struct struct_simpleentry entry2 = {
469 .g1 = 49,
470 .g2 = &source_simple,
471 };
472 struct struct_simpleentry entry3 = {
473 .g1 = 4700,
474 .g2 = NULL,
475 };
476 struct struct_simpleentry entry4 = {
477 .g1 = -47,
478 .g2 = &source_simple,
479 };
480 struct list_simple *destination;
481 void *buffer;
482 size_t len, len2;
483 struct struct_simpleentry *e1, *e2;
484 struct struct_simple *s;
485
486 TAILQ_INIT(&source);
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);
491
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");
501 free(buffer);
502
503 e1 = TAILQ_FIRST(destination);
504 ck_assert_int_eq(e1->g1, 47);
505 s = e1->g2;
506 e2 = TAILQ_NEXT(e1, s_entries);
507 free(e1);
508 ck_assert_int_eq(e2->g1, 49);
509 ck_assert_ptr_eq(e2->g2, s);
510 e1 = TAILQ_NEXT(e2, s_entries);
511 free(e2);
512 ck_assert_int_eq(e1->g1, 4700);
513 ck_assert_ptr_eq(e1->g2, NULL);
514 e2 = TAILQ_NEXT(e1, s_entries);
515 free(e1);
516 ck_assert_int_eq(e2->g1, -47);
517 ck_assert_ptr_eq(e2->g2, s);
518 e1 = TAILQ_NEXT(e2, s_entries);
519 free(e2);
520 ck_assert_ptr_eq(e1, NULL);
521 free(s);
522 free(destination);
523 }
524 END_TEST
525
526 START_TEST(test_simple_repaired_list) {
527 struct struct_simple source_simple = {
528 .a1 = 451,
529 .a2 = 451424,
530 .a3 = 'o',
531 .a4 = 74,
532 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
533 };
534 struct list_simple source;
535 struct struct_simpleentry entry1 = {
536 .g1 = 47,
537 .g2 = &source_simple,
538 };
539 struct struct_simpleentry entry2 = {
540 .g1 = 49,
541 .g2 = &source_simple,
542 };
543 struct struct_simpleentry entry3 = {
544 .g1 = 4700,
545 .g2 = NULL,
546 };
547 struct struct_simpleentry entry4 = {
548 .g1 = -47,
549 .g2 = &source_simple,
550 };
551 struct struct_simpleentry entry5 = {
552 .g1 = -1000,
553 .g2 = NULL,
554 };
555 struct list_simple *destination;
556 void *buffer;
557 size_t len, len2;
558 struct struct_simpleentry *e1, *e2, *e3, *e4;
559
560 TAILQ_INIT(&source);
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);
565
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");
575 free(buffer);
576
577 marshal_repair_tailq(struct_simpleentry, destination, s_entries);
578
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);
587
588 TAILQ_INSERT_TAIL(destination, &entry5, s_entries);
589 free(e1->g2);
590 free(e1);
591 free(e2);
592 free(e3);
593 free(e4);
594 free(destination);
595 }
596 END_TEST
597
598 START_TEST(test_empty_repaired_list) {
599 struct list_simple source;
600 size_t len, len2;
601 struct list_simple *destination;
602 void *buffer;
603 struct struct_simpleentry *e1;
604 struct struct_simpleentry entry5 = {
605 .g1 = -1000,
606 .g2 = NULL,
607 };
608 TAILQ_INIT(&source);
609
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");
615 free(buffer);
616
617 marshal_repair_tailq(struct_simpleentry, destination, s_entries);
618
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);
623
624 TAILQ_INSERT_TAIL(destination, &entry5, s_entries);
625
626 free(destination);
627 }
628 END_TEST
629
630 struct struct_withlist {
631 int i1;
632 TAILQ_HEAD(, struct_simpleentry) i2;
633 int i3;
634 };
635 MARSHAL_BEGIN(struct_withlist)
636 MARSHAL_SUBTQ(struct_withlist, struct_simpleentry, i2)
637 MARSHAL_END(struct_withlist);
638
639 START_TEST(test_embedded_list) {
640 struct struct_withlist source = {
641 .i1 = 45424,
642 .i3 = 4542,
643 };
644 struct struct_simple source_simple = {
645 .a1 = 451,
646 .a2 = 451424,
647 .a3 = 'o',
648 .a4 = 74,
649 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
650 };
651 struct struct_simpleentry entry1 = {
652 .g1 = 47,
653 .g2 = &source_simple,
654 };
655 struct struct_simpleentry entry2 = {
656 .g1 = 49,
657 .g2 = &source_simple,
658 };
659 struct struct_simpleentry entry3 = {
660 .g1 = 4700,
661 .g2 = NULL,
662 };
663 struct struct_simpleentry entry4 = {
664 .g1 = -47,
665 .g2 = &source_simple,
666 };
667 struct struct_withlist *destination;
668 void *buffer;
669 size_t len, len2;
670 struct struct_simpleentry *e1, *e2;
671 struct struct_simple *s;
672
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);
678
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");
688 free(buffer);
689
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);
695 s = e1->g2;
696 e2 = TAILQ_NEXT(e1, s_entries);
697 free(e1);
698 ck_assert_int_eq(e2->g1, 49);
699 ck_assert_ptr_eq(e2->g2, s);
700 e1 = TAILQ_NEXT(e2, s_entries);
701 free(e2);
702 ck_assert_int_eq(e1->g1, 4700);
703 ck_assert_ptr_eq(e1->g2, NULL);
704 e2 = TAILQ_NEXT(e1, s_entries);
705 free(e1);
706 ck_assert_int_eq(e2->g1, -47);
707 ck_assert_ptr_eq(e2->g2, s);
708 e1 = TAILQ_NEXT(e2, s_entries);
709 free(e2);
710 ck_assert_ptr_eq(e1, NULL);
711 free(s);
712 free(destination);
713 }
714 END_TEST
715
716 struct struct_string {
717 int s1;
718 char *s2;
719 char *s3;
720 };
721 MARSHAL_BEGIN(struct_string)
722 MARSHAL_STR(struct_string, s2)
723 MARSHAL_STR(struct_string, s3)
724 MARSHAL_END(struct_string);
725
726 START_TEST(test_string) {
727 struct struct_string source = {
728 .s1 = 44444,
729 .s2 = "String 2",
730 .s3 = "String 3",
731 };
732 struct struct_string *destination;
733 void *buffer;
734 size_t len, len2;
735
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");
741 free(buffer);
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);
747 free(destination);
748 }
749 END_TEST
750
751 struct struct_fixedstring {
752 int s1;
753 char *s2;
754 int s2_len;
755 char *s3;
756 };
757 MARSHAL_BEGIN(struct_fixedstring)
758 MARSHAL_FSTR(struct_fixedstring, s2, s2_len)
759 MARSHAL_STR(struct_fixedstring, s3)
760 MARSHAL_END(struct_fixedstring);
761
762 START_TEST(test_fixed_string) {
763 struct struct_fixedstring source = {
764 .s1 = 44444,
765 .s2 = "String 2 Bla",
766 .s2_len = 8, /* Not 12! */
767 .s3 = "String 3",
768 };
769 struct struct_fixedstring *destination;
770 void *buffer;
771 size_t len, len2;
772
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");
778 free(buffer);
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);
791 free(destination);
792 }
793 END_TEST
794
795 struct struct_ignore {
796 int t1;
797 void *t2;
798 int t3;
799 };
800 MARSHAL_BEGIN(struct_ignore)
801 MARSHAL_IGNORE(struct_ignore, t2)
802 MARSHAL_END(struct_ignore);
803
804 START_TEST(test_ignore) {
805 struct struct_ignore source = {
806 .t1 = 4544,
807 .t2 = (void *)"String 2 Bla",
808 .t3 = 11111,
809 };
810 struct struct_ignore *destination;
811 void *buffer;
812 size_t len, len2;
813
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");
819 free(buffer);
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);
824 free(destination);
825 }
826 END_TEST
827
828 START_TEST(test_equality) {
829 struct struct_simple source_simple1 = {
830 .a1 = 451,
831 .a2 = 451424,
832 .a3 = 'o',
833 .a4 = 74,
834 .a5 = { 'a', 'b', 'c', 'd', 'e', 'f', 'g'},
835 };
836 struct struct_simpleentry entry1 = {
837 .g1 = 47,
838 .g2 = &source_simple1,
839 };
840
841 struct struct_simple source_simple2;
842 struct struct_simpleentry entry2;
843
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);
855 }
856 END_TEST
857
858 Suite *
859 marshal_suite(void)
860 {
861 Suite *s = suite_create("Marshalling");
862
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);
881
882 return s;
883 }
884
885 int
886 main()
887 {
888 int number_failed;
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);
893 srunner_free(sr);
894 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
895 }