tizen 2.3 release
[external/buxton.git] / test / check_shared_lib.c
1 /*
2  * This file is part of buxton.
3  *
4  * Copyright (C) 2013 Intel Corporation
5  *
6  * buxton is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1
9  * of the License, or (at your option) any later version.
10  */
11
12 #ifdef HAVE_CONFIG_H
13         #include "config.h"
14 #endif
15
16 #include <check.h>
17 #include <fcntl.h>
18 #include <malloc.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <limits.h>
24
25 #include "backend.h"
26 #include "buxtonlist.h"
27 #include "check_utils.h"
28 #include "hashmap.h"
29 #include "log.h"
30 #include "serialize.h"
31 #include "smack.h"
32 #include "util.h"
33 #include "configurator.h"
34
35 #ifdef NDEBUG
36 #error "re-run configure with --enable-debug"
37 #endif
38
39 START_TEST(log_write_check)
40 {
41         char log_file[] = "log-check-stderr-file";
42         char log_msg[] = "Log test";
43         _cleanup_free_ char *log_read = malloc(strlen(log_msg));
44         fail_if(log_read == NULL,
45                 "Failed to allocate space for reading the log");
46
47         int old_stderr = fileno(stderr);
48         fail_if(old_stderr == -1, "Failed to get fileno for stderr");
49
50         int dup_stderr = dup(old_stderr);
51         fail_if(dup_stderr == -1, "Failed to dup stderr");
52
53         FILE *new_stderr = freopen(log_file, "w", stderr);
54         fail_if(new_stderr == NULL, "Failed to reopen stderr");
55
56         buxton_log(log_msg);
57         fail_if(fflush(stderr) != 0, "Failed to flush stderr");
58
59         FILE *read_test = fopen(log_file, "r");
60         fail_if(read_test == NULL, "Failed to open stderr file for reading");
61
62         size_t len = fread(log_read, 1, strlen(log_msg), read_test);
63         fail_if(len != strlen(log_msg), "Failed to read entire log message");
64         fail_if(strncmp(log_msg, log_read, strlen(log_msg)) != 0,
65                 "Failed to write log message correctly");
66
67         fclose(stderr);
68         fclose(read_test);
69         stderr = fdopen(dup_stderr, "w");
70 }
71 END_TEST
72
73
74 START_TEST(hashmap_check)
75 {
76         Hashmap *map;
77         char *value;
78         int r;
79
80         map = hashmap_new(string_hash_func, string_compare_func);
81         fail_if(map == NULL, "Failed to allocated hashmap");
82         r = hashmap_put(map, "test", "passed");
83         fail_if(r < 0, "Failed to add element to hashmap");
84
85         value = hashmap_get(map, "test");
86
87         fail_if(value == NULL,
88                 "Failed to get value from hashmap");
89
90         fail_if(strcmp(value, "passed") != 0,
91                 "Failed to retrieve the put value");
92
93         hashmap_remove(map, "test");
94         fail_if(hashmap_isempty(map) != true,
95                 "Failed to remove item from hashmap");
96
97         hashmap_free(map);
98 }
99 END_TEST
100
101 static inline void array_free_fun(void *p)
102 {
103         free(p);
104 }
105
106 START_TEST(array_check)
107 {
108         BuxtonArray *array = NULL;
109         char *value;
110         char *element;
111         void *f;
112         bool r;
113
114         array = buxton_array_new();
115         fail_if(array == NULL, "Failed to allocate memory for BuxtonArray");
116         element = strdup("test");
117         fail_if(!element, "Failed to allocate memory for array item");
118         r = buxton_array_add(NULL, element);
119         fail_if(r, "Added element to NULL array");
120         r = buxton_array_add(array, NULL);
121         fail_if(r, "Added NULL element to array");
122         r = buxton_array_add(array, element);
123         fail_if(r  == false, "Failed to add element to BuxtonArray");
124         fail_if(array->len != 1,
125                 "Failed to get correct value for number of elements in array");
126
127         f = buxton_array_get(NULL, 0);
128         fail_if(f, "Got value from NULL array");
129         f = buxton_array_get(array, (uint16_t)(array->len + 1));
130         fail_if(f, "Got value from index bigger than maximum index");
131         value = (char *)buxton_array_get(array, 0);
132
133         fail_if(value == NULL,
134                 "Failed to get value from BuxtonArray");
135
136         fail_if(strcmp(value, "test") != 0,
137                 "Failed to retrieve the stored value");
138
139         buxton_array_free(&array, array_free_fun);
140         fail_if(array != NULL,
141                 "Failed to free BuxtonArray");
142 }
143 END_TEST
144
145 START_TEST(list_check)
146 {
147         BuxtonList *list = NULL;
148         int i;
149         char *tmp = NULL;
150         char *head = "<head of the list>";
151         char *head2 = "<prepend should appear before head now>";
152         char *data = "<middle element to be removed>";
153
154         /* Append a million strings. Results in about 3 million allocs
155          * due to asprintf, calloc of node, etc */
156         int DEFAULT_SIZE = (10*1000)*100;
157         for (i = 0; i <= DEFAULT_SIZE; i++) {
158                 if (i == 5) {
159                         fail_if(buxton_list_append(&list, data) == false,
160                                 "Failed to append to BuxtonList");
161                 } else {
162                         asprintf(&tmp, "i #%d", i);
163                         fail_if(buxton_list_prepend(&list, tmp) == false,
164                                 "Failed to prepend to BuxtonList");
165                 }
166         }
167
168         fail_if(list->size != DEFAULT_SIZE, "List size invalid");
169
170         /* Prepend head */
171         fail_if(buxton_list_prepend(&list, head) != true, "Prepend head failed");
172         fail_if(list->size != DEFAULT_SIZE+1, "Prepended head size invalid");
173
174         /* Prepend head2 */
175         fail_if(buxton_list_prepend(&list, head2) != true, "Prepend head2 failed");
176         fail_if(list->size != DEFAULT_SIZE+2, "Prepended head2 size invalid");
177
178         /* Remove from middle */
179         fail_if(buxton_list_remove(&list, data, false) != true,
180                 "List removal from middle failed");
181         fail_if(list->size != DEFAULT_SIZE+1, "List middle removal size invalid");
182
183         /* Remove from end */
184         fail_if(buxton_list_remove(&list, tmp, true) != true,
185                 "List tail removal failed");
186         fail_if(list->size != DEFAULT_SIZE, "List tail removal size invalid");
187
188         fail_if(buxton_list_append(&list, "newend") != true,
189                 "List new tail append failed");
190         fail_if(list->size != DEFAULT_SIZE+1, "List new tail size invalid");
191         fail_if(buxton_list_remove(&list, "newend", false) != true,
192                 "List new tail removal failed");
193         fail_if(list->size != DEFAULT_SIZE,
194                 "List new tail size invalid (post removal)");
195
196         /* Fake remove */
197         fail_if(buxton_list_remove(&list, "nonexistent", false) == true,
198                 "List non existent removal should fail");
199         fail_if(list->size != DEFAULT_SIZE,
200                 "List size invalid after no change");
201
202         /* Remove head */
203         fail_if(buxton_list_remove(&list, head, false) == false,
204                 "List remove head failed");
205         fail_if(buxton_list_remove(&list, head2, false) == false,
206                 "List remove head2 failed");
207         fail_if(list->size != DEFAULT_SIZE-2,
208                 "List post heads removal size invalid");
209
210         buxton_list_free_all(&list);
211 }
212 END_TEST
213
214 START_TEST(get_layer_path_check)
215 {
216         BuxtonLayer layer;
217         char *path = NULL;
218         char *real_path = NULL;
219         int r;
220
221         memzero(&layer, sizeof(BuxtonLayer));
222         layer.name = buxton_string_pack("path-test");
223         layer.type = LAYER_SYSTEM;
224         r = asprintf(&real_path, "%s/%s", buxton_db_path(), "path-test.db");
225         fail_if(r == -1, "Failed to set real path for system layer");
226
227         path = get_layer_path(&layer);
228         fail_if(path == NULL, "Failed to get path for system layer");
229         fail_if(strcmp(path, real_path) != 0,
230                 "Failed to set correct system path");
231
232         free(path);
233         free(real_path);
234
235         layer.name = buxton_string_pack("user-path-test");
236         layer.type = LAYER_USER;
237         layer.uid = 1000;
238         r = asprintf(&real_path, "%s/%s", buxton_db_path(), "user-path-test-1000.db");
239         fail_if(r == -1, "Failed to set real path for user layer");
240
241         path = get_layer_path(&layer);
242         fail_if(path == NULL, "Failed to get path for user layer");
243         fail_if(strcmp(path, real_path) != 0,
244                 "Failed to set correct user path");
245
246         free(path);
247         free(real_path);
248
249         layer.name = buxton_string_pack("bad-type-test");
250         layer.type = -1;
251         fail_if(get_layer_path(&layer) != NULL,
252                 "Invalid layer type didn't return failure");
253 }
254 END_TEST
255
256 START_TEST(buxton_data_copy_check)
257 {
258         BuxtonData original, copy;
259
260         original.type = STRING;
261         original.store.d_string = buxton_string_pack("test-data-copy");
262         buxton_data_copy(&original, &copy);
263         fail_if(copy.type != original.type,
264                 "Failed to copy string type");
265         fail_if(!copy.store.d_string.value, "Failed to copy string data");
266         fail_if((strcmp(original.store.d_string.value, copy.store.d_string.value) != 0),
267                 "Incorrectly copied string data");
268         if (copy.store.d_string.value)
269                 free(copy.store.d_string.value);
270
271         original.type = INT32;
272         original.store.d_int32 = INT_MAX;
273         buxton_data_copy(&original, &copy);
274         fail_if(copy.type != original.type,
275                 "Failed to copy int32 type");
276         fail_if(original.store.d_int32 != copy.store.d_int32,
277                 "Failed to copy int32 data");
278
279         original.type = UINT32;
280         original.store.d_uint32 = UINT_MAX;
281         buxton_data_copy(&original, &copy);
282         fail_if(copy.type != original.type,
283                 "Failed to copy uint32 type");
284         fail_if(original.store.d_uint32 != copy.store.d_uint32,
285                 "Failed to copy int32 data");
286
287         original.type = INT64;
288         original.store.d_int64 = LLONG_MAX;
289         buxton_data_copy(&original, &copy);
290         fail_if(copy.type != original.type,
291                 "Failed to copy int64 type");
292         fail_if(original.store.d_int64 != copy.store.d_int64,
293                 "Failed to copy int64 data");
294
295         original.type = UINT64;
296         original.store.d_uint64 = ULLONG_MAX;
297         buxton_data_copy(&original, &copy);
298         fail_if(copy.type != original.type,
299                 "Failed to copy uint64 type");
300         fail_if(original.store.d_uint64 != copy.store.d_uint64,
301                 "Failed to copy uint64 data");
302
303         original.type = FLOAT;
304         original.store.d_float = 3.14F;
305         buxton_data_copy(&original, &copy);
306         fail_if(copy.type != original.type,
307                 "Failed to copy float type");
308         fail_if(original.store.d_float != copy.store.d_float,
309                 "Failed to copy float data");
310
311         original.type = DOUBLE;
312         original.store.d_double = 3.1415;
313         buxton_data_copy(&original, &copy);
314         fail_if(copy.type != original.type,
315                 "Failed to copy double type");
316         fail_if(original.store.d_double != copy.store.d_double,
317                 "Failed to copy double data");
318
319         original.type = BOOLEAN;
320         original.store.d_boolean = true;
321         buxton_data_copy(&original, &copy);
322         fail_if(copy.type != original.type,
323                 "Failed to copy boolean type");
324         fail_if(original.store.d_boolean != copy.store.d_boolean,
325                 "Failed to copy boolean data");
326
327         original.type = -1;
328         buxton_data_copy(&original, &copy);
329         fail_if(copy.type || copy.store.d_string.value, "Copied invalid data");
330 }
331 END_TEST
332
333 START_TEST(buxton_type_as_string_check)
334 {
335         BuxtonDataType type;
336
337         type = STRING;
338         fail_if(strcmp(buxton_type_as_string(type), "string") != 0,
339                 "Failed to get string of STRING type");
340
341         type = INT32;
342         fail_if(strcmp(buxton_type_as_string(type), "int32_t") != 0,
343                 "Failed to get string of INT32 type");
344
345         type = UINT32;
346         fail_if(strcmp(buxton_type_as_string(type), "uint32_t") != 0,
347                 "Failed to get string of UINT32 type");
348
349         type = INT64;
350         fail_if(strcmp(buxton_type_as_string(type), "int64_t") != 0,
351                 "Failed to get string of INT64 type");
352
353         type = UINT64;
354         fail_if(strcmp(buxton_type_as_string(type), "uint64_t") != 0,
355                 "Failed to get string of UINT64 type");
356
357         type = FLOAT;
358         fail_if(strcmp(buxton_type_as_string(type), "float") != 0,
359                 "Failed to get string of FLOAT type");
360
361         type = DOUBLE;
362         fail_if(strcmp(buxton_type_as_string(type), "double") != 0,
363                 "Failed to get string of DOUBLE type");
364
365         type = BOOLEAN;
366         fail_if(strcmp(buxton_type_as_string(type), "boolean") != 0,
367                 "Failed to get string of BOOLEAN type");
368 }
369 END_TEST
370
371 START_TEST(_write_check)
372 {
373         int in, out;
374         uint8_t buf[10];
375
376         setup_socket_pair(&in, &out);
377         fail_if(fcntl(in, F_SETFL, O_NONBLOCK),
378                 "Failed to set socket to non blocking");
379         fail_if(fcntl(out, F_SETFL, O_NONBLOCK),
380                 "Failed to set socket to non blocking");
381
382         buf[0] = 1;
383         fail_if(!_write(out, buf, 1), "Failed to write 1 byte");
384 }
385 END_TEST
386
387 START_TEST(buxton_db_serialize_check)
388 {
389         BuxtonData dsource, dtarget;
390         uint8_t *packed = NULL;
391         BuxtonString lsource, ltarget;
392
393         dsource.type = STRING;
394         lsource = buxton_string_pack("label");
395         dsource.store.d_string = buxton_string_pack("test-string");
396         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
397                 "Failed to serialize string data");
398         buxton_deserialize(packed, &dtarget, &ltarget);
399         fail_if(dsource.type != dtarget.type,
400                 "Source and destination type differ for string");
401         fail_if(strcmp(lsource.value, ltarget.value) != 0,
402                 "Source and destination string labels differ");
403         fail_if(strcmp(dsource.store.d_string.value, dtarget.store.d_string.value) != 0,
404                 "Source and destination string data differ");
405         free(packed);
406         free(ltarget.value);
407         if (dtarget.store.d_string.value)
408                 free(dtarget.store.d_string.value);
409
410         dsource.type = INT32;
411         dsource.store.d_int32 = INT_MAX;
412         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
413                 "Failed to serialize int32 data");
414         buxton_deserialize(packed, &dtarget, &ltarget);
415         fail_if(dsource.type != dtarget.type,
416                 "Source and destination type differ for int32");
417         fail_if(strcmp(lsource.value, ltarget.value) != 0,
418                 "Source and destination int32 labels differ");
419         fail_if(dsource.store.d_int32 != dtarget.store.d_int32,
420                 "Source and destination int32 data differ");
421         free(ltarget.value);
422         free(packed);
423
424         dsource.type = UINT32;
425         dsource.store.d_uint32 = UINT_MAX;
426         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
427                 "Failed to serialize uint32 data");
428         buxton_deserialize(packed, &dtarget, &ltarget);
429         fail_if(dsource.type != dtarget.type,
430                 "Source and destination type differ for uint32");
431         fail_if(strcmp(lsource.value, ltarget.value) != 0,
432                 "Source and destination uint32 labels differ");
433         fail_if(dsource.store.d_uint32 != dtarget.store.d_uint32,
434                 "Source and destination uint32 data differ");
435         free(ltarget.value);
436         free(packed);
437
438         dsource.type = INT64;
439         dsource.store.d_int64 = LONG_MAX;
440         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
441                 "Failed to serialize int64 data");
442         buxton_deserialize(packed, &dtarget, &ltarget);
443         fail_if(dsource.type != dtarget.type,
444                 "Source and destination type differ for int64");
445         fail_if(strcmp(lsource.value, ltarget.value) != 0,
446                 "Source and destination int64 labels differ");
447         fail_if(dsource.store.d_int64 != dtarget.store.d_int64,
448                 "Source and destination int64 data differ");
449         free(ltarget.value);
450         free(packed);
451
452         dsource.type = UINT64;
453         dsource.store.d_uint64 = ULLONG_MAX;
454         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
455                 "Failed to serialize uint64 data");
456         buxton_deserialize(packed, &dtarget, &ltarget);
457         fail_if(dsource.type != dtarget.type,
458                 "Source and destination type differ for uint64");
459         fail_if(strcmp(lsource.value, ltarget.value) != 0,
460                 "Source and destination uint64 labels differ");
461         fail_if(dsource.store.d_uint64 != dtarget.store.d_uint64,
462                 "Source and destination uint64 data differ");
463         free(ltarget.value);
464         free(packed);
465
466         dsource.type = FLOAT;
467         dsource.store.d_float = 3.14F;
468         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
469                 "Failed to serialize float data");
470         buxton_deserialize(packed, &dtarget, &ltarget);
471         fail_if(dsource.type != dtarget.type,
472                 "Source and destination type differ for float");
473         fail_if(strcmp(lsource.value, ltarget.value) != 0,
474                 "Source and destination float labels differ");
475         fail_if(dsource.store.d_float != dtarget.store.d_float,
476                 "Source and destination float data differ");
477         free(ltarget.value);
478         free(packed);
479
480         dsource.type = DOUBLE;
481         dsource.store.d_double = 3.1415;
482         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
483                 "Failed to serialize double data");
484         buxton_deserialize(packed, &dtarget, &ltarget);
485         fail_if(dsource.type != dtarget.type,
486                 "Source and destination type differ for double");
487         fail_if(strcmp(lsource.value, ltarget.value) != 0,
488                 "Source and destination double labels differ");
489         fail_if(dsource.store.d_double != dtarget.store.d_double,
490                 "Source and destination double data differ");
491         free(ltarget.value);
492         free(packed);
493
494         dsource.type = BOOLEAN;
495         dsource.store.d_boolean = true;
496         fail_if(buxton_serialize(&dsource, &lsource, &packed) == false,
497                 "Failed to serialize boolean data");
498         buxton_deserialize(packed, &dtarget, &ltarget);
499         fail_if(dsource.type != dtarget.type,
500                 "Source and destination type differ for boolean");
501         fail_if(strcmp(lsource.value, ltarget.value) != 0,
502                 "Source and destination boolean labels differ");
503         free(ltarget.value);
504         free(packed);
505 }
506 END_TEST
507
508 START_TEST(buxton_message_serialize_check)
509 {
510         BuxtonControlMessage csource;
511         BuxtonControlMessage ctarget;
512         BuxtonData dsource1, dsource2;
513         uint16_t control, message;
514         BuxtonData *dtarget = NULL;
515         uint8_t *packed = NULL;
516         BuxtonArray *list = NULL;
517         BuxtonArray *list2 = NULL;
518         size_t ret;
519         size_t pcount;
520         bool r;
521         uint32_t msource;
522         uint32_t mtarget;
523
524         list = buxton_array_new();
525         fail_if(!list, "Failed to allocate list");
526         dsource1.type = STRING;
527         dsource1.store.d_string = buxton_string_pack("test-key");
528         csource = BUXTON_CONTROL_GET;
529         msource = 0;
530         r = buxton_array_add(list, &dsource1);
531         fail_if(!r, "Failed to add element to array");
532         ret = buxton_serialize_message(&packed, csource, msource, list);
533         fail_if(ret == 0, "Failed to serialize string data");
534         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
535                                            &dtarget) != 1,
536                 "Failed to deserialize string data");
537         fail_if(ctarget != csource, "Failed to get correct control message for string");
538         fail_if(mtarget != msource,
539                 "Failed to get correct message id for string");
540         fail_if(dsource1.type != dtarget[0].type,
541                 "Source and destination type differ for string");
542         fail_if(strcmp(dsource1.store.d_string.value, dtarget[0].store.d_string.value) != 0,
543                 "Source and destination string data differ");
544         free(packed);
545         if (dtarget) {
546                 if (dtarget[0].store.d_string.value) {
547                         free(dtarget[0].store.d_string.value);
548                 }
549                 free(dtarget);
550         }
551
552         dsource1.type = INT32;
553         dsource1.store.d_int32 = INT_MAX;
554         csource = BUXTON_CONTROL_GET;
555         ret = buxton_serialize_message(&packed, csource, msource, list);
556         fail_if(ret == 0, "Failed to serialize int32 data");
557         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
558                                            &dtarget) != 1,
559                 "Failed to deserialize int data");
560         fail_if(ctarget != csource, "Failed to get correct control message for int32");
561         fail_if(mtarget != msource,
562                 "Failed to get correct message id for int32");
563         fail_if(dsource1.type != dtarget[0].type,
564                 "Source and destination type differ for int32");
565         fail_if(dsource1.store.d_int32 != dtarget[0].store.d_int32,
566                 "Source and destination int32 data differ");
567         free(packed);
568         free(dtarget);
569
570         dsource1.type = UINT32;
571         dsource1.store.d_uint32 = UINT_MAX;
572         csource = BUXTON_CONTROL_GET;
573         ret = buxton_serialize_message(&packed, csource, msource, list);
574         fail_if(ret == 0, "Failed to serialize uint32 data");
575         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
576                                            &dtarget) != 1,
577                 "Failed to deserialize uint32 data");
578         fail_if(ctarget != csource, "Failed to get correct control message for uint32");
579         fail_if(mtarget != msource,
580                 "Failed to get correct message id for uint32");
581         fail_if(dsource1.type != dtarget[0].type,
582                 "Source and destination type differ for uint32");
583         fail_if(dsource1.store.d_uint32 != dtarget[0].store.d_uint32,
584                 "Source and destination uint32 data differ");
585         free(packed);
586         free(dtarget);
587
588         dsource1.type = INT64;
589         dsource1.store.d_int64 = LONG_MAX;
590         csource = BUXTON_CONTROL_GET;
591         ret = buxton_serialize_message(&packed, csource, msource, list);
592         fail_if(ret == 0, "Failed to serialize long data");
593         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
594                                            &dtarget) != 1,
595                 "Failed to deserialize long data");
596         fail_if(ctarget != csource, "Failed to get correct control message for long");
597         fail_if(mtarget != msource,
598                 "Failed to get correct message id for long");
599         fail_if(dsource1.type != dtarget[0].type,
600                 "Source and destination type differ for long");
601         fail_if(dsource1.store.d_int64 != dtarget[0].store.d_int64,
602                 "Source and destination long data differ");
603         free(packed);
604         free(dtarget);
605
606         dsource1.type = UINT64;
607         dsource1.store.d_uint64 = ULLONG_MAX;
608         csource = BUXTON_CONTROL_GET;
609         ret = buxton_serialize_message(&packed, csource, msource, list);
610         fail_if(ret == 0, "Failed to serialize uint64 data");
611         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
612                                            &dtarget) != 1,
613                 "Failed to deserialize uint64 data");
614         fail_if(ctarget != csource, "Failed to get correct control message for uint64");
615         fail_if(mtarget != msource,
616                 "Failed to get correct message id for uint64");
617         fail_if(dsource1.type != dtarget[0].type,
618                 "Source and destination type differ for uint64");
619         fail_if(dsource1.store.d_uint64 != dtarget[0].store.d_uint64,
620                 "Source and destination uint64 data differ");
621         free(packed);
622         free(dtarget);
623
624         dsource1.type = FLOAT;
625         dsource1.store.d_float = 3.14F;
626         csource = BUXTON_CONTROL_GET;
627         ret = buxton_serialize_message(&packed, csource, msource, list);
628         fail_if(ret == 0, "Failed to serialize float data");
629         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
630                                            &dtarget) != 1,
631                 "Failed to deserialize float data");
632         fail_if(ctarget != csource, "Failed to get correct control message for float");
633         fail_if(mtarget != msource,
634                 "Failed to get correct message id for float");
635         fail_if(dsource1.type != dtarget[0].type,
636                 "Source and destination type differ for float");
637         fail_if(dsource1.store.d_float != dtarget[0].store.d_float,
638                 "Source and destination float data differ");
639         free(packed);
640         free(dtarget);
641
642         dsource1.type = DOUBLE;
643         dsource1.store.d_double = 3.1415;
644         csource = BUXTON_CONTROL_GET;
645         ret = buxton_serialize_message(&packed, csource, msource, list);
646         fail_if(ret == 0, "Failed to serialize double data");
647         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
648                                            &dtarget) != 1,
649                 "Failed to deserialize double data");
650         fail_if(ctarget != csource, "Failed to get correct control message for double");
651         fail_if(mtarget != msource,
652                 "Failed to get correct message id for double");
653         fail_if(dsource1.type != dtarget[0].type,
654                 "Source and destination type differ for double");
655         fail_if(dsource1.store.d_double != dtarget[0].store.d_double,
656                 "Source and destination double data differ");
657         free(packed);
658         free(dtarget);
659
660         dsource1.type = BOOLEAN;
661         dsource1.store.d_boolean = true;
662         csource = BUXTON_CONTROL_GET;
663         ret = buxton_serialize_message(&packed, csource, msource, list);
664         fail_if(ret == 0, "Failed to serialize boolean data");
665         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
666                                            &dtarget) != 1,
667                 "Failed to deserialize boolean data");
668         fail_if(ctarget != csource, "Failed to get correct control message for boolean");
669         fail_if(mtarget != msource,
670                 "Failed to get correct message id for boolean");
671         fail_if(dsource1.type != dtarget[0].type,
672                 "Source and destination type differ for boolean");
673         fail_if(dsource1.store.d_boolean != dtarget[0].store.d_boolean,
674                 "Source and destination boolean data differ");
675         free(packed);
676         free(dtarget);
677
678         dsource1.type = INT32;
679         dsource1.store.d_int32 = 1;
680         dsource2.type = INT32;
681         dsource2.store.d_int32 = 2;
682         csource = BUXTON_CONTROL_STATUS;
683         r = buxton_array_add(list, &dsource2);
684         fail_if(!r, "Failed to add element to array");
685         ret = buxton_serialize_message(&packed, csource, msource, list);
686         fail_if(ret == 0, "Failed to serialize 2arg data");
687         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
688                                            &dtarget) != 2,
689                 "Failed to deserialize 2arg data");
690         fail_if(ctarget != csource, "Failed to get correct control message for 2arg");
691         fail_if(mtarget != msource,
692                 "Failed to get correct message id for 2arg");
693         fail_if(dsource1.type != dtarget[0].type,
694                 "1 Source and destination type differ for 2arg");
695         fail_if(dsource1.store.d_int32 != dtarget[0].store.d_int32,
696                 "1 Source and destination differ for 2arg data");
697         fail_if(dsource2.type != dtarget[1].type,
698                 "2 Source and destination type differ for 2arg");
699         fail_if(dsource2.store.d_int32 != dtarget[1].store.d_int32,
700                 "2 Source and destination differ for 2arg data");
701         free(packed);
702         free(dtarget);
703
704         list2 = buxton_array_new();
705         fail_if(!list, "Failed to allocate list");
706         list2->len = 0;
707         dsource1.type = STRING;
708         dsource1.store.d_string = buxton_string_pack("test-key");
709         csource = BUXTON_CONTROL_GET;
710         ret = buxton_serialize_message(&packed, csource, msource, list2);
711         fail_if(ret == 0, "Unable to serialize with 0 element list");
712
713         list2->len = BUXTON_MESSAGE_MAX_PARAMS + 1;
714         ret = buxton_serialize_message(&packed, csource, msource, list2);
715         fail_if(ret != 0, "Serialized with too many parameters");
716
717         list2->len = 0;
718         r = buxton_array_add(list2, &dsource1);
719         fail_if(!r, "Failed to add element to array");
720         list2->len = 2;
721         ret = buxton_serialize_message(&packed, csource, msource, list2);
722         fail_if(ret != 0, "Serialized with incorrect parameter count");
723         list2->len = 0;
724
725         dsource1.type = -1;
726         dsource1.store.d_string = buxton_string_pack("test-key");
727         csource = BUXTON_CONTROL_GET;
728         ret = buxton_serialize_message(&packed, csource, msource, list);
729         fail_if(ret != 0, "Serialized with bad data type");
730
731         dsource1.type = STRING;
732         dsource1.store.d_string = buxton_string_pack("test-key");
733         csource = -1;
734         ret = buxton_serialize_message(&packed, csource, msource, list);
735         fail_if(ret != 0, "Serialized with bad message type");
736
737         dsource1.type = INT32;
738         dsource1.store.d_int32 = INT_MAX;
739         csource = BUXTON_CONTROL_GET;
740         ret = buxton_serialize_message(&packed, csource, msource, list);
741         fail_if(buxton_deserialize_message(packed, &ctarget,
742                                            BUXTON_MESSAGE_HEADER_LENGTH - 1,
743                                            &mtarget, &dtarget) >= 0,
744                 "Deserialized message with too small a length data");
745
746         /* don't read past end of buffer check */
747         fail_if(buxton_deserialize_message(packed, &ctarget,
748                                            (sizeof(uint32_t) * 3)
749                                            + sizeof(uint32_t)
750                                            + sizeof(uint16_t)
751                                            + (sizeof(uint32_t) * 2),
752                                            &mtarget, &dtarget) >= 0,
753                 "Deserialized message size smaller than minimum data length");
754
755         control = 0x0000;
756         memcpy(packed, &control, sizeof(uint16_t));
757         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
758                                            &dtarget) >= 0,
759                 "Deserialized message with invalid control");
760         free(packed);
761
762         ret = buxton_serialize_message(&packed, csource, msource, list);
763         message = BUXTON_CONTROL_MIN;
764         memcpy(packed+sizeof(uint16_t), &message, sizeof(uint16_t));
765         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
766                                            &dtarget) >= 0,
767                 "Deserialized message with invalid control");
768         free(packed);
769
770         ret = buxton_serialize_message(&packed, csource, msource, list);
771         message = BUXTON_CONTROL_MAX;
772         memcpy(packed+sizeof(uint16_t), &message, sizeof(uint16_t));
773         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
774                                            &dtarget) >= 0,
775                 "Deserialized message with invalid control");
776         free(packed);
777
778         ret = buxton_serialize_message(&packed, csource, msource, list);
779         pcount = 0;
780         memcpy(packed+(2 * sizeof(uint32_t)+sizeof(uint32_t)), &pcount, sizeof(uint32_t));
781         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
782                                            &dtarget) < 0,
783                 "Unable to deserialize message with 0 BuxtonData");
784         free(packed);
785
786         ret = buxton_serialize_message(&packed, csource, msource, list);
787         pcount = BUXTON_MESSAGE_MAX_PARAMS + 1;
788         memcpy(packed+(2 * sizeof(uint32_t)+sizeof(uint32_t)), &pcount, sizeof(uint32_t));
789         fail_if(buxton_deserialize_message(packed, &ctarget, ret, &mtarget,
790                                            &dtarget) >= 0,
791                 "Unable to deserialize message with 0 BuxtonData");
792         free(packed);
793
794         buxton_array_free(&list, NULL);
795         buxton_array_free(&list2, NULL);
796 }
797 END_TEST
798
799 START_TEST(buxton_get_message_size_check)
800 {
801         BuxtonControlMessage csource;
802         BuxtonData dsource;
803         uint8_t *packed = NULL;
804         BuxtonArray *list = NULL;
805         size_t ret;
806         bool r;
807
808         list = buxton_array_new();
809         fail_if(!list, "Failed to allocate list");
810         dsource.type = STRING;
811         dsource.store.d_string = buxton_string_pack("test-key");
812         csource = BUXTON_CONTROL_GET;
813         r = buxton_array_add(list, &dsource);
814         fail_if(!r, "Failed to add element to array");
815         ret = buxton_serialize_message(&packed, csource, 0, list);
816         fail_if(ret == 0, "Failed to serialize string data for size");
817         fail_if(ret != buxton_get_message_size(packed, ret),
818                 "Failed to get correct message size");
819         fail_if(buxton_get_message_size(packed, BUXTON_MESSAGE_HEADER_LENGTH - 1) != 0,
820                 "Got size even though message smaller than the minimum");
821
822         free(packed);
823         buxton_array_free(&list, NULL);
824 }
825 END_TEST
826
827 static Suite *
828 shared_lib_suite(void)
829 {
830         Suite *s;
831         TCase *tc;
832
833         s = suite_create("shared_lib");
834         tc = tcase_create("log_functions");
835         tcase_add_test(tc, log_write_check);
836         suite_add_tcase(s, tc);
837
838         tc = tcase_create("hashmap_functions");
839         tcase_add_test(tc, hashmap_check);
840         suite_add_tcase(s, tc);
841
842         tc = tcase_create("array_functions");
843         tcase_add_test(tc, array_check);
844         suite_add_tcase(s, tc);
845
846         tc = tcase_create("list_functions");
847         tcase_add_test(tc, list_check);
848         suite_add_tcase(s, tc);
849
850         tc = tcase_create("util_functions");
851         tcase_add_test(tc, get_layer_path_check);
852         tcase_add_test(tc, buxton_data_copy_check);
853         tcase_add_test(tc, buxton_type_as_string_check);
854         tcase_add_test(tc, _write_check);
855         suite_add_tcase(s, tc);
856
857         tc = tcase_create("buxton_serialize_functions");
858         tcase_add_test(tc, buxton_db_serialize_check);
859         tcase_add_test(tc, buxton_message_serialize_check);
860         tcase_add_test(tc, buxton_get_message_size_check);
861         suite_add_tcase(s, tc);
862
863         return s;
864 }
865
866 int main(void)
867 {
868         int number_failed;
869         Suite *s;
870         SRunner *sr;
871
872         putenv("BUXTON_CONF_FILE=" ABS_TOP_BUILDDIR "/test/test.conf");
873         s = shared_lib_suite();
874         sr = srunner_create(s);
875         srunner_run_all(sr, CK_VERBOSE);
876         number_failed = srunner_ntests_failed(sr);
877         srunner_free(sr);
878
879         return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
880 }
881
882
883 /*
884  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
885  *
886  * Local variables:
887  * c-basic-offset: 8
888  * tab-width: 8
889  * indent-tabs-mode: t
890  * End:
891  *
892  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
893  * :indentSize=8:tabSize=8:noTabs=false:
894  */