Imported Upstream version 2
[platform/upstream/buxton.git] / test / check_daemon.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 <errno.h>
18 #include <fcntl.h>
19 #include <semaphore.h>
20 #include <signal.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/mman.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <time.h>
29 #include <unistd.h>
30
31 #include "buxton.h"
32 #include "buxtonresponse.h"
33 #include "configurator.h"
34 #include "check_utils.h"
35 #include "daemon.h"
36 #include "direct.h"
37 #include "hashmap.h"
38 #include "log.h"
39 #include "smack.h"
40 #include "util.h"
41
42 #ifdef NDEBUG
43 #error "re-run configure with --enable-debug"
44 #endif
45
46 #define BUXTON_ROOT_CHECK_ENV "BUXTON_ROOT_CHECK"
47
48 static pid_t daemon_pid;
49 int fuzz_time;
50
51 typedef struct _fuzz_context_t {
52         uint8_t buf[4096];
53         size_t size;
54         int iteration;
55 } FuzzContext;
56
57 static bool use_smack(void)
58 {
59         bool __attribute__((unused))dummy;
60
61         dummy = buxton_cache_smack_rules();
62
63         return buxton_smack_enabled();
64 }
65
66 static char* dump_fuzz(FuzzContext *fuzz)
67 {
68         char* buf;
69         size_t buff_size;
70         FILE* s;
71         int l = 0;
72         int c = 0;
73
74         s = open_memstream(&buf, &buff_size);
75
76         fprintf(s, "\n\n******************************************\n");
77         fprintf(s, "current time %ld\n", time(NULL));
78         fprintf(s, "iteration: %d\tsize: %llu\n", fuzz->iteration, (unsigned long long)fuzz->size);
79         for (int i = 0; i < fuzz->size; i++) {
80                 fprintf(s, "%02X ", fuzz->buf[i]);
81                 c+= 3;
82                 if (c > 80) {
83                         fprintf(s, "\n");
84                         c = 0;
85                         l++;
86                 }
87         }
88         fclose(s);
89
90         return buf;
91 }
92
93 static void check_did_not_crash(pid_t pid, FuzzContext *fuzz)
94 {
95         pid_t rpid;
96         int status;
97
98         rpid = waitpid(pid, &status, WNOHANG);
99         fail_if(rpid == -1, "couldn't wait for pid %m");
100         if (rpid == 0) {
101                 /* child is still running */
102                 return;
103         }
104         fail_if(WIFEXITED(status), "daemon exited with status %d%s",
105                 WEXITSTATUS(status), dump_fuzz(fuzz));
106         fail_if(WIFSIGNALED(status), "daemon was killed with signal %d%s",
107                 WTERMSIG(status), dump_fuzz(fuzz));
108 }
109
110 static void exec_daemon(void)
111 {
112         char path[PATH_MAX];
113
114         //FIXME: path is wrong for makedistcheck
115         snprintf(path, PATH_MAX, "%s/check_buxtond", get_current_dir_name());
116
117         if (execl(path, "check_buxtond", (const char*)NULL) < 0) {
118                 fail("couldn't exec: %m");
119         }
120         fail("should never reach here");
121 }
122
123 static void setup(void)
124 {
125         daemon_pid = 0;
126         sigset_t sigset;
127         pid_t pid;
128
129         unlink(buxton_socket());
130
131         sigemptyset(&sigset);
132         sigaddset(&sigset, SIGCHLD);
133         sigprocmask(SIG_BLOCK, &sigset, NULL);
134
135         pid = fork();
136         fail_if(pid < 0, "couldn't fork");
137         if (pid) {
138                 /* parent*/
139                 daemon_pid = pid;
140                 usleep(128*1000);
141         } else {
142                 /* child */
143                 exec_daemon();
144         }
145 }
146
147 static void teardown(void)
148 {
149         if (daemon_pid) {
150                 int status;
151                 pid_t pid;
152
153                 pid = waitpid(daemon_pid, &status, WNOHANG);
154                 fail_if(pid == -1, "waitpid error");
155                 if (pid) {
156                         fail("daemon crashed!");
157                 } else  {
158                         /* if the daemon is still running, kill it */
159                         kill(SIGTERM, daemon_pid);
160                         usleep(64*1000);
161                         kill(SIGKILL, daemon_pid);
162                 }
163         }
164 }
165
166 START_TEST(buxton_open_check)
167 {
168         BuxtonClient c = NULL;
169         fail_if(buxton_open(&c) == -1,
170                 "Connection failed to open with daemon.");
171 }
172 END_TEST
173
174 static void client_create_group_test(BuxtonResponse response, void *data)
175 {
176         char *k = (char *)data;
177         BuxtonKey key;
178         char *group;
179         uid_t uid = getuid();
180         char *root_check = getenv(BUXTON_ROOT_CHECK_ENV);
181         bool skip_check = (root_check && streq(root_check, "0"));
182
183         fail_if(buxton_response_type(response) != BUXTON_CONTROL_CREATE_GROUP,
184                 "Failed to get create group response type");
185
186         if (uid == 0) {
187                 fail_if(buxton_response_status(response) != 0,
188                         "Create group failed");
189                 key = buxton_response_key(response);
190                 fail_if(!key, "Failed to get create group key");
191                 group = buxton_key_get_group(key);
192                 fail_if(!group, "Failed to get group from key");
193                 fail_if(!streq(group, k),
194                         "Incorrect set key returned");
195                 free(group);
196                 buxton_key_free(key);
197         } else {
198                 fail_if(buxton_response_status(response) == 0  && !skip_check,
199                         "Create group succeeded, but the client is not root");
200         }
201 }
202 START_TEST(buxton_create_group_check)
203 {
204         BuxtonClient c;
205         BuxtonKey key = buxton_key_create("tgroup", NULL, "base", STRING);
206         fail_if(!key, "Failed to create key");
207         fail_if(buxton_open(&c) == -1,
208                 "Open failed with daemon.");
209         fail_if(buxton_create_group(c, key, client_create_group_test,
210                                     "tgroup", true),
211                 "Creating group in buxton failed.");
212         buxton_key_free(key);
213 }
214 END_TEST
215
216 static void client_remove_group_test(BuxtonResponse response, void *data)
217 {
218         char *k = (char *)data;
219         BuxtonKey key;
220         char *group;
221         uid_t uid = getuid();
222         char *root_check = getenv(BUXTON_ROOT_CHECK_ENV);
223         bool skip_check = (root_check && streq(root_check, "0"));
224
225         fail_if(buxton_response_type(response) != BUXTON_CONTROL_REMOVE_GROUP,
226                 "Failed to get remove group response type");
227
228         if (uid == 0) {
229                 fail_if(buxton_response_status(response) != 0,
230                         "Remove group failed");
231                 key = buxton_response_key(response);
232                 fail_if(!key, "Failed to get create group key");
233                 group = buxton_key_get_group(key);
234                 fail_if(!group, "Failed to get group from key");
235                 fail_if(!streq(group, k),
236                         "Incorrect set key returned");
237                 free(group);
238                 buxton_key_free(key);
239         } else {
240                 fail_if(buxton_response_status(response) == 0  && !skip_check,
241                         "Create group succeeded, but the client is not root");
242         }
243 }
244 START_TEST(buxton_remove_group_check)
245 {
246         BuxtonClient c;
247         BuxtonKey key = buxton_key_create("tgroup", NULL, "base", STRING);
248         fail_if(!key, "Failed to create key");
249         fail_if(buxton_open(&c) == -1,
250                 "Open failed with daemon.");
251         fail_if(buxton_remove_group(c, key, client_remove_group_test,
252                                     "tgroup", true),
253                 "Removing group in buxton failed.");
254         buxton_key_free(key);
255 }
256 END_TEST
257
258 static void client_set_value_test(BuxtonResponse response, void *data)
259 {
260         char *k = (char *)data;
261         BuxtonKey key;
262         char *group;
263
264         fail_if(buxton_response_type(response) != BUXTON_CONTROL_SET,
265                 "Failed to get set response type");
266         fail_if(buxton_response_status(response) != 0,
267                 "Set value failed");
268         key = buxton_response_key(response);
269         fail_if(!key, "Failed to get set key");
270         group = buxton_key_get_group(key);
271         fail_if(!group, "Failed to get group from key");
272         fail_if(!streq(group, k),
273                 "Incorrect set group returned");
274         free(group);
275         buxton_key_free(key);
276 }
277 START_TEST(buxton_set_value_check)
278 {
279         BuxtonClient c;
280         BuxtonKey group = buxton_key_create("group", NULL, "test-gdbm-user", STRING);
281         fail_if(!group, "Failed to create key for group");
282         BuxtonKey key = buxton_key_create("group", "name", "test-gdbm-user", STRING);
283         fail_if(!key, "Failed to create key");
284         fail_if(buxton_open(&c) == -1,
285                 "Open failed with daemon.");
286         fail_if(buxton_create_group(c, group, NULL, NULL, true),
287                 "Creating group in buxton failed.");
288         fail_if(buxton_set_label(c, group, "*", NULL, NULL, true),
289                 "Setting group in buxton failed.");
290         fail_if(buxton_set_value(c, key, "bxt_test_value",
291                                  client_set_value_test,
292                                  "group", true),
293                 "Setting value in buxton failed.");
294         buxton_key_free(group);
295         buxton_key_free(key);
296 }
297 END_TEST
298
299 static void client_set_label_test(BuxtonResponse response, void *data)
300 {
301         BuxtonKey user_key = (BuxtonKey)data;
302         BuxtonKey key;
303         char *user_group, *group;
304         char *user_name, *name;
305         uid_t uid = getuid();
306         char *root_check = getenv(BUXTON_ROOT_CHECK_ENV);
307         bool skip_check = (root_check && streq(root_check, "0"));
308
309         fail_if(buxton_response_type(response) != BUXTON_CONTROL_SET_LABEL,
310                 "Failed to get set label response type");
311
312         if (uid == 0) {
313                 fail_if(buxton_response_status(response) != 0,
314                         "Set label failed");
315                 key = buxton_response_key(response);
316                 fail_if(!key, "Failed to get set label key");
317                 user_group = buxton_key_get_group(user_key);
318                 fail_if(!user_group, "Failed to get group from user key");
319                 group = buxton_key_get_group(key);
320                 fail_if(!group, "Failed to get group from key");
321                 fail_if(!streq(group, user_group),
322                         "Incorrect set label group returned");
323                 free(user_group);
324                 free(group);
325
326                 user_name = buxton_key_get_name(user_key);
327                 if (user_name) {
328                         name = buxton_key_get_name(key);
329                         fail_if(!name, "Failed to get name from key");
330                         fail_if(!streq(name, user_name),
331                                 "Incorrect set label name returned");
332                         free(user_name);
333                         free(name);
334                 }
335                 buxton_key_free(key);
336         } else {
337                 if (skip_check) {
338                         fail_if(buxton_response_status(response) != 0,
339                         "Set label failed");
340                 } else {
341                         fail_if(buxton_response_status(response) == 0,
342                         "Set label succeeded, but the client is not root");
343                 }
344         }
345 }
346 START_TEST(buxton_set_label_check)
347 {
348         BuxtonClient c;
349         BuxtonKey group = buxton_key_create("bxt_group", NULL, "test-gdbm", STRING);
350         fail_if(!group, "Failed to create key for group");
351         fail_if(buxton_open(&c) == -1,
352                 "Open failed with daemon.");
353         fail_if(buxton_create_group(c, group, NULL, NULL, true),
354                 "Creating group in buxton failed.");
355         fail_if(buxton_set_label(c, group, "*",
356                                  client_set_label_test,
357                                  group, true),
358                 "Setting label for group in buxton failed.");
359
360         BuxtonKey name = buxton_key_create("bxt_group", "bxt_name", "test-gdbm", STRING);
361         fail_if(!name, "Failed to create key for name");
362         fail_if(buxton_set_value(c, name, "bxt_value", NULL, NULL, true),
363                 "Setting label for name in buxton failed.");
364         fail_if(buxton_set_label(c, name, "*",
365                                  client_set_label_test,
366                                  name, true),
367                 "Setting label for name in buxton failed.");
368
369         buxton_key_free(group);
370         buxton_key_free(name);
371 }
372 END_TEST
373
374 static void client_get_value_test(BuxtonResponse response, void *data)
375 {
376         BuxtonKey key;
377         char *group;
378         char *name;
379         char *v;
380         char *value = (char *)data;
381
382         fail_if(buxton_response_status(response) != 0,
383                 "Get value failed");
384
385         key = buxton_response_key(response);
386         fail_if(!key, "Failed to get key");
387         group = buxton_key_get_group(key);
388         fail_if(!group, "Failed to get group");
389         fail_if(!streq(group, "group"),
390                 "Failed to get correct group");
391         name = buxton_key_get_name(key);
392         fail_if(!name, "Failed to get name");
393         fail_if(!streq(name, "name"),
394                 "Failed to get correct name");
395         v = buxton_response_value(response);
396         printf("val=%s\n", v);
397         fail_if(!v, "Failed to get value");
398         fail_if(!streq(v, value),
399                 "Failed to get correct value");
400
401         free(v);
402         free(group);
403         free(name);
404         buxton_key_free(key);
405 }
406 START_TEST(buxton_get_value_for_layer_check)
407 {
408         BuxtonClient c = NULL;
409         BuxtonKey key = buxton_key_create("group", "name", "test-gdbm-user", STRING);
410
411         fail_if(buxton_open(&c) == -1,
412                 "Open failed with daemon.");
413         fail_if(buxton_get_value(c, key,
414                                  client_get_value_test,
415                                  "bxt_test_value", true),
416                 "Retrieving value from buxton gdbm backend failed.");
417 }
418 END_TEST
419
420 START_TEST(buxton_get_value_check)
421 {
422         BuxtonClient c = NULL;
423
424         BuxtonKey group = buxton_key_create("group", NULL, "test-gdbm", STRING);
425         fail_if(!group, "Failed to create key for group");
426         BuxtonKey key = buxton_key_create("group", "name", "test-gdbm", STRING);
427
428         fail_if(buxton_open(&c) == -1,
429                 "Open failed with daemon.");
430
431         fail_if(buxton_create_group(c, group, NULL, NULL, true),
432                 "Creating group in buxton failed.");
433         fail_if(buxton_set_label(c, group, "*", NULL, NULL, true),
434                 "Setting group in buxton failed.");
435         fail_if(buxton_set_value(c, key, "bxt_test_value2",
436                                  client_set_value_test, "group", true),
437                 "Failed to set second value.");
438         buxton_key_free(group);
439         buxton_key_free(key);
440         key = buxton_key_create("group", "name", NULL, STRING);
441         fail_if(buxton_get_value(c, key,
442                                  client_get_value_test,
443                                  "bxt_test_value2", true),
444                 "Retrieving value from buxton gdbm backend failed.");
445         buxton_key_free(key);
446 }
447 END_TEST
448
449 START_TEST(parse_list_check)
450 {
451         BuxtonData l3[2];
452         BuxtonData l2[4];
453         BuxtonData l1[3];
454         _BuxtonKey key;
455         BuxtonData *value = NULL;
456
457         fail_if(parse_list(BUXTON_CONTROL_NOTIFY, 2, l1, &key, &value),
458                 "Parsed bad notify argument count");
459         l1[0].type = INT32;
460         l1[1].type = STRING;
461         l1[2].type = UINT32;
462         fail_if(parse_list(BUXTON_CONTROL_NOTIFY, 3, l1, &key, &value),
463                 "Parsed bad notify type 1");
464         l1[0].type = STRING;
465         l1[1].type = FLOAT;
466         l1[2].type = UINT32;
467         fail_if(parse_list(BUXTON_CONTROL_NOTIFY, 3, l1, &key, &value),
468                 "Parsed bad notify type 3");
469         l1[0].type = STRING;
470         l1[1].type = STRING;
471         l1[2].type = STRING;
472         fail_if(parse_list(BUXTON_CONTROL_NOTIFY, 3, l1, &key, &value),
473                 "Parsed bad notify type 3");
474         l1[0].type = STRING;
475         l1[1].type = STRING;
476         l1[2].type = UINT32;
477         l1[0].store.d_string = buxton_string_pack("s1");
478         l1[1].store.d_string = buxton_string_pack("s2");
479         l1[2].store.d_uint32 = STRING;
480         fail_if(!parse_list(BUXTON_CONTROL_NOTIFY, 3, l1, &key, &value),
481                 "Unable to parse valid notify");
482         fail_if(!streq(key.group.value, l1[0].store.d_string.value),
483                 "Failed to set correct notify group");
484         fail_if(!streq(key.name.value, l1[1].store.d_string.value),
485                 "Failed to set correct notify name");
486         fail_if(key.type != l1[2].store.d_uint32,
487                 "Failed to set correct notify type");
488
489         fail_if(parse_list(BUXTON_CONTROL_UNNOTIFY, 2, l1, &key, &value),
490                 "Parsed bad unnotify argument count");
491         l1[0].type = INT32;
492         l1[1].type = STRING;
493         l1[2].type = UINT32;
494         fail_if(parse_list(BUXTON_CONTROL_UNNOTIFY, 3, l1, &key, &value),
495                 "Parsed bad unnotify type 1");
496         l1[0].type = STRING;
497         l1[1].type = FLOAT;
498         l1[2].type = UINT32;
499         fail_if(parse_list(BUXTON_CONTROL_UNNOTIFY, 3, l1, &key, &value),
500                 "Parsed bad unnotify type 2");
501         l1[0].type = INT32;
502         l1[1].type = STRING;
503         l1[2].type = STRING;
504         fail_if(parse_list(BUXTON_CONTROL_UNNOTIFY, 3, l1, &key, &value),
505                 "Parsed bad unnotify type 3");
506         l1[0].type = STRING;
507         l1[1].type = STRING;
508         l1[2].type = UINT32;
509         l1[0].store.d_string = buxton_string_pack("s3");
510         l1[1].store.d_string = buxton_string_pack("s4");
511         l1[2].store.d_uint32 = STRING;
512         fail_if(!parse_list(BUXTON_CONTROL_UNNOTIFY, 3, l1, &key, &value),
513                 "Unable to parse valid unnotify");
514         fail_if(!streq(key.group.value, l1[0].store.d_string.value),
515                 "Failed to set correct unnotify group");
516         fail_if(!streq(key.name.value, l1[1].store.d_string.value),
517                 "Failed to set correct unnotify name");
518         fail_if(key.type != l1[2].store.d_uint32,
519                 "Failed to set correct unnotify type");
520
521         fail_if(parse_list(BUXTON_CONTROL_GET, 5, l2, &key, &value),
522                 "Parsed bad get argument count");
523         l2[0].type = INT32;
524         l2[1].type = STRING;
525         l2[2].type = STRING;
526         l2[3].type = UINT32;
527         fail_if(parse_list(BUXTON_CONTROL_GET, 4, l2, &key, &value),
528                 "Parsed bad get type 1");
529         l2[0].type = STRING;
530         l2[1].type = FLOAT;
531         l2[2].type = STRING;
532         l2[3].type = UINT32;
533         fail_if(parse_list(BUXTON_CONTROL_GET, 4, l2, &key, &value),
534                 "Parsed bad get type 2");
535         l2[0].type = STRING;
536         l2[1].type = STRING;
537         l2[2].type = BOOLEAN;
538         l2[3].type = UINT32;
539         fail_if(parse_list(BUXTON_CONTROL_GET, 4, l2, &key, &value),
540                 "Parsed bad get type 3");
541         l2[0].type = STRING;
542         l2[1].type = STRING;
543         l2[2].type = STRING;
544         l2[3].type = STRING;
545         fail_if(parse_list(BUXTON_CONTROL_GET, 4, l2, &key, &value),
546                 "Parsed bad get type 4");
547         l2[0].type = STRING;
548         l2[1].type = STRING;
549         l2[2].type = STRING;
550         l2[3].type = UINT32;
551         l2[0].store.d_string = buxton_string_pack("s5");
552         l2[1].store.d_string = buxton_string_pack("s6");
553         l2[2].store.d_string = buxton_string_pack("s7");
554         l2[3].store.d_uint32 = STRING;
555         fail_if(!parse_list(BUXTON_CONTROL_GET, 4, l2, &key, &value),
556                 "Unable to parse valid get 1");
557         fail_if(!streq(key.layer.value, l2[0].store.d_string.value),
558                 "Failed to set correct get layer 1");
559         fail_if(!streq(key.group.value, l2[1].store.d_string.value),
560                 "Failed to set correct get group 1");
561         fail_if(!streq(key.name.value, l2[2].store.d_string.value),
562                 "Failed to set correct get name");
563         fail_if(key.type != l2[3].store.d_uint32,
564                 "Failed to set correct get type 1");
565         l2[0].store.d_string = buxton_string_pack("s6");
566         l2[1].store.d_string = buxton_string_pack("s6");
567         l2[2].type = UINT32;
568         l2[2].store.d_uint32 = STRING;
569         fail_if(!parse_list(BUXTON_CONTROL_GET, 3, l2, &key, &value),
570                 "Unable to parse valid get 2");
571         fail_if(!streq(key.group.value, l2[0].store.d_string.value),
572                 "Failed to set correct get group 2");
573         fail_if(!streq(key.name.value, l2[1].store.d_string.value),
574                 "Failed to set correct get name 2");
575         fail_if(key.type != l2[2].store.d_uint32,
576                 "Failed to set correct get type 2");
577         l1[0].type = INT32;
578         l1[1].type = STRING;
579         l1[2].type = UINT32;
580         fail_if(parse_list(BUXTON_CONTROL_GET, 3, l1, &key, &value),
581                 "Parsed bad get type 5");
582         l1[0].type = STRING;
583         l1[1].type = FLOAT;
584         l1[2].type = UINT32;
585         fail_if(parse_list(BUXTON_CONTROL_GET, 3, l1, &key, &value),
586                 "Parsed bad get type 6");
587         l1[0].type = STRING;
588         l1[1].type = STRING;
589         l1[2].type = BOOLEAN;
590         fail_if(parse_list(BUXTON_CONTROL_GET, 3, l1, &key, &value),
591                 "Parsed bad get type 7");
592
593         fail_if(parse_list(BUXTON_CONTROL_SET, 1, l2, &key, &value),
594                 "Parsed bad set argument count");
595         l2[0].type = INT32;
596         l2[1].type = STRING;
597         l2[2].type = STRING;
598         l2[3].type = FLOAT;
599         fail_if(parse_list(BUXTON_CONTROL_SET, 4, l2, &key, &value),
600                 "Parsed bad set type 1");
601         l2[0].type = STRING;
602         l2[1].type = FLOAT;
603         l2[2].type = STRING;
604         l2[3].type = FLOAT;
605         fail_if(parse_list(BUXTON_CONTROL_SET, 4, l2, &key, &value),
606                 "Parsed bad set type 2");
607         l2[0].type = STRING;
608         l2[1].type = STRING;
609         l2[2].type = BOOLEAN;
610         l2[3].type = FLOAT;
611         fail_if(parse_list(BUXTON_CONTROL_SET, 4, l2, &key, &value),
612                 "Parsed bad set type 3");
613         l2[0].type = STRING;
614         l2[1].type = STRING;
615         l2[2].type = STRING;
616         l2[3].type = FLOAT;
617         l2[0].store.d_string = buxton_string_pack("s8");
618         l2[1].store.d_string = buxton_string_pack("s9");
619         l2[2].store.d_string = buxton_string_pack("s10");
620         l2[3].store.d_float = 3.14F;
621         fail_if(!parse_list(BUXTON_CONTROL_SET, 4, l2, &key, &value),
622                 "Unable to parse valid set 1");
623         fail_if(!streq(key.layer.value, l2[0].store.d_string.value),
624                 "Failed to set correct set layer 1");
625         fail_if(!streq(key.group.value, l2[1].store.d_string.value),
626                 "Failed to set correct set group 1");
627         fail_if(!streq(key.name.value, l2[2].store.d_string.value),
628                 "Failed to set correct set name 1");
629         fail_if(value->store.d_float != l2[3].store.d_float,
630                 "Failed to set correct set value 1");
631
632         fail_if(parse_list(BUXTON_CONTROL_UNSET, 1, l2, &key, &value),
633                 "Parsed bad unset argument count");
634         l2[0].type = INT32;
635         l2[1].type = STRING;
636         l2[2].type = STRING;
637         l2[3].type = UINT32;
638         fail_if(parse_list(BUXTON_CONTROL_UNSET, 4, l2, &key, &value),
639                 "Parsed bad unset type 1");
640         l2[0].type = STRING;
641         l2[1].type = FLOAT;
642         l2[2].type = STRING;
643         l2[3].type = UINT32;
644         fail_if(parse_list(BUXTON_CONTROL_UNSET, 4, l2, &key, &value),
645                 "Parsed bad unset type 2");
646         l2[0].type = STRING;
647         l2[1].type = STRING;
648         l2[2].type = BOOLEAN;
649         l2[3].type = UINT32;
650         fail_if(parse_list(BUXTON_CONTROL_UNSET, 4, l2, &key, &value),
651                 "Parsed bad unset type 3");
652         l2[0].type = STRING;
653         l2[1].type = STRING;
654         l2[2].type = STRING;
655         l2[3].type = STRING;
656         fail_if(parse_list(BUXTON_CONTROL_UNSET, 4, l2, &key, &value),
657                 "Parsed bad unset type 4");
658         l2[0].type = STRING;
659         l2[1].type = STRING;
660         l2[2].type = STRING;
661         l2[3].type = UINT32;
662         l2[0].store.d_string = buxton_string_pack("s11");
663         l2[1].store.d_string = buxton_string_pack("s12");
664         l2[2].store.d_string = buxton_string_pack("s13");
665         l2[3].store.d_uint32 = STRING;
666         fail_if(!parse_list(BUXTON_CONTROL_UNSET, 4, l2, &key, &value),
667                 "Unable to parse valid unset 1");
668         fail_if(!streq(key.layer.value, l2[0].store.d_string.value),
669                 "Failed to set correct unset layer 1");
670         fail_if(!streq(key.group.value, l2[1].store.d_string.value),
671                 "Failed to set correct unset group 1");
672         fail_if(!streq(key.name.value, l2[2].store.d_string.value),
673                 "Failed to set correct unset name 1");
674         fail_if(key.type != l2[3].store.d_uint32,
675                 "Failed to set correct unset type 1");
676
677         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 1, l2, &key, &value),
678                 "Parsed bad set label argument count");
679         l1[0].type = INT32;
680         l1[1].type = STRING;
681         l1[2].type = STRING;
682         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 3, l1, &key, &value),
683                 "Parsed bad set label type 1");
684         l1[0].type = STRING;
685         l1[1].type = FLOAT;
686         l1[2].type = STRING;
687         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 3, l1, &key, &value),
688                 "Parsed bad set label type 2");
689         l1[0].type = STRING;
690         l1[1].type = STRING;
691         l1[2].type = BOOLEAN;
692         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 3, l1, &key, &value),
693                 "Parsed bad set label type 3");
694         l1[0].type = STRING;
695         l1[1].type = STRING;
696         l1[2].type = STRING;
697         l1[0].store.d_string = buxton_string_pack("s14");
698         l1[1].store.d_string = buxton_string_pack("s15");
699         l1[2].store.d_string = buxton_string_pack("*");
700         fail_if(!parse_list(BUXTON_CONTROL_SET_LABEL, 3, l1, &key, &value),
701                 "Unable to parse valid set label 1");
702         fail_if(!streq(key.layer.value, l1[0].store.d_string.value),
703                 "Failed to set correct set label layer 1");
704         fail_if(!streq(key.group.value, l1[1].store.d_string.value),
705                 "Failed to set correct set label group 1");
706         fail_if(!streq(value->store.d_string.value, l1[2].store.d_string.value),
707                 "Failed to set correct set label label 1");
708         fail_if(key.type != STRING, "Failed to key type in set label");
709         l2[0].type = INT32;
710         l2[1].type = STRING;
711         l2[2].type = STRING;
712         l2[3].type = STRING;
713         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 4, l2, &key, &value),
714                 "Parsed bad set label type 4");
715         l2[0].type = STRING;
716         l2[1].type = FLOAT;
717         l2[2].type = STRING;
718         l2[3].type = STRING;
719         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 4, l2, &key, &value),
720                 "Parsed bad set label type 5");
721         l2[0].type = STRING;
722         l2[1].type = STRING;
723         l2[2].type = BOOLEAN;
724         l2[3].type = STRING;
725         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 4, l2, &key, &value),
726                 "Parsed bad set label type 6");
727         l2[0].type = STRING;
728         l2[1].type = STRING;
729         l2[2].type = STRING;
730         l2[3].type = UINT32;
731         fail_if(parse_list(BUXTON_CONTROL_SET_LABEL, 4, l2, &key, &value),
732                 "Parsed bad set label type 7");
733         l2[0].type = STRING;
734         l2[1].type = STRING;
735         l2[2].type = STRING;
736         l2[3].type = STRING;
737         l2[0].store.d_string = buxton_string_pack("x1");
738         l2[1].store.d_string = buxton_string_pack("x2");
739         l2[2].store.d_string = buxton_string_pack("x3");
740         l2[3].store.d_string = buxton_string_pack("x4");
741         fail_if(!parse_list(BUXTON_CONTROL_SET_LABEL, 4, l2, &key, &value),
742                 "Unable to parse valid set label 2");
743         fail_if(!streq(key.layer.value, l2[0].store.d_string.value),
744                 "Failed to set correct set label layer 2");
745         fail_if(!streq(key.group.value, l2[1].store.d_string.value),
746                 "Failed to set correct set label group 2");
747         fail_if(!streq(key.name.value, l2[2].store.d_string.value),
748                 "Failed to set correct set label name 2");
749         fail_if(!streq(value->store.d_string.value, l2[3].store.d_string.value),
750                 "Failed to set correct set label label 2");
751
752         fail_if(parse_list(BUXTON_CONTROL_CREATE_GROUP, 1, l3, &key, &value),
753                 "Parsed bad create group argument count");
754         l3[0].type = INT32;
755         l3[1].type = STRING;
756         fail_if(parse_list(BUXTON_CONTROL_CREATE_GROUP, 2, l3, &key, &value),
757                 "Parsed bad create group type 1");
758         l3[0].type = STRING;
759         l3[1].type = FLOAT;
760         fail_if(parse_list(BUXTON_CONTROL_CREATE_GROUP, 2, l3, &key, &value),
761                 "Parsed bad create group type 2");
762         l3[0].type = STRING;
763         l3[1].type = STRING;
764         l3[0].store.d_string = buxton_string_pack("s16");
765         l3[1].store.d_string = buxton_string_pack("s17");
766         fail_if(!parse_list(BUXTON_CONTROL_CREATE_GROUP, 2, l3, &key, &value),
767                 "Unable to parse valid create group 1");
768         fail_if(!streq(key.layer.value, l3[0].store.d_string.value),
769                 "Failed to set correct create group layer 1");
770         fail_if(!streq(key.group.value, l3[1].store.d_string.value),
771                 "Failed to set correct create group group 1");
772         fail_if(key.type != STRING, "Failed to key type in create group");
773
774         fail_if(parse_list(BUXTON_CONTROL_REMOVE_GROUP, 1, l3, &key, &value),
775                 "Parsed bad remove group argument count");
776         l3[0].type = INT32;
777         l3[1].type = STRING;
778         fail_if(parse_list(BUXTON_CONTROL_REMOVE_GROUP, 2, l3, &key, &value),
779                 "Parsed bad remove group type 1");
780         l3[0].type = STRING;
781         l3[1].type = FLOAT;
782         fail_if(parse_list(BUXTON_CONTROL_REMOVE_GROUP, 2, l3, &key, &value),
783                 "Parsed bad remove group type 2");
784         l3[0].type = STRING;
785         l3[1].type = STRING;
786         l3[0].store.d_string = buxton_string_pack("s18");
787         l3[1].store.d_string = buxton_string_pack("s19");
788         fail_if(!parse_list(BUXTON_CONTROL_REMOVE_GROUP, 2, l3, &key, &value),
789                 "Unable to parse valid remove group 1");
790         fail_if(!streq(key.layer.value, l3[0].store.d_string.value),
791                 "Failed to set correct remove group layer 1");
792         fail_if(!streq(key.group.value, l3[1].store.d_string.value),
793                 "Failed to set correct remove group group 1");
794         fail_if(key.type != STRING, "Failed to key type in remove group");
795
796         fail_if(parse_list(BUXTON_CONTROL_MIN, 2, l3, &key, &value),
797                 "Parsed bad control type 1");
798 }
799 END_TEST
800
801 START_TEST(create_group_check)
802 {
803         _BuxtonKey key = { {0}, {0}, {0}, 0};
804         client_list_item client;
805         int32_t status;
806         BuxtonDaemon server;
807         BuxtonString clabel = buxton_string_pack("_");
808
809         fail_if(!buxton_direct_open(&server.buxton),
810                 "Failed to open buxton direct connection");
811
812         client.cred.uid = getuid();
813         if (use_smack())
814                 client.smack_label = &clabel;
815         else
816                 client.smack_label = NULL;
817         server.buxton.client.uid = 0;
818
819         key.layer = buxton_string_pack("test-gdbm-user");
820         key.group = buxton_string_pack("daemon-check");
821         key.type = STRING;
822         create_group(&server, &client, &key, &status);
823         fail_if(status != 0, "Failed to create group");
824
825         key.layer = buxton_string_pack("test-gdbm");
826         create_group(&server, &client, &key, &status);
827         fail_if(status != 0, "Failed to create group");
828
829         key.layer = buxton_string_pack("base");
830         key.group = buxton_string_pack("tgroup");
831         create_group(&server, &client, &key, &status);
832         fail_if(status != 0, "Failed to create group");
833
834         buxton_direct_close(&server.buxton);
835 }
836 END_TEST
837
838 START_TEST(remove_group_check)
839 {
840         _BuxtonKey key = { {0}, {0}, {0}, 0};
841         client_list_item client;
842         int32_t status;
843         BuxtonDaemon server;
844         BuxtonString clabel = buxton_string_pack("_");
845
846         fail_if(!buxton_direct_open(&server.buxton),
847                 "Failed to open buxton direct connection");
848
849         client.cred.uid = getuid();
850         if (use_smack())
851                 client.smack_label = &clabel;
852         else
853                 client.smack_label = NULL;
854         server.buxton.client.uid = 0;
855
856         key.layer = buxton_string_pack("base");
857         key.group = buxton_string_pack("tgroup");
858         key.type = STRING;
859
860         remove_group(&server, &client, &key, &status);
861         fail_if(status != 0, "Failed to remove group");
862
863         buxton_direct_close(&server.buxton);
864 }
865 END_TEST
866
867 START_TEST(set_label_check)
868 {
869         _BuxtonKey key = { {0}, {0}, {0}, 0};
870         BuxtonData value;
871         client_list_item client;
872         int32_t status;
873         BuxtonDaemon server;
874         BuxtonString clabel = buxton_string_pack("_");
875
876         fail_if(!buxton_direct_open(&server.buxton),
877                 "Failed to open buxton direct connection");
878
879         client.cred.uid = getuid();
880         if (use_smack())
881                 client.smack_label = &clabel;
882         else
883                 client.smack_label = NULL;
884         server.buxton.client.uid = 0;
885         key.layer = buxton_string_pack("test-gdbm-user");
886         key.group = buxton_string_pack("daemon-check");
887         key.type = STRING;
888         value.type = STRING;
889         value.store.d_string = buxton_string_pack("*");
890
891         key.layer = buxton_string_pack("test-gdbm");
892         set_label(&server, &client, &key, &value, &status);
893         fail_if(status != 0, "Failed to set label 2");
894         buxton_direct_close(&server.buxton);
895 }
896 END_TEST
897
898 START_TEST(set_value_check)
899 {
900         _BuxtonKey key = { {0}, {0}, {0}, 0};
901         BuxtonData value;
902         client_list_item client;
903         int32_t status;
904         BuxtonDaemon server;
905         BuxtonString clabel = buxton_string_pack("_");
906
907         fail_if(!buxton_direct_open(&server.buxton),
908                 "Failed to open buxton direct connection");
909
910         client.cred.uid = getuid();
911         server.buxton.client.uid = 0;
912
913         if (use_smack())
914                 client.smack_label = &clabel;
915         else
916                 client.smack_label = NULL;
917
918         key.layer = buxton_string_pack("test-gdbm-user");
919         key.group = buxton_string_pack("daemon-check");
920         key.name = buxton_string_pack("name");
921         value.type = STRING;
922         value.store.d_string = buxton_string_pack("user-layer-value");
923
924         set_value(&server, &client, &key, &value, &status);
925         fail_if(status != 0, "Failed to set value");
926         fail_if(server.buxton.client.uid != client.cred.uid, "Failed to change buxton uid");
927
928         key.layer = buxton_string_pack("test-gdbm");
929         value.store.d_string = buxton_string_pack("system-layer-value");
930         set_value(&server, &client, &key, &value, &status);
931         fail_if(status != 0, "Failed to set value");
932
933         buxton_direct_close(&server.buxton);
934 }
935 END_TEST
936
937 START_TEST(get_value_check)
938 {
939         _BuxtonKey key = { {0}, {0}, {0}, 0};
940         BuxtonData *value;
941         client_list_item client;
942         int32_t status;
943         BuxtonDaemon server;
944         BuxtonString clabel = buxton_string_pack("_");
945
946         fail_if(!buxton_direct_open(&server.buxton),
947                 "Failed to open buxton direct connection");
948
949         fail_if(!buxton_cache_smack_rules(),
950                 "Failed to cache smack rules");
951         client.cred.uid = getuid();
952         if (use_smack())
953                 client.smack_label = &clabel;
954         else
955                 client.smack_label = NULL;
956         server.buxton.client.uid = 0;
957         key.layer = buxton_string_pack("test-gdbm-user");
958         key.group = buxton_string_pack("daemon-check");
959         key.name = buxton_string_pack("name");
960         key.type = STRING;
961
962         value = get_value(&server, &client, &key, &status);
963         fail_if(!value, "Failed to get value");
964         fail_if(status != 0, "Failed to get value");
965         fail_if(value->type != STRING, "Failed to get correct type");
966         fail_if(!streq(value->store.d_string.value, "user-layer-value"), "Failed to get correct value");
967         fail_if(server.buxton.client.uid != client.cred.uid, "Failed to change buxton uid");
968         free(value);
969
970         server.buxton.client.uid = 0;
971         key.layer.value = NULL;
972         key.layer.length = 0;
973         value = get_value(&server, &client, &key, &status);
974         fail_if(!value, "Failed to get value 2");
975         fail_if(status != 0, "Failed to get value 2");
976         fail_if(value->type != STRING, "Failed to get correct type 2");
977         fail_if(!streq(value->store.d_string.value, "system-layer-value"), "Failed to get correct value 2");
978         fail_if(server.buxton.client.uid != client.cred.uid, "Failed to change buxton uid 2");
979         free(value);
980
981         buxton_direct_close(&server.buxton);
982 }
983 END_TEST
984
985 START_TEST(register_notification_check)
986 {
987         _BuxtonKey key = { {0}, {0}, {0}, 0};
988         client_list_item client, no_client;
989         BuxtonString clabel = buxton_string_pack("_");
990         int32_t status;
991         BuxtonDaemon server;
992         uint32_t msgid;
993
994         fail_if(!buxton_cache_smack_rules(),
995                 "Failed to cache smack rules");
996         if (use_smack())
997                 client.smack_label = &clabel;
998         else
999                 client.smack_label = NULL;
1000         client.cred.uid = 1002;
1001         fail_if(!buxton_direct_open(&server.buxton),
1002                 "Failed to open buxton direct connection");
1003         server.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1004         fail_if(!server.notify_mapping, "Failed to allocate hashmap");
1005
1006         key.group = buxton_string_pack("group");
1007         key.name = buxton_string_pack("name");
1008         key.type = STRING;
1009         register_notification(&server, &client, &key, 1, &status);
1010         fail_if(status != 0, "Failed to register notification");
1011         register_notification(&server, &client, &key, 1, &status);
1012         fail_if(status != 0, "Failed to register notification");
1013         //FIXME: Figure out what to do with duplicates
1014         key.group = buxton_string_pack("no-key");
1015         msgid = unregister_notification(&server, &client, &key, &status);
1016         fail_if(status == 0,
1017                 "Unregistered from notifications with invalid key");
1018         fail_if(msgid != 0, "Got unexpected notify message id");
1019         key.group = buxton_string_pack("group");
1020         msgid = unregister_notification(&server, &no_client, &key, &status);
1021         fail_if(status == 0,
1022                 "Unregistered from notifications with invalid client");
1023         fail_if(msgid != 0, "Got unexpected notify message id");
1024         msgid = unregister_notification(&server, &client, &key, &status);
1025         fail_if(status != 0,
1026                 "Unable to unregister from notifications");
1027         fail_if(msgid != 1, "Failed to get correct notify message id");
1028         key.group = buxton_string_pack("key2");
1029         register_notification(&server, &client, &key, 0, &status);
1030         fail_if(status == 0, "Registered notification with key not in db");
1031
1032         hashmap_free(server.notify_mapping);
1033         buxton_direct_close(&server.buxton);
1034 }
1035 END_TEST
1036 START_TEST(buxtond_handle_message_error_check)
1037 {
1038         int client, server;
1039         BuxtonDaemon daemon;
1040         BuxtonString slabel;
1041         size_t size;
1042         BuxtonData data1;
1043         client_list_item cl;
1044         bool r;
1045         BuxtonArray *list = NULL;
1046         uint16_t control;
1047
1048         setup_socket_pair(&client, &server);
1049         fail_if(fcntl(client, F_SETFL, O_NONBLOCK),
1050                 "Failed to set socket to non blocking");
1051         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1052                 "Failed to set socket to non blocking");
1053         list = buxton_array_new();
1054         fail_if(!list, "Failed to allocate list");
1055
1056         cl.fd = server;
1057         slabel = buxton_string_pack("_");
1058         cl.smack_label = &slabel;
1059         daemon.buxton.client.uid = 1001;
1060         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1061         fail_if(!buxton_direct_open(&daemon.buxton),
1062                 "Failed to open buxton direct connection");
1063
1064         cl.data = malloc(4);
1065         fail_if(!cl.data, "Couldn't allocate blank message");
1066         cl.data[0] = 0;
1067         cl.data[1]= 0;
1068         cl.data[2] = 0;
1069         cl.data[3] = 0;
1070         size = 100;
1071         r = buxtond_handle_message(&daemon, &cl, size);
1072         fail_if(r, "Failed to detect invalid message data");
1073         free(cl.data);
1074
1075         data1.type = STRING;
1076         data1.store.d_string = buxton_string_pack("group");
1077         r = buxton_array_add(list, &data1);
1078         fail_if(!r, "Failed to add element to array");
1079         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_NOTIFY, 0,
1080                                         list);
1081         fail_if(size == 0, "Failed to serialize message");
1082         control = BUXTON_CONTROL_MIN;
1083         memcpy(cl.data, &control, sizeof(uint16_t));
1084         r = buxtond_handle_message(&daemon, &cl, size);
1085         fail_if(r, "Failed to detect min control size");
1086         control = BUXTON_CONTROL_MAX;
1087         memcpy(cl.data, &control, sizeof(uint16_t));
1088         r = buxtond_handle_message(&daemon, &cl, size);
1089         free(cl.data);
1090         fail_if(r, "Failed to detect max control size");
1091
1092         close(client);
1093         buxton_direct_close(&daemon.buxton);
1094         buxton_array_free(&list, NULL);
1095 }
1096 END_TEST
1097
1098 START_TEST(buxtond_handle_message_create_group_check)
1099 {
1100         BuxtonDaemon daemon;
1101         BuxtonString slabel;
1102         size_t size;
1103         BuxtonData data1, data2;
1104         client_list_item cl;
1105         bool r;
1106         BuxtonData *list;
1107         BuxtonArray *out_list1, *out_list2;
1108         BuxtonControlMessage msg;
1109         ssize_t csize;
1110         int client, server;
1111         ssize_t s;
1112         uint8_t buf[4096];
1113         uint32_t msgid;
1114
1115         setup_socket_pair(&client, &server);
1116         fail_if(fcntl(client, F_SETFL, O_NONBLOCK),
1117                 "Failed to set socket to non blocking");
1118         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1119                 "Failed to set socket to non blocking");
1120
1121         cl.fd = server;
1122         slabel = buxton_string_pack("_");
1123         if (use_smack())
1124                 cl.smack_label = &slabel;
1125         else
1126                 cl.smack_label = NULL;
1127         cl.cred.uid = 1002;
1128         daemon.buxton.client.uid = 1001;
1129         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1130         fail_if(!buxton_direct_open(&daemon.buxton),
1131                 "Failed to open buxton direct connection");
1132         daemon.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1133         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1134
1135         out_list1 = buxton_array_new();
1136         fail_if(!out_list1, "Failed to allocate list");
1137         data1.type = STRING;
1138         data1.store.d_string = buxton_string_pack("base");
1139         data2.type = STRING;
1140         data2.store.d_string = buxton_string_pack("tgroup");
1141         r = buxton_array_add(out_list1, &data1);
1142         fail_if(!r, "Failed to add element to array");
1143         r = buxton_array_add(out_list1, &data2);
1144         fail_if(!r, "Failed to add element to array");
1145
1146         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_CREATE_GROUP, 0,
1147                                         out_list1);
1148         fail_if(size == 0, "Failed to serialize message");
1149         r = buxtond_handle_message(&daemon, &cl, size);
1150         free(cl.data);
1151         fail_if(!r, "Failed to handle create group message");
1152
1153         s = read(client, buf, 4096);
1154         fail_if(s < 0, "Read from client failed");
1155         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1156         fail_if(csize != 1, "Failed to get correct response to create group");
1157         fail_if(msg != BUXTON_CONTROL_STATUS,
1158                 "Failed to get correct control type");
1159         fail_if(list[0].type != INT32,
1160                 "Failed to get correct indicator type");
1161         fail_if(list[0].store.d_int32 != 0,
1162                 "Failed to create group");
1163         fail_if(msgid != 0, "Failed to get correct message id");
1164         free(list);
1165
1166         out_list2 = buxton_array_new();
1167         fail_if(!out_list2, "Failed to allocate list");
1168         data1.store.d_string = buxton_string_pack("base");
1169         data2.store.d_string = buxton_string_pack("daemon-check");
1170         r = buxton_array_add(out_list2, &data1);
1171         fail_if(!r, "Failed to add element to array");
1172         r = buxton_array_add(out_list2, &data2);
1173         fail_if(!r, "Failed to add element to array");
1174
1175         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_CREATE_GROUP, 1,
1176                                         out_list2);
1177         fail_if(size == 0, "Failed to serialize message");
1178         r = buxtond_handle_message(&daemon, &cl, size);
1179         free(cl.data);
1180         fail_if(!r, "Failed to handle create group message");
1181
1182         s = read(client, buf, 4096);
1183         fail_if(s < 0, "Read from client failed");
1184         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1185         fail_if(csize != 1, "Failed to get correct response to create group");
1186         fail_if(msg != BUXTON_CONTROL_STATUS,
1187                 "Failed to get correct control type");
1188         fail_if(list[0].type != INT32,
1189                 "Failed to get correct indicator type");
1190         fail_if(list[0].store.d_int32 != 0,
1191                 "Failed to create group");
1192         fail_if(msgid != 1, "Failed to get correct message id");
1193
1194         free(list);
1195         cleanup_callbacks();
1196         close(client);
1197         hashmap_free(daemon.notify_mapping);
1198         buxton_direct_close(&daemon.buxton);
1199         buxton_array_free(&out_list1, NULL);
1200         buxton_array_free(&out_list2, NULL);
1201 }
1202 END_TEST
1203
1204 START_TEST(buxtond_handle_message_remove_group_check)
1205 {
1206         BuxtonDaemon daemon;
1207         BuxtonString slabel;
1208         size_t size;
1209         BuxtonData data1, data2;
1210         client_list_item cl;
1211         bool r;
1212         BuxtonData *list;
1213         BuxtonArray *out_list;
1214         BuxtonControlMessage msg;
1215         ssize_t csize;
1216         int client, server;
1217         ssize_t s;
1218         uint8_t buf[4096];
1219         uint32_t msgid;
1220
1221         setup_socket_pair(&client, &server);
1222         fail_if(fcntl(client, F_SETFL, O_NONBLOCK),
1223                 "Failed to set socket to non blocking");
1224         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1225                 "Failed to set socket to non blocking");
1226
1227         out_list = buxton_array_new();
1228         fail_if(!out_list, "Failed to allocate list");
1229         cl.fd = server;
1230         slabel = buxton_string_pack("_");
1231         if (use_smack())
1232                 cl.smack_label = &slabel;
1233         else
1234                 cl.smack_label = NULL;
1235         cl.cred.uid = 1002;
1236         daemon.buxton.client.uid = 1001;
1237         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1238         fail_if(!buxton_direct_open(&daemon.buxton),
1239                 "Failed to open buxton direct connection");
1240         daemon.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1241         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1242
1243         data1.type = STRING;
1244         data1.store.d_string = buxton_string_pack("base");
1245         data2.type = STRING;
1246         data2.store.d_string = buxton_string_pack("tgroup");
1247         r = buxton_array_add(out_list, &data1);
1248         fail_if(!r, "Failed to add element to array");
1249         r = buxton_array_add(out_list, &data2);
1250         fail_if(!r, "Failed to add element to array");
1251
1252         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_REMOVE_GROUP, 0,
1253                                         out_list);
1254         fail_if(size == 0, "Failed to serialize message");
1255         r = buxtond_handle_message(&daemon, &cl, size);
1256         free(cl.data);
1257         fail_if(!r, "Failed to handle remove group message");
1258
1259         s = read(client, buf, 4096);
1260         fail_if(s < 0, "Read from client failed");
1261         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1262         fail_if(csize != 1, "Failed to get correct response to remove group");
1263         fail_if(msg != BUXTON_CONTROL_STATUS,
1264                 "Failed to get correct control type");
1265         fail_if(list[0].type != INT32,
1266                 "Failed to get correct indicator type");
1267         fail_if(list[0].store.d_int32 != 0,
1268                 "Failed to remove group");
1269         fail_if(msgid != 0, "Failed to get correct message id");
1270
1271         free(list);
1272         cleanup_callbacks();
1273         close(client);
1274         hashmap_free(daemon.notify_mapping);
1275         buxton_direct_close(&daemon.buxton);
1276         buxton_array_free(&out_list, NULL);
1277 }
1278 END_TEST
1279
1280 START_TEST(buxtond_handle_message_set_label_check)
1281 {
1282         BuxtonDaemon daemon;
1283         BuxtonString slabel;
1284         size_t size;
1285         BuxtonData data1, data2, data3;
1286         client_list_item cl;
1287         bool r;
1288         BuxtonData *list;
1289         BuxtonArray *out_list;
1290         BuxtonControlMessage msg;
1291         ssize_t csize;
1292         int client, server;
1293         ssize_t s;
1294         uint8_t buf[4096];
1295         uint32_t msgid;
1296
1297         setup_socket_pair(&client, &server);
1298         fail_if(fcntl(client, F_SETFL, O_NONBLOCK),
1299                 "Failed to set socket to non blocking");
1300         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1301                 "Failed to set socket to non blocking");
1302
1303         out_list = buxton_array_new();
1304         fail_if(!out_list, "Failed to allocate list");
1305         cl.fd = server;
1306         slabel = buxton_string_pack("_");
1307         if (use_smack())
1308                 cl.smack_label = &slabel;
1309         else
1310                 cl.smack_label = NULL;
1311         cl.cred.uid = 1002;
1312         daemon.buxton.client.uid = 1001;
1313         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1314         fail_if(!buxton_direct_open(&daemon.buxton),
1315                 "Failed to open buxton direct connection");
1316         daemon.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1317         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1318
1319         data1.type = STRING;
1320         data1.store.d_string = buxton_string_pack("base");
1321         data2.type = STRING;
1322         data2.store.d_string = buxton_string_pack("daemon-check");
1323         data3.type = STRING;
1324         data3.store.d_string = buxton_string_pack("*");
1325         r = buxton_array_add(out_list, &data1);
1326         fail_if(!r, "Failed to add element to array");
1327         r = buxton_array_add(out_list, &data2);
1328         fail_if(!r, "Failed to add element to array");
1329         r = buxton_array_add(out_list, &data3);
1330         fail_if(!r, "Failed to add element to array");
1331
1332         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_SET_LABEL, 0,
1333                                         out_list);
1334         fail_if(size == 0, "Failed to serialize message");
1335         r = buxtond_handle_message(&daemon, &cl, size);
1336         free(cl.data);
1337         fail_if(!r, "Failed to handle set label message");
1338
1339         s = read(client, buf, 4096);
1340         fail_if(s < 0, "Read from client failed");
1341         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1342         fail_if(csize != 1, "Failed to get correct response to set label");
1343         fail_if(msg != BUXTON_CONTROL_STATUS,
1344                 "Failed to get correct control type");
1345         fail_if(list[0].type != INT32,
1346                 "Failed to get correct indicator type");
1347         fail_if(list[0].store.d_int32 != 0,
1348                 "Failed to set label");
1349         fail_if(msgid != 0, "Failed to get correct message id");
1350
1351         free(list);
1352         cleanup_callbacks();
1353         close(client);
1354         hashmap_free(daemon.notify_mapping);
1355         buxton_direct_close(&daemon.buxton);
1356         buxton_array_free(&out_list, NULL);
1357 }
1358 END_TEST
1359
1360 START_TEST(buxtond_handle_message_set_value_check)
1361 {
1362         BuxtonDaemon daemon;
1363         BuxtonString slabel;
1364         size_t size;
1365         BuxtonData data1, data2, data3, data4;
1366         client_list_item cl;
1367         bool r;
1368         BuxtonData *list;
1369         BuxtonArray *out_list;
1370         BuxtonControlMessage msg;
1371         ssize_t csize;
1372         int client, server;
1373         ssize_t s;
1374         uint8_t buf[4096];
1375         uint32_t msgid;
1376
1377         setup_socket_pair(&client, &server);
1378         fail_if(fcntl(client, F_SETFL, O_NONBLOCK),
1379                 "Failed to set socket to non blocking");
1380         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1381                 "Failed to set socket to non blocking");
1382
1383         out_list = buxton_array_new();
1384         fail_if(!out_list, "Failed to allocate list");
1385         cl.fd = server;
1386         slabel = buxton_string_pack("_");
1387         if (use_smack())
1388                 cl.smack_label = &slabel;
1389         else
1390                 cl.smack_label = NULL;
1391         cl.cred.uid = 1002;
1392         daemon.buxton.client.uid = 1001;
1393         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1394         fail_if(!buxton_direct_open(&daemon.buxton),
1395                 "Failed to open buxton direct connection");
1396         daemon.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1397         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1398
1399         data1.type = STRING;
1400         data1.store.d_string = buxton_string_pack("base");
1401         data2.type = STRING;
1402         data2.store.d_string = buxton_string_pack("daemon-check");
1403         data3.type = STRING;
1404         data3.store.d_string = buxton_string_pack("name");
1405         data4.type = STRING;
1406         data4.store.d_string = buxton_string_pack("bxt_test_value3");
1407         r = buxton_array_add(out_list, &data1);
1408         fail_if(!r, "Failed to add element to array");
1409         r = buxton_array_add(out_list, &data2);
1410         fail_if(!r, "Failed to add element to array");
1411         r = buxton_array_add(out_list, &data3);
1412         fail_if(!r, "Failed to add element to array");
1413         r = buxton_array_add(out_list, &data4);
1414         fail_if(!r, "Failed to add element to array");
1415         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_NOTIFY, 0,
1416                                         out_list);
1417         fail_if(size == 0, "Failed to serialize message");
1418         r = buxtond_handle_message(&daemon, &cl, size);
1419         free(cl.data);
1420         fail_if(r, "Failed to detect parse_list failure");
1421
1422         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_SET, 0,
1423                                         out_list);
1424         fail_if(size == 0, "Failed to serialize message");
1425         r = buxtond_handle_message(&daemon, &cl, size);
1426         free(cl.data);
1427         fail_if(!r, "Failed to handle set message");
1428
1429         s = read(client, buf, 4096);
1430         fail_if(s < 0, "Read from client failed");
1431         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1432         fail_if(csize != 1, "Failed to get correct response to set");
1433         fail_if(msg != BUXTON_CONTROL_STATUS,
1434                 "Failed to get correct control type");
1435         fail_if(list[0].type != INT32,
1436                 "Failed to get correct indicator type");
1437         fail_if(list[0].store.d_int32 != 0,
1438                 "Failed to set");
1439         fail_if(msgid != 0, "Failed to get correct message id");
1440
1441         free(list);
1442         cleanup_callbacks();
1443         close(client);
1444         hashmap_free(daemon.notify_mapping);
1445         buxton_direct_close(&daemon.buxton);
1446         buxton_array_free(&out_list, NULL);
1447 }
1448 END_TEST
1449
1450 START_TEST(buxtond_handle_message_get_check)
1451 {
1452         int client, server;
1453         BuxtonDaemon daemon;
1454         BuxtonString slabel;
1455         size_t size;
1456         BuxtonData data1, data2, data3, data4;
1457         client_list_item cl;
1458         bool r;
1459         BuxtonData *list;
1460         BuxtonArray *out_list;
1461         BuxtonArray *out_list2;
1462         BuxtonControlMessage msg;
1463         ssize_t csize;
1464         ssize_t s;
1465         uint8_t buf[4096];
1466         uint32_t msgid;
1467
1468         setup_socket_pair(&client, &server);
1469         out_list = buxton_array_new();
1470         fail_if(!out_list, "Failed to allocate list");
1471
1472         cl.fd = server;
1473         slabel = buxton_string_pack("_");
1474         if (use_smack())
1475                 cl.smack_label = &slabel;
1476         else
1477                 cl.smack_label = NULL;
1478         cl.cred.uid = getuid();
1479         daemon.buxton.client.uid = 1001;
1480         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1481         fail_if(!buxton_direct_open(&daemon.buxton),
1482                 "Failed to open buxton direct connection");
1483
1484         data1.type = STRING;
1485         data1.store.d_string = buxton_string_pack("test-gdbm-user");
1486         data2.type = STRING;
1487         data2.store.d_string = buxton_string_pack("daemon-check");
1488         data3.type = STRING;
1489         data3.store.d_string = buxton_string_pack("name");
1490         data4.type = UINT32;
1491         data4.store.d_uint32 = STRING;
1492         r = buxton_array_add(out_list, &data1);
1493         fail_if(!r, "Failed to add element to array");
1494         r = buxton_array_add(out_list, &data2);
1495         fail_if(!r, "Failed to add element to array");
1496         r = buxton_array_add(out_list, &data3);
1497         fail_if(!r, "Failed to add element to array");
1498         r = buxton_array_add(out_list, &data4);
1499         fail_if(!r, "Failed to add element to array");
1500         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_GET, 0,
1501                                         out_list);
1502         fail_if(size == 0, "Failed to serialize message");
1503         r = buxtond_handle_message(&daemon, &cl, size);
1504         free(cl.data);
1505         fail_if(!r, "Failed to get message 1");
1506
1507         s = read(client, buf, 4096);
1508         fail_if(s < 0, "Read from client failed");
1509         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1510         fail_if(csize != 2, "Failed to get valid message from buffer");
1511         fail_if(msg != BUXTON_CONTROL_STATUS,
1512                 "Failed to get correct control type");
1513         fail_if(msgid != 0, "Failed to get correct message id");
1514         fail_if(list[0].type != INT32, "Failed to get correct response type");
1515         fail_if(list[0].store.d_int32 != 0,
1516                 "Failed to get value");
1517         fail_if(list[1].type != STRING, "Failed to get correct value type");
1518         fail_if(!streq(list[1].store.d_string.value, "user-layer-value"),
1519                 "Failed to get correct value");
1520
1521         free(list[1].store.d_string.value);
1522         free(list);
1523
1524         out_list2 = buxton_array_new();
1525         fail_if(!out_list2, "Failed to allocate list 2");
1526         r = buxton_array_add(out_list2, &data2);
1527         fail_if(!r, "Failed to add element to array 2");
1528         r = buxton_array_add(out_list2, &data3);
1529         fail_if(!r, "Failed to add element to array 2");
1530         r = buxton_array_add(out_list2, &data4);
1531         fail_if(!r, "Failed to add element to array 2");
1532         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_GET, 0,
1533                                         out_list2);
1534         fail_if(size == 0, "Failed to serialize message 2");
1535         r = buxtond_handle_message(&daemon, &cl, size);
1536         free(cl.data);
1537         fail_if(!r, "Failed to get message 2");
1538
1539         s = read(client, buf, 4096);
1540         fail_if(s < 0, "Read from client failed 2");
1541         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1542         fail_if(csize != 2, "Failed to get correct response to get 2");
1543         fail_if(msg != BUXTON_CONTROL_STATUS,
1544                 "Failed to get correct control type 2");
1545         fail_if(msgid != 0, "Failed to get correct message id 2");
1546         fail_if(list[0].type != INT32, "Failed to get correct response type 2");
1547         fail_if(list[0].store.d_int32 != 0,
1548                 "Failed to get value 2");
1549         fail_if(list[1].type != STRING, "Failed to get correct value type 2");
1550         fail_if(streq(list[1].store.d_string.value, "bxt_test_value2"),
1551                 "Failed to get correct value 2");
1552
1553         free(list[1].store.d_string.value);
1554         free(list);
1555         close(client);
1556         buxton_direct_close(&daemon.buxton);
1557         buxton_array_free(&out_list, NULL);
1558         buxton_array_free(&out_list2, NULL);
1559 }
1560 END_TEST
1561
1562 START_TEST(buxtond_handle_message_notify_check)
1563 {
1564         int client, server;
1565         BuxtonDaemon daemon;
1566         BuxtonString slabel;
1567         size_t size;
1568         BuxtonData data1, data2, data3;
1569         client_list_item cl;
1570         bool r;
1571         BuxtonData *list;
1572         BuxtonArray *out_list;
1573         BuxtonControlMessage msg;
1574         ssize_t csize;
1575         ssize_t s;
1576         uint8_t buf[4096];
1577         uint32_t msgid;
1578
1579         setup_socket_pair(&client, &server);
1580         out_list = buxton_array_new();
1581         fail_if(!out_list, "Failed to allocate list");
1582
1583         cl.fd = server;
1584         slabel = buxton_string_pack("_");
1585         if (use_smack())
1586                 cl.smack_label = &slabel;
1587         else
1588                 cl.smack_label = NULL;
1589         cl.cred.uid = 1002;
1590         daemon.buxton.client.uid = 1001;
1591         daemon.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1592         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1593         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1594         fail_if(!buxton_direct_open(&daemon.buxton),
1595                 "Failed to open buxton direct connection");
1596
1597         data1.type = STRING;
1598         data1.store.d_string = buxton_string_pack("group");
1599         data2.type = STRING;
1600         data2.store.d_string = buxton_string_pack("name");
1601         data3.type = UINT32;
1602         data3.store.d_uint32 = STRING;
1603         r = buxton_array_add(out_list, &data1);
1604         fail_if(!r, "Failed to add element to array");
1605         r = buxton_array_add(out_list, &data2);
1606         fail_if(!r, "Failed to add element to array");
1607         r = buxton_array_add(out_list, &data3);
1608         fail_if(!r, "Failed to add element to array");
1609         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_NOTIFY, 0,
1610                                         out_list);
1611         fail_if(size == 0, "Failed to serialize message");
1612         r = buxtond_handle_message(&daemon, &cl, size);
1613         free(cl.data);
1614         fail_if(!r, "Failed to register for notification");
1615
1616         s = read(client, buf, 4096);
1617         fail_if(s < 0, "Read from client failed");
1618         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1619         fail_if(csize != 1, "Failed to get correct response to notify");
1620         fail_if(msg != BUXTON_CONTROL_STATUS,
1621                 "Failed to get correct control type");
1622         fail_if(msgid != 0, "Failed to get correct notify message id");
1623         fail_if(list[0].type != INT32, "Failed to get correct response type");
1624         fail_if(list[0].store.d_int32 != 0,
1625                 "Failed to register notification");
1626
1627         free(list);
1628
1629         /* UNNOTIFY */
1630         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_UNNOTIFY, 0,
1631                                         out_list);
1632         fail_if(size == 0, "Failed to serialize message");
1633         r = buxtond_handle_message(&daemon, &cl, size);
1634         free(cl.data);
1635         fail_if(!r, "Failed to unregister from notification");
1636
1637         s = read(client, buf, 4096);
1638         fail_if(s < 0, "Read from client failed 2");
1639         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1640         fail_if(csize != 2, "Failed to get correct response to unnotify");
1641         fail_if(msg != BUXTON_CONTROL_STATUS,
1642                 "Failed to get correct control type 2");
1643         fail_if(list[0].type != INT32,
1644                 "Failed to get correct indicator type 2");
1645         fail_if(list[0].store.d_int32 != 0,
1646                 "Failed to unregister for notification");
1647         fail_if(list[1].type != UINT32,
1648                 "Failed to get correct unnotify message id type");
1649         fail_if(list[1].store.d_uint32 != 0,
1650                 "Failed to get correct unnotify message id");
1651         fail_if(msgid != 0, "Failed to get correct message id 2");
1652
1653         free(list);
1654         close(client);
1655         hashmap_free(daemon.notify_mapping);
1656         buxton_direct_close(&daemon.buxton);
1657         buxton_array_free(&out_list, NULL);
1658 }
1659 END_TEST
1660
1661 START_TEST(buxtond_handle_message_unset_check)
1662 {
1663         int client, server;
1664         BuxtonDaemon daemon;
1665         BuxtonString slabel;
1666         size_t size;
1667         BuxtonData data1, data2, data3, data4;
1668         client_list_item cl;
1669         bool r;
1670         BuxtonData *list;
1671         BuxtonArray *out_list;
1672         BuxtonControlMessage msg;
1673         ssize_t csize;
1674         ssize_t s;
1675         uint8_t buf[4096];
1676         uint32_t msgid;
1677
1678         setup_socket_pair(&client, &server);
1679         out_list = buxton_array_new();
1680         fail_if(!out_list, "Failed to allocate list");
1681
1682         cl.fd = server;
1683         slabel = buxton_string_pack("_");
1684         if (use_smack())
1685                 cl.smack_label = &slabel;
1686         else
1687                 cl.smack_label = NULL;
1688         cl.cred.uid = 1002;
1689         daemon.buxton.client.uid = 1001;
1690         fail_if(!buxton_cache_smack_rules(), "Failed to cache Smack rules");
1691         fail_if(!buxton_direct_open(&daemon.buxton),
1692                 "Failed to open buxton direct connection");
1693         daemon.notify_mapping = hashmap_new(string_hash_func, string_compare_func);
1694         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1695
1696         data1.type = STRING;
1697         data1.store.d_string = buxton_string_pack("base");
1698         data2.type = STRING;
1699         data2.store.d_string = buxton_string_pack("daemon-check");
1700         data3.type = STRING;
1701         data3.store.d_string = buxton_string_pack("name");
1702         data4.type = UINT32;
1703         data4.store.d_uint32 = STRING;
1704         r = buxton_array_add(out_list, &data1);
1705         fail_if(!r, "Failed to add element to array");
1706         r = buxton_array_add(out_list, &data2);
1707         fail_if(!r, "Failed to add element to array");
1708         r = buxton_array_add(out_list, &data3);
1709         fail_if(!r, "Failed to add element to array");
1710         r = buxton_array_add(out_list, &data4);
1711         fail_if(!r, "Failed to add element to array");
1712         size = buxton_serialize_message(&cl.data, BUXTON_CONTROL_UNSET, 0,
1713                                         out_list);
1714         fail_if(size == 0, "Failed to serialize message");
1715         r = buxtond_handle_message(&daemon, &cl, size);
1716         free(cl.data);
1717         fail_if(!r, "Failed to unset message");
1718
1719         s = read(client, buf, 4096);
1720         fail_if(s < 0, "Read from client failed");
1721         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1722         fail_if(csize != 1, "Failed to get correct response to unset");
1723         fail_if(msg != BUXTON_CONTROL_STATUS,
1724                 "Failed to get correct control type");
1725         fail_if(list[0].type != INT32,
1726                 "Failed to get correct indicator type");
1727         fail_if(list[0].store.d_int32 != 0,
1728                 "Failed to unset");
1729         fail_if(msgid != 0, "Failed to get correct message id");
1730
1731         free(list);
1732         close(client);
1733         hashmap_free(daemon.notify_mapping);
1734         buxton_direct_close(&daemon.buxton);
1735         buxton_array_free(&out_list, NULL);
1736 }
1737 END_TEST
1738
1739 START_TEST(buxtond_notify_clients_check)
1740 {
1741         int client, server;
1742         BuxtonDaemon daemon;
1743         _BuxtonKey key;
1744         BuxtonString slabel;
1745         BuxtonData value1, value2;
1746         client_list_item cl;
1747         int32_t status;
1748         bool r;
1749         BuxtonData *list;
1750         BuxtonControlMessage msg;
1751         ssize_t csize;
1752         ssize_t s;
1753         uint8_t buf[4096];
1754         uint32_t msgid;
1755
1756         setup_socket_pair(&client, &server);
1757
1758         cl.fd = server;
1759         slabel = buxton_string_pack("_");
1760         if (use_smack())
1761                 cl.smack_label = &slabel;
1762         else
1763                 cl.smack_label = NULL;
1764         cl.cred.uid = 1002;
1765         daemon.notify_mapping = hashmap_new(string_hash_func,
1766                                             string_compare_func);
1767         fail_if(!daemon.notify_mapping, "Failed to allocate hashmap");
1768         fail_if(!buxton_cache_smack_rules(),
1769                 "Failed to cache Smack rules");
1770         fail_if(!buxton_direct_open(&daemon.buxton),
1771                 "Failed to open buxton direct connection");
1772
1773         value1.type = STRING;
1774         value1.store.d_string = buxton_string_pack("dummy value");
1775         key.group = buxton_string_pack("dummy");
1776         key.name = buxton_string_pack("name");
1777         buxtond_notify_clients(&daemon, &cl, &key, &value1);
1778
1779         value1.store.d_string = buxton_string_pack("real value");
1780         key.group = buxton_string_pack("daemon-check");
1781         key.name = buxton_string_pack("name");
1782         key.layer = buxton_string_pack("base");
1783         key.type = STRING;
1784         r = buxton_direct_set_value(&daemon.buxton, &key,
1785                                     &value1, NULL);
1786         fail_if(!r, "Failed to set value for notify");
1787         register_notification(&daemon, &cl, &key, 0, &status);
1788         fail_if(status != 0,
1789                 "Failed to register notification for notify");
1790         buxtond_notify_clients(&daemon, &cl, &key, &value1);
1791
1792         value2.type = STRING;
1793         value2.store.d_string = buxton_string_pack("new value");
1794         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1795
1796         s = read(client, buf, 4096);
1797         fail_if(s < 0, "Read from client failed");
1798         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1799         fail_if(csize != 1,
1800                 "Failed to get correct response to notify string");
1801         fail_if(msg != BUXTON_CONTROL_CHANGED,
1802                 "Failed to get correct control type");
1803         fail_if(msgid != 0, "Failed to get correct message id");
1804         fail_if(list[0].type != STRING,
1805                 "Failed to get correct notification value type string");
1806         fail_if(!streq(list[0].store.d_string.value, "new value"),
1807                 "Failed to get correct notification value data string");
1808
1809         free(list[0].store.d_string.value);
1810         free(list);
1811
1812         key.group = buxton_string_pack("group");
1813         key.name.value = NULL;
1814         key.name.length = 0;
1815         r = buxton_direct_create_group(&daemon.buxton, &key, NULL);
1816         fail_if(!r, "Unable to create group");
1817         r = buxton_direct_set_label(&daemon.buxton, &key, &slabel);
1818         fail_if(!r, "Unable set group label");
1819
1820         value1.type = INT32;
1821         value1.store.d_int32 = 1;
1822         value2.type = INT32;
1823         value2.store.d_int32 = 2;
1824         key.group = buxton_string_pack("group");
1825         key.name = buxton_string_pack("name32");
1826         key.type = INT32;
1827         r = buxton_direct_set_value(&daemon.buxton, &key,
1828                                     &value1, NULL);
1829         fail_if(!r, "Failed to set value for notify");
1830         register_notification(&daemon, &cl, &key, 0, &status);
1831         fail_if(status != 0,
1832                 "Failed to register notification for notify");
1833         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1834
1835         s = read(client, buf, 4096);
1836         fail_if(s < 0, "Read from client failed");
1837         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1838         fail_if(csize != 1,
1839                 "Failed to get correct response to notify int32");
1840         fail_if(msg != BUXTON_CONTROL_CHANGED,
1841                 "Failed to get correct control type");
1842         fail_if(msgid != 0, "Failed to get correct message id");
1843         fail_if(list[0].type != INT32,
1844                 "Failed to get correct notification value type int32");
1845         fail_if(list[0].store.d_int32 != 2,
1846                 "Failed to get correct notification value data int32");
1847
1848         free(list);
1849
1850         value1.type = UINT32;
1851         value1.store.d_uint32 = 1;
1852         value2.type = UINT32;
1853         value2.store.d_uint32 = 2;
1854         key.group = buxton_string_pack("group");
1855         key.name = buxton_string_pack("nameu32");
1856         key.type = UINT32;
1857         r = buxton_direct_set_value(&daemon.buxton, &key,
1858                                     &value1, NULL);
1859         fail_if(!r, "Failed to set value for notify");
1860         register_notification(&daemon, &cl, &key, 0, &status);
1861         fail_if(status != 0,
1862                 "Failed to register notification for notify");
1863         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1864
1865         s = read(client, buf, 4096);
1866         fail_if(s < 0, "Read from client failed");
1867         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1868         fail_if(csize != 1,
1869                 "Failed to get correct response to notify uint32");
1870         fail_if(msg != BUXTON_CONTROL_CHANGED,
1871                 "Failed to get correct control type");
1872         fail_if(msgid != 0, "Failed to get correct message id");
1873         fail_if(list[0].type != UINT32,
1874                 "Failed to get correct notification value type uint32");
1875         fail_if(list[0].store.d_uint32 != 2,
1876                 "Failed to get correct notification value data uint32");
1877
1878         free(list);
1879
1880         value1.type = INT64;
1881         value1.store.d_int64 = 2;
1882         value2.type = INT64;
1883         value2.store.d_int64 = 3;
1884         key.group = buxton_string_pack("group");
1885         key.name = buxton_string_pack("name64");
1886         key.type = INT64;
1887         r = buxton_direct_set_value(&daemon.buxton, &key,
1888                                     &value1, NULL);
1889         fail_if(!r, "Failed to set value for notify");
1890         register_notification(&daemon, &cl, &key, 0, &status);
1891         fail_if(status != 0,
1892                 "Failed to register notification for notify");
1893         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1894
1895         s = read(client, buf, 4096);
1896         fail_if(s < 0, "Read from client failed");
1897         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1898         fail_if(csize != 1,
1899                 "Failed to get correct response to notify int64");
1900         fail_if(msg != BUXTON_CONTROL_CHANGED,
1901                 "Failed to get correct control type");
1902         fail_if(msgid != 0, "Failed to get correct message id");
1903         fail_if(list[0].type != INT64,
1904                 "Failed to get correct notification value type int 64");
1905         fail_if(list[0].store.d_int64 != 3,
1906                 "Failed to get correct notification value data int64");
1907
1908         free(list);
1909
1910         value1.type = UINT64;
1911         value1.store.d_uint64 = 2;
1912         value2.type = UINT64;
1913         value2.store.d_uint64 = 3;
1914         key.group = buxton_string_pack("group");
1915         key.name = buxton_string_pack("nameu64");
1916         key.type = UINT64;
1917         r = buxton_direct_set_value(&daemon.buxton, &key,
1918                                     &value1, NULL);
1919         fail_if(!r, "Failed to set value for notify");
1920         register_notification(&daemon, &cl, &key, 0, &status);
1921         fail_if(status != 0,
1922                 "Failed to register notification for notify");
1923         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1924
1925         s = read(client, buf, 4096);
1926         fail_if(s < 0, "Read from client failed");
1927         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1928         fail_if(csize != 1,
1929                 "Failed to get correct response to notify uint64");
1930         fail_if(msg != BUXTON_CONTROL_CHANGED,
1931                 "Failed to get correct control type");
1932         fail_if(msgid != 0, "Failed to get correct message id");
1933         fail_if(list[0].type != UINT64,
1934                 "Failed to get correct notification value type uint64");
1935         fail_if(list[0].store.d_uint64 != 3,
1936                 "Failed to get correct notification value data uint64");
1937
1938         free(list);
1939
1940         value1.type = FLOAT;
1941         value1.store.d_float = 3.1F;
1942         value2.type = FLOAT;
1943         value2.store.d_float = 3.14F;
1944         key.group = buxton_string_pack("group");
1945         key.name = buxton_string_pack("namef");
1946         key.type = FLOAT;
1947         r = buxton_direct_set_value(&daemon.buxton, &key,
1948                                     &value1, NULL);
1949         fail_if(!r, "Failed to set value for notify");
1950         register_notification(&daemon, &cl, &key, 0, &status);
1951         fail_if(status != 0,
1952                 "Failed to register notification for notify");
1953         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1954
1955         s = read(client, buf, 4096);
1956         fail_if(s < 0, "Read from client failed");
1957         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1958         fail_if(csize != 1,
1959                 "Failed to get correct response to notify float");
1960         fail_if(msg != BUXTON_CONTROL_CHANGED,
1961                 "Failed to get correct control type");
1962         fail_if(msgid != 0, "Failed to get correct message id");
1963         fail_if(list[0].type != FLOAT,
1964                 "Failed to get correct notification value type float");
1965         fail_if(list[0].store.d_float != 3.14F,
1966                 "Failed to get correct notification value data float");
1967
1968         free(list);
1969
1970         value1.type = DOUBLE;
1971         value1.store.d_double = 3.141F;
1972         value2.type = DOUBLE;
1973         value2.store.d_double = 3.1415F;
1974         key.group = buxton_string_pack("group");
1975         key.name = buxton_string_pack("named");
1976         key.type = DOUBLE;
1977         r = buxton_direct_set_value(&daemon.buxton, &key,
1978                                     &value1, NULL);
1979         fail_if(!r, "Failed to set value for notify");
1980         register_notification(&daemon, &cl, &key, 0, &status);
1981         fail_if(status != 0,
1982                 "Failed to register notification for notify");
1983         buxtond_notify_clients(&daemon, &cl, &key, &value2);
1984
1985         s = read(client, buf, 4096);
1986         fail_if(s < 0, "Read from client failed");
1987         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
1988         fail_if(csize != 1,
1989                 "Failed to get correct response to notify double");
1990         fail_if(msg != BUXTON_CONTROL_CHANGED,
1991                 "Failed to get correct control type");
1992         fail_if(msgid != 0, "Failed to get correct message id");
1993         fail_if(list[0].type != DOUBLE,
1994                 "Failed to get correct notification value type double");
1995         fail_if(list[0].store.d_double != 3.1415F,
1996                 "Failed to get correct notification value data double");
1997
1998         free(list);
1999
2000         value1.type = BOOLEAN;
2001         value1.store.d_boolean = false;
2002         value2.type = BOOLEAN;
2003         value2.store.d_int32 = true;
2004         key.group = buxton_string_pack("group");
2005         key.name = buxton_string_pack("nameb");
2006         key.type = BOOLEAN;
2007         r = buxton_direct_set_value(&daemon.buxton, &key,
2008                                     &value1, NULL);
2009         fail_if(!r, "Failed to set value for notify");
2010         register_notification(&daemon, &cl, &key, 0, &status);
2011         fail_if(status != 0,
2012                 "Failed to register notification for notify");
2013         buxtond_notify_clients(&daemon, &cl, &key, &value2);
2014
2015         s = read(client, buf, 4096);
2016         fail_if(s < 0, "Read from client failed");
2017         csize = buxton_deserialize_message(buf, &msg, (size_t)s, &msgid, &list);
2018         fail_if(csize != 1,
2019                 "Failed to get correct response to notify bool");
2020         fail_if(msg != BUXTON_CONTROL_CHANGED,
2021                 "Failed to get correct control type");
2022         fail_if(msgid != 0, "Failed to get correct message id");
2023         fail_if(list[0].type != BOOLEAN,
2024                 "Failed to get correct notification value type bool");
2025         fail_if(list[0].store.d_boolean != true,
2026                 "Failed to get correct notification value data bool");
2027
2028         free(list);
2029         close(client);
2030         buxton_direct_close(&daemon.buxton);
2031 }
2032 END_TEST
2033
2034 START_TEST(identify_client_check)
2035 {
2036         int sender;
2037         client_list_item client;
2038         bool r;
2039         int32_t msg = 5;
2040
2041         setup_socket_pair(&client.fd, &sender);
2042         r = identify_client(&client);
2043         fail_if(r, "Identified client without message");
2044
2045         write(sender, &msg, sizeof(int32_t));
2046         r = identify_client(&client);
2047         fail_if(!r, "Identify client failed");
2048
2049         close(client.fd);
2050         close(sender);
2051 }
2052 END_TEST
2053
2054 START_TEST(add_pollfd_check)
2055 {
2056         BuxtonDaemon daemon;
2057         int fd;
2058         short events;
2059         bool a;
2060
2061         fd = 3;
2062         daemon.nfds_alloc = 0;
2063         daemon.accepting_alloc = 0;
2064         daemon.nfds = 0;
2065         daemon.pollfds = NULL;
2066         daemon.accepting = NULL;
2067         events = 1;
2068         a = true;
2069         add_pollfd(&daemon, fd, events, a);
2070         fail_if(daemon.nfds != 1, "Failed to increase nfds");
2071         fail_if(daemon.pollfds[0].fd != fd, "Failed to set pollfd");
2072         fail_if(daemon.pollfds[0].events != events, "Failed to set events");
2073         fail_if(daemon.pollfds[0].revents != 0, "Failed to set revents");
2074         fail_if(daemon.accepting[0] != a, "Failed to set accepting status");
2075         free(daemon.pollfds);
2076         free(daemon.accepting);
2077 }
2078 END_TEST
2079
2080 START_TEST(del_pollfd_check)
2081 {
2082         BuxtonDaemon daemon;
2083         int fd;
2084         short events;
2085         bool a;
2086
2087         fd = 3;
2088         daemon.nfds_alloc = 0;
2089         daemon.accepting_alloc = 0;
2090         daemon.nfds = 0;
2091         daemon.pollfds = NULL;
2092         daemon.accepting = NULL;
2093         events = 1;
2094         a = true;
2095         add_pollfd(&daemon, fd, events, a);
2096         fail_if(daemon.nfds != 1, "Failed to add pollfd");
2097         del_pollfd(&daemon, 0);
2098         fail_if(daemon.nfds != 0, "Failed to decrease nfds 1");
2099
2100         fd = 4;
2101         events = 2;
2102         a = false;
2103         add_pollfd(&daemon, fd, events, a);
2104         fail_if(daemon.nfds != 1, "Failed to increase nfds after del");
2105         fail_if(daemon.pollfds[0].fd != fd, "Failed to set pollfd after del");
2106         fail_if(daemon.pollfds[0].events != events,
2107                 "Failed to set events after del");
2108         fail_if(daemon.pollfds[0].revents != 0,
2109                 "Failed to set revents after del");
2110         fail_if(daemon.accepting[0] != a,
2111                 "Failed to set accepting status after del");
2112         fd = 5;
2113         events = 3;
2114         a = true;
2115         add_pollfd(&daemon, fd, events, a);
2116         del_pollfd(&daemon, 0);
2117         fail_if(daemon.nfds != 1, "Failed to delete fd 2");
2118         fail_if(daemon.pollfds[0].fd != fd, "Failed to set pollfd after del2");
2119         fail_if(daemon.pollfds[0].events != events,
2120                 "Failed to set events after del2");
2121         fail_if(daemon.pollfds[0].revents != 0,
2122                 "Failed to set revents after del2");
2123         fail_if(daemon.accepting[0] != a,
2124                 "Failed to set accepting status after del2");
2125 }
2126 END_TEST
2127
2128 START_TEST(handle_client_check)
2129 {
2130 }
2131 END_TEST
2132
2133 START_TEST(buxtond_eat_garbage_check)
2134 {
2135         daemon_pid = 0;
2136         sigset_t sigset;
2137         pid_t pid;
2138
2139         unlink(buxton_socket());
2140
2141         sigemptyset(&sigset);
2142         sigaddset(&sigset, SIGCHLD);
2143         sigprocmask(SIG_BLOCK, &sigset, NULL);
2144
2145         pid = fork();
2146         fail_if(pid < 0, "couldn't fork");
2147         if (pid) {              /* parent*/
2148                 BuxtonClient c;
2149                 FuzzContext fuzz;
2150                 time_t start;
2151                 bool keep_going = true;
2152                 int fd;
2153
2154
2155                 srand(0);
2156                 bzero(&fuzz, sizeof(FuzzContext));
2157
2158                 daemon_pid = pid;
2159                 usleep(250*1000);
2160                 check_did_not_crash(daemon_pid, &fuzz);
2161
2162
2163                 fail_if(time(&start) == -1, "call to time() failed");
2164                 do {
2165                         pid_t client;
2166                         ssize_t bytes;
2167                         time_t now;
2168
2169                         fail_if(time(&now) == -1, "call to time() failed");
2170                         if (now - start >= fuzz_time) {
2171                                 keep_going = false;
2172                         }
2173
2174                         fuzz.size = (unsigned int)rand() % 4096;
2175                         for (int i=0; i < fuzz.size; i++) {
2176                                 fuzz.buf[i] = (uint8_t)(rand() % 255);
2177                         }
2178                         if ((fuzz.size >= 6) && (rand() % 4096)) {
2179                                 uint16_t control = (uint16_t)((rand() % (BUXTON_CONTROL_MAX-1)) + 1);
2180
2181                                 /* magic */
2182                                 fuzz.buf[0] = 0x06;
2183                                 fuzz.buf[1] = 0x72;
2184
2185                                 /* valid message type */
2186                                 memcpy((void*)(fuzz.buf + 2), (void*)(&control), sizeof(uint16_t));
2187
2188                                 /* valid size */
2189                                 memcpy((void *)(fuzz.buf + 4), (void *)(&fuzz.size), sizeof(uint32_t));
2190                         }
2191                         client = fork();
2192                         fail_if(client == -1, "couldn't fork");
2193                         if (client == 0) {
2194                                 fd = buxton_open(&c);
2195                                 fail_if(fd == -1,
2196                                         "Open failed with daemon%s", dump_fuzz(&fuzz));
2197
2198
2199                                 bytes = write(fd, (void*)(fuzz.buf), fuzz.size);
2200                                 fail_if(bytes == -1, "write failed: %m%s", dump_fuzz(&fuzz));
2201                                 fail_unless(bytes == fuzz.size, "write was %d instead of %d", bytes, fuzz.size);
2202
2203                                 buxton_close(c);
2204                                 usleep(1*1000);
2205
2206                                 check_did_not_crash(daemon_pid, &fuzz);
2207                                 exit(0);
2208                         } else {
2209                                 int status;
2210                                 pid_t wait = waitpid(client, &status, 0);
2211                                 fail_if(wait == -1, "waitpid failed");
2212                                 fail_unless(WIFEXITED(status), "client died");
2213                                 fuzz.iteration++;
2214                         }
2215                 } while (keep_going);
2216         } else {                /* child */
2217                 exec_daemon();
2218         }
2219 }
2220 END_TEST
2221
2222 BuxtonClient c;
2223
2224 void cleanup(void)
2225 {
2226         //used to cleanup the helper groups, values, names that are needed by other fuzzed values/labels
2227
2228         fail_if(buxton_open(&c) == -1, "Cleanup: Open failed with daemon.");
2229
2230         BuxtonKey key = buxton_key_create("tempgroup", NULL, "base", STRING);
2231         fail_if(buxton_remove_group(c, key, NULL, "tempgroup", true), "Cleanup: Error at removing");
2232         buxton_key_free(key);
2233         buxton_close(c);
2234
2235 }
2236
2237 char *random_string(int str_size)
2238 {
2239         //generates random strings of maximum str_size characters
2240         //ignore this for now, it will be replaced by something more intelligent
2241
2242         int size;
2243         char *str;
2244
2245         size = rand() % str_size;
2246         str = calloc((size_t)(size + 1), sizeof(char));
2247
2248         for (int i = 0; i < size ; i++) {
2249                 str[i] = (char)(rand() % 255 + 1); //1-255, use % 25+97 to use lower-case alpha chars
2250         }
2251
2252         return str;
2253 }
2254
2255 static void SIGPIPE_handler(int signo)
2256 {
2257         buxton_close(c);
2258
2259         //reconnect
2260         fail_if(buxton_open(&c) == -1,"SIGPIPE: Open failed with daemon.");
2261 }
2262
2263 START_TEST(buxtond_fuzz_commands)
2264 {
2265 /*      Previous fuzzer had correct MAGIC, CONTROL code, Message SIZE and randomized everything else.
2266  *      This only randomizes the Data Value.
2267  *
2268  *      If you want to fuzz the protocol, use the above fuzzer.
2269  *      If you want to fuzz the daemon, use this one. Use export BUXTON_FUZZER=NEW
2270  */
2271
2272         daemon_pid = 0;
2273         pid_t pid;
2274         sigset_t sigset;
2275         struct sigaction sa;
2276         char *random_group, *random_layer, *random_label, *random_value, *random_name;
2277         int max_length = 32768;
2278         unlink(buxton_socket());
2279
2280         sigemptyset(&sigset);
2281         sigaddset(&sigset, SIGCHLD);
2282         sigprocmask(SIG_BLOCK, &sigset, NULL);
2283
2284         // since the daemon will close the connection with the client if it receives a "weird" command
2285         // we have to treat SIGPIPE
2286         memset(&sa, 0, sizeof(sa));
2287         sa.sa_handler = SIGPIPE_handler;
2288         sigaction(SIGPIPE, &sa, NULL);
2289
2290         printf("============== CAUTION!!! Fuzzer at work =================\n");
2291         FILE *f = fopen("debug_check_daemon.txt", "w");
2292         fclose(f);
2293
2294         pid = fork();
2295         fail_if(pid < 0, "couldn't fork");
2296         if (pid) {              /* parent*/
2297                 FuzzContext fuzz;
2298                 time_t start;
2299                 bool keep_going = true;
2300
2301                 srand((unsigned int) time(NULL));
2302                 bzero(&fuzz, sizeof(FuzzContext));
2303
2304                 usleep(250*1000); //wait for daemon to start
2305
2306                 fail_if(time(&start) == -1, "call to time() failed");
2307                 do {
2308                         BuxtonKey key = NULL;
2309                         time_t now;
2310
2311                         fail_if(time(&now) == -1, "call to time() failed");
2312                         if (now - start >= fuzz_time) {
2313                                 keep_going = false;
2314                         }
2315
2316                         cleanup();
2317
2318                         /* create a random group and layer */
2319                         random_group = random_string(max_length);
2320                         random_layer = random_string(max_length);
2321
2322                         key = buxton_key_create(random_group, NULL, random_layer, STRING);
2323                         fail_if(!key, "Failed to create key");
2324                         fail_if(buxton_open(&c) == -1, "Open failed with daemon.");
2325
2326                         f = fopen("debug_check_daemon.txt", "w");
2327                         fail_if(!f, "Unable to open file\n");
2328                         fprintf(f, "Create group: Group: %s\t Layer: %s\n", random_group, random_layer);
2329                         fflush(f);
2330
2331                         if (buxton_create_group(c, key, NULL, random_group, true)) {
2332                                 fprintf(f, "1: Group created!\n");
2333                         } else {
2334                                 fprintf(f, "1: Group was NOT created.\n");
2335                         }
2336                         fflush(f);
2337                         buxton_key_free(key);
2338
2339                         /* create a random group in an existing layer */
2340                         key = buxton_key_create(random_group, NULL, "base", STRING);
2341                         fail_if(!key, "Failed to create key");
2342                         fprintf(f, "Create group: Group: %s\t Layer: base\n", random_group);
2343                         fflush(f);
2344
2345                         if (buxton_create_group(c, key, NULL, random_group, true)) {
2346                                 fprintf(f, "1: Group created!\n");
2347                         } else {
2348                                 fprintf(f, "1: Group was NOT created.\n");
2349                         }
2350                         fflush(f);
2351                         buxton_key_free(key);
2352
2353                         // create a random name on random group on a random layer
2354                         random_name = random_string(max_length);
2355                         key = buxton_key_create(random_group, random_name, random_layer, STRING);
2356                         fail_if(!key, "Failed to create key");
2357
2358                         fprintf(f, "Create name: Group: %s\t Layer: %s\t Name:%s\n", random_group, random_layer, random_name);
2359                         fflush(f);
2360
2361                         if (buxton_create_group(c, key, NULL, random_group, true)) {
2362                                 fprintf(f, "2: Name created!\n");
2363                         } else {
2364                                 fprintf(f, "2: Name was NOT created.\n");
2365                         }
2366                         fflush(f);
2367                         buxton_key_free(key);
2368
2369                         // create a random name on existing group
2370                         // create group
2371                         key = buxton_key_create("tempgroup", NULL, "base", STRING);
2372                         fail_if(!key, "Failed to create key");
2373                         fail_if(buxton_create_group(c, key, NULL,"tempgroup", true), "Creating group in buxton failed.");
2374                         buxton_key_free(key);
2375
2376                         // put name on group
2377                         key = buxton_key_create("tempgroup", random_name, "base", STRING);
2378                         fail_if(!key, "Failed to create key");
2379                         fprintf(f, "Create name: Group: tempgroup\t Layer: base\t Name: %s\n", random_name);
2380
2381                         if (buxton_create_group(c, key, NULL, "tempgroup", true)) {
2382                                 fprintf(f, "2: Name created!\n");
2383                         } else {
2384                                 fprintf(f, "2: Name was NOT created.\n");
2385                         }
2386                         fflush(f);
2387                         buxton_key_free(key);
2388
2389                         // create a random value on a existing labeled group
2390                         //create the "existing" group, plus the name
2391                         random_value = random_string(max_length);
2392                         BuxtonKey group = buxton_key_create("tempgroup", NULL, "base", STRING);
2393                         fail_if(!group, "Failed to create key for group");
2394                         key = buxton_key_create("tempgroup", "name", "base", STRING);
2395                         fail_if(!key, "Failed to create key");
2396
2397                         // set the a correct label and randomized value
2398                         fprintf(f, "Set label: Group: tgroup\t Layer: base\t Value: %s\n", random_value);
2399                         fflush(f);
2400                         fail_if(buxton_set_label(c, group, "*", NULL, NULL, true), "Setting label in buxton failed.");
2401
2402                         if (buxton_set_value(c, key, random_value, NULL, "tgroup", true)) {
2403                                 fprintf(f, "3: Value was set!\n");
2404                         } else {
2405                                 fprintf(f, "3: Value was NOT set.\n");
2406                         }
2407                         fflush(f);
2408                         buxton_key_free(group);
2409                         buxton_key_free(key);
2410
2411                         //set a random label on an existing group
2412                         random_label = random_string(3);
2413                         group = buxton_key_create("tempgroup", NULL, "base", STRING);
2414                         fail_if(!group, "Failed to create key for group");
2415
2416                         fprintf(f, "Set label: Group: tempgroup\t Layer: base\t Label: %s\n", random_label);
2417                         if (buxton_set_label(c, group, random_label, NULL, group, true)) {
2418                                 fprintf(f, "3: Label was set!\n");
2419                         } else {
2420                                 fprintf(f, "3: Label was NOT set.\n");
2421                         }
2422                         fflush(f);
2423
2424                         //set random value/label on name
2425                         BuxtonKey name = buxton_key_create("tempgroup", "name", "base", STRING);
2426                         fail_if(!name, "Failed to create key for name");
2427
2428                         fprintf(f, "Set label and value: Group: tempgroup\t Layer: base\t Name: name\t Value: %s\t Label: %s \n", random_value, random_label);
2429                         if (buxton_set_value(c, name, random_value, NULL, NULL, true)) {
2430                                 fprintf(f, "4: Value on name was set!\n");
2431                         } else {
2432                                 fprintf(f, "4: Value on name  was NOT set.\n");
2433                         }
2434                         free(random_value);
2435                         fflush(f);
2436
2437                         if (buxton_set_label(c, name, random_label, NULL, name, true)) {
2438                                 fprintf(f, "4: Label on name was set!\n");
2439                         } else {
2440                                 fprintf(f, "4: Label on name was NOT set.\n");
2441                         }
2442                         fflush(f);
2443                         buxton_key_free(group);
2444                         buxton_key_free(name);
2445                         free(random_label);
2446
2447                         // remove name from group
2448                         key = buxton_key_create(random_group, random_name, random_layer, STRING);
2449                         fprintf(f, "Remove group: Group: %s\t Layer: %s\t Name:%s\n", random_group, random_layer, random_name);
2450                         if (buxton_remove_group(c, key, NULL, random_group, true)) {
2451                                 fprintf(f, "5: Name from group was removed!\n");
2452                         } else {
2453                                 fprintf(f, "5: Name from group was NOT removed.\n");
2454                         }
2455                         fflush(f);
2456                         buxton_key_free(key);
2457
2458                         // remove name from existing group
2459                         key = buxton_key_create("tempgroup", random_name, "base", STRING);
2460                         fprintf(f, "Remove group: Group: tempgroup\t Layer: base\t Name:%s\n", random_name);
2461                         if (buxton_remove_group(c, key, NULL, "tempgroup", true)) {
2462                                 fprintf(f, "5: Name from group was removed!\n");
2463                         } else {
2464                                 fprintf(f, "5: Name from group was NOT removed.\n");
2465                         }
2466                         fflush(f);
2467                         free(random_name);
2468                         buxton_key_free(key);
2469
2470                         /* remove group from existing layer*/
2471                         key = buxton_key_create(random_group, NULL, "base", STRING);
2472                         fail_if(!key, "Failed to create key");
2473                         fprintf(f, "Remove group: Group: %s\t Layer: base\n", random_group);
2474                         if (buxton_remove_group(c, key, NULL, random_group, true)) {
2475                                 fprintf(f, "5: Group was removed!\n");
2476                         } else {
2477                                 fprintf(f, "5: Group was NOT removed.\n");
2478                         }
2479                         fflush(f);
2480                         buxton_key_free(key);
2481
2482                         /* remove group */
2483                         key = buxton_key_create(random_group, NULL, random_layer, STRING);
2484                         fail_if(!key, "Failed to create key");
2485                         fprintf(f, "Remove group: Group: %s\t Layer: %s\n", random_group, random_layer);
2486                         if (buxton_remove_group(c, key, NULL, random_group, true)) {
2487                                 fprintf(f, "5: Group was removed!\n");
2488                         } else {
2489                                 fprintf(f, "5: Group was NOT removed.\n");
2490                         }
2491                         buxton_key_free(key);
2492                         fflush(f);
2493
2494                         buxton_close(c);
2495                         usleep(1*1000);
2496
2497                         fprintf(f, "5: Closed comm.\n");
2498                         fclose(f);
2499                         free(random_layer);
2500                         free(random_group);
2501
2502                         reap_callbacks();
2503                 } while (keep_going);
2504         } else {                /* child */
2505                 exec_daemon();
2506         }
2507
2508         usleep(3 * 1000);
2509         reap_callbacks();
2510 }
2511 END_TEST
2512
2513 static Suite *
2514 daemon_suite(void)
2515 {
2516         Suite *s;
2517         TCase *tc;
2518         char *fuzzer_engine;
2519
2520         s = suite_create("daemon");
2521         tc = tcase_create("daemon test functions");
2522         tcase_add_checked_fixture(tc, setup, teardown);
2523         tcase_add_test(tc, buxton_open_check);
2524         tcase_add_test(tc, buxton_create_group_check);
2525         tcase_add_test(tc, buxton_remove_group_check);
2526         tcase_add_test(tc, buxton_set_value_check);
2527         tcase_add_test(tc, buxton_set_label_check);
2528         tcase_add_test(tc, buxton_get_value_for_layer_check);
2529         tcase_add_test(tc, buxton_get_value_check);
2530         suite_add_tcase(s, tc);
2531
2532         tc = tcase_create("buxton_daemon_functions");
2533         tcase_add_test(tc, parse_list_check);
2534         tcase_add_test(tc, create_group_check);
2535         tcase_add_test(tc, remove_group_check);
2536         tcase_add_test(tc, set_label_check);
2537
2538         tcase_add_test(tc, set_value_check);
2539         tcase_add_test(tc, get_value_check);
2540         tcase_add_test(tc, register_notification_check);
2541         tcase_add_test(tc, buxtond_handle_message_error_check);
2542         tcase_add_test(tc, buxtond_handle_message_create_group_check);
2543         tcase_add_test(tc, buxtond_handle_message_remove_group_check);
2544         tcase_add_test(tc, buxtond_handle_message_set_label_check);
2545         tcase_add_test(tc, buxtond_handle_message_set_value_check);
2546         tcase_add_test(tc, buxtond_handle_message_get_check);
2547         tcase_add_test(tc, buxtond_handle_message_notify_check);
2548         tcase_add_test(tc, buxtond_handle_message_unset_check);
2549         tcase_add_test(tc, buxtond_notify_clients_check);
2550         tcase_add_test(tc, identify_client_check);
2551         tcase_add_test(tc, add_pollfd_check);
2552         tcase_add_test(tc, del_pollfd_check);
2553         tcase_add_test(tc, handle_client_check);
2554         suite_add_tcase(s, tc);
2555
2556         tc = tcase_create("buxton daemon evil tests");
2557         tcase_add_checked_fixture(tc, NULL, teardown);
2558         fuzzer_engine = getenv("BUXTON_FUZZER");
2559         if (fuzzer_engine) {
2560                 if (strcmp(fuzzer_engine,"NEW") == 0) {
2561                         tcase_add_test(tc, buxtond_fuzz_commands);
2562                 } else {
2563                         tcase_add_test(tc, buxtond_eat_garbage_check);
2564                 }
2565         } else {
2566                 tcase_add_test(tc, buxtond_eat_garbage_check);
2567         }
2568         tcase_set_timeout(tc, fuzz_time+2);
2569         suite_add_tcase(s, tc);
2570
2571         return s;
2572 }
2573
2574 int main(void)
2575 {
2576         int number_failed;
2577         Suite *s;
2578         SRunner *sr;
2579         char *fuzzenv;
2580
2581         putenv("BUXTON_CONF_FILE=" ABS_TOP_BUILDDIR "/test/test.conf");
2582         putenv("BUXTON_ROOT_CHECK=0");
2583         fuzzenv = getenv("BUXTON_FUZZ_TIME");
2584         if (fuzzenv) {
2585                 fuzz_time = atoi(fuzzenv);
2586         } else {
2587                 fuzz_time = 2;
2588         }
2589         s = daemon_suite();
2590         sr = srunner_create(s);
2591         srunner_run_all(sr, CK_VERBOSE);
2592         number_failed = srunner_ntests_failed(sr);
2593         srunner_free(sr);
2594
2595         return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
2596 }
2597
2598 /*
2599  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2600  *
2601  * Local variables:
2602  * c-basic-offset: 8
2603  * tab-width: 8
2604  * indent-tabs-mode: t
2605  * End:
2606  *
2607  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2608  * :indentSize=8:tabSize=8:noTabs=false:
2609  */