tizen 2.3 release
[external/buxton.git] / test / check_buxton.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 <stdlib.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23
24 #include "backend.h"
25 #include "buxton.h"
26 #include "buxtonresponse.h"
27 #include "check_utils.h"
28 #include "configurator.h"
29 #include "direct.h"
30 #include "protocol.h"
31 #include "serialize.h"
32 #include "util.h"
33
34 #ifdef NDEBUG
35 #error "re-run configure with --enable-debug"
36 #endif
37
38 #define BUXTON_ROOT_CHECK_ENV "BUXTON_ROOT_CHECK"
39
40 START_TEST(buxton_direct_open_check)
41 {
42         BuxtonControl c;
43         fail_if(buxton_direct_open(&c) == false,
44                 "Direct open failed without daemon.");
45         buxton_direct_close(&c);
46 }
47 END_TEST
48
49 START_TEST(buxton_direct_init_db_check)
50 {
51         BuxtonControl c;
52         BuxtonString slayer_name = buxton_string_pack("base");
53         BuxtonString ulayer_name = buxton_string_pack("user");
54         char db[PATH_MAX];
55         int r;
56         struct stat st;
57
58         fail_if(buxton_direct_open(&c) == false,
59                 "Direct open failed without daemon.");
60
61         fail_if(!buxton_direct_init_db(&c, &ulayer_name),
62                 "Failed to run init_db for user");
63
64         sprintf(db, "%s/user-%d.db", buxton_db_path(), getuid());
65         r = stat(db, &st);
66         fail_if(r != -1 && errno != ENOENT, "user db file created");
67
68         fail_if(!buxton_direct_init_db(&c, &slayer_name),
69                 "Failed to run init_db");
70
71         sprintf(db, "%s/base.db", buxton_db_path());
72         r = stat(db, &st);
73         fail_if(r != 0, "Failed to create db file");
74
75         buxton_direct_close(&c);
76 }
77 END_TEST
78
79 START_TEST(buxton_direct_create_group_check)
80 {
81         BuxtonControl c;
82         fail_if(buxton_direct_open(&c) == false,
83                 "Direct open failed without daemon.");
84         _BuxtonKey group;
85
86         group.layer = buxton_string_pack("base");
87         group.group = buxton_string_pack("tgroup");
88         group.name = (BuxtonString){ NULL, 0 };
89         group.type = STRING;
90         fail_if(!buxton_direct_create_group(&c, &group, NULL),
91                 "Create group failed");
92 }
93 END_TEST
94
95 START_TEST(buxton_direct_remove_group_check)
96 {
97         BuxtonControl c;
98         fail_if(buxton_direct_open(&c) == false,
99                 "Direct open failed without daemon.");
100         _BuxtonKey group;
101
102         group.layer = buxton_string_pack("base");
103         group.group = buxton_string_pack("tgroup");
104         group.name = (BuxtonString){ NULL, 0 };
105         group.type = STRING;
106         fail_if(!buxton_direct_remove_group(&c, &group, NULL),
107                 "Failed to remove group");
108 }
109 END_TEST
110
111 START_TEST(buxton_direct_set_value_check)
112 {
113         BuxtonControl c;
114         fail_if(buxton_direct_open(&c) == false,
115                 "Direct open failed without daemon.");
116         _BuxtonKey group;
117         BuxtonString glabel;
118         _BuxtonKey key;
119         BuxtonData data;
120
121         group.layer = buxton_string_pack("test-gdbm");
122         group.group = buxton_string_pack("bxt_test_group");
123         group.name = (BuxtonString){ NULL, 0 };
124         group.type = STRING;
125         glabel = buxton_string_pack("*");
126
127         key.layer = group.layer;
128         key.group = group.group;
129         key.name = buxton_string_pack("bxt_test_key");
130         key.type = STRING;
131
132         c.client.uid = getuid();
133         fail_if(buxton_direct_create_group(&c, &group, NULL) == false,
134                 "Creating group failed.");
135         fail_if(buxton_direct_set_label(&c, &group, &glabel) == false,
136                 "Setting group label failed.");
137         data.type = STRING;
138         data.store.d_string = buxton_string_pack("bxt_test_value");
139         fail_if(buxton_direct_set_value(&c, &key, &data, NULL) == false,
140                 "Setting value in buxton directly failed.");
141         buxton_direct_close(&c);
142 }
143 END_TEST
144
145 START_TEST(buxton_direct_get_value_for_layer_check)
146 {
147         BuxtonControl c;
148         BuxtonData result;
149         BuxtonString dlabel;
150         _BuxtonKey key;
151
152         key.layer = buxton_string_pack("test-gdbm");
153         key.group = buxton_string_pack("bxt_test_group");
154         key.name = buxton_string_pack("bxt_test_key");
155         key.type = STRING;
156
157         c.client.uid = getuid();
158         fail_if(buxton_direct_open(&c) == false,
159                 "Direct open failed without daemon.");
160         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
161                 "Retrieving value from buxton gdbm backend failed.");
162         fail_if(result.type != STRING,
163                 "Buxton gdbm backend returned incorrect result type.");
164         //FIXME get label test figured out
165         fail_if(strcmp(result.store.d_string.value, "bxt_test_value") != 0,
166                 "Buxton gdbm returned a different value to that set.");
167         if (result.store.d_string.value)
168                 free(result.store.d_string.value);
169         buxton_direct_close(&c);
170 }
171 END_TEST
172
173 START_TEST(buxton_direct_get_value_check)
174 {
175         BuxtonControl c;
176         BuxtonData data, result;
177         BuxtonString dlabel;
178         _BuxtonKey key;
179         key.layer = buxton_string_pack("test-gdbm");
180         key.group = buxton_string_pack("bxt_test_group");
181         key.name = buxton_string_pack("bxt_test_key");
182         key.type = STRING;
183
184         fail_if(buxton_direct_open(&c) == false,
185                 "Direct open failed without daemon.");
186
187         c.client.uid = getuid();
188         data.type = STRING;
189         data.store.d_string = buxton_string_pack("bxt_test_value2");
190         fail_if(data.store.d_string.value == NULL,
191                 "Failed to allocate test string.");
192         fail_if(buxton_direct_set_value(&c, &key, &data, NULL) == false,
193                 "Failed to set second value.");
194         fail_if(buxton_direct_get_value(&c, &key, &result, &dlabel, NULL) == -1,
195                 "Retrieving value from buxton gdbm backend failed.");
196         fail_if(result.type != STRING,
197                 "Buxton gdbm backend returned incorrect result type.");
198         //FIXME figure out label check
199         fail_if(strcmp(result.store.d_string.value, "bxt_test_value2") != 0,
200                 "Buxton gdbm returned a different value to that set.");
201         if (result.store.d_string.value)
202                 free(result.store.d_string.value);
203         buxton_direct_close(&c);
204 }
205 END_TEST
206
207 START_TEST(buxton_memory_backend_check)
208 {
209         BuxtonControl c;
210         BuxtonData data, result;
211         BuxtonString dlabel, glabel;
212         _BuxtonKey group;
213         _BuxtonKey key;
214
215         group.layer = buxton_string_pack("temp");
216         group.group = buxton_string_pack("bxt_mem_test_group");
217         group.name = (BuxtonString){ NULL, 0 };
218         group.type = STRING;
219         glabel = buxton_string_pack("*");
220
221         key.layer = group.layer;
222         key.group = group.group;
223         key.name = buxton_string_pack("bxt_mem_test_key");
224         key.type = STRING;
225
226         fail_if(buxton_direct_open(&c) == false,
227                 "Direct open failed without daemon.");
228
229         c.client.uid = getuid();
230         fail_if(buxton_direct_create_group(&c, &group, NULL) == false,
231                 "Creating group failed.");
232         fail_if(buxton_direct_set_label(&c, &group, &glabel) == false,
233                 "Setting group label failed.");
234         data.type = STRING;
235         data.store.d_string = buxton_string_pack("bxt_test_value");
236         fail_if(buxton_direct_set_value(&c, &key, &data, NULL) == false,
237                 "Setting value in buxton memory backend directly failed.");
238         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
239                 "Retrieving value from buxton memory backend directly failed.");
240         // FIXME: BUXTON_GROUP_VALUE is the dummy group data value, but the memory
241         // backend doesn't understand groups, so this is the current workaround.
242         fail_if(!streq(result.store.d_string.value, "bxt_test_value"),
243                 "Buxton memory returned a different value to that set.");
244         buxton_direct_close(&c);
245 }
246 END_TEST
247
248 START_TEST(buxton_key_check)
249 {
250         char *group = "group";
251         char *name = "name";
252         char *layer = "layer";
253         BuxtonKey key;
254         char *g;
255         char *n;
256         char *l;
257         BuxtonDataType type = STRING;
258
259         key = buxton_key_create(group, name, layer, type);
260         fail_if(!key, "Failed to create buxton key");
261         g = buxton_key_get_group(key);
262         n = buxton_key_get_name(key);
263         l = buxton_key_get_layer(key);
264         fail_if(!g, "Failed to get group from key");
265         fail_if(!n, "Failed to get name from key");
266         fail_if(!l, "Failed to get layer from key");
267         fail_if(buxton_key_get_type(key) != type,
268                 "Failed to get correct type from key");
269         fail_if(!streq(g, group), "Got different group back from key");
270         fail_if(!streq(n, name), "Got different name back from key");
271         fail_if(!streq(l, layer), "Got different layer back from key");
272         free(g);
273         free(n);
274         free(l);
275         buxton_key_free(key);
276
277         fail_if(buxton_key_create(NULL, name, layer, type), "Got key back with invalid group");
278         fail_if(buxton_key_create(group, name, layer, BUXTON_TYPE_MIN),
279                 "Got key back with invalid type 1");
280         fail_if(buxton_key_create(group, name, layer, BUXTON_TYPE_MAX),
281                 "Got key back with invalid type 2");
282
283         key = buxton_key_create(group, NULL, layer, type);
284         fail_if(!key, "Failed to create buxton key with empty name");
285         fail_if(buxton_key_get_name(key), "Got name back with no name key");
286         buxton_key_free(key);
287
288         key = buxton_key_create(group, name, NULL, type);
289         fail_if(!key, "Failed to create buxton key with empty layer");
290         fail_if(buxton_key_get_layer(key), "Got layer back with no layer key");
291         buxton_key_free(key);
292 }
293 END_TEST
294
295 START_TEST(buxton_set_label_check)
296 {
297         BuxtonControl c;
298         BuxtonString label = buxton_string_pack("*");
299         _BuxtonKey key;
300         key.layer = buxton_string_pack("test-gdbm");
301         key.group = buxton_string_pack("bxt_test");
302         key.name.value = NULL;
303         key.type = STRING;
304         char *root_check = getenv(BUXTON_ROOT_CHECK_ENV);
305         bool skip_check = (root_check && streq(root_check, "0"));
306
307         c.client.uid = 0;
308         fail_if(buxton_direct_open(&c) == false,
309                 "Direct open failed without daemon.");
310         fail_if(buxton_direct_create_group(&c, &key, NULL) == false,
311                 "Creating group failed.");
312         fail_if(buxton_direct_set_label(&c, &key, &label) == false,
313                 "Failed to set label as root user.");
314
315         c.client.uid = 1000;
316
317         if (skip_check)
318                 fail_if(!buxton_direct_set_label(&c, &key, &label),
319                         "Unable to set label with root check disabled");
320         else
321                 fail_if(buxton_direct_set_label(&c, &key, &label),
322                         "Able to set label as non-root user.");
323
324         buxton_direct_close(&c);
325 }
326 END_TEST
327
328 START_TEST(buxton_group_label_check)
329 {
330         BuxtonControl c;
331         BuxtonData result;
332         BuxtonString dlabel;
333         BuxtonString label = buxton_string_pack("*");
334         _BuxtonKey key;
335         key.layer = buxton_string_pack("test-gdbm");
336         key.group = buxton_string_pack("test-group");
337         key.name.value = NULL;
338         key.type = STRING;
339
340
341         c.client.uid = 0;
342         fail_if(buxton_direct_open(&c) == false,
343                 "Direct open failed without daemon.");
344         fail_if(buxton_direct_create_group(&c, &key, NULL) == false,
345                 "Creating group failed.");
346         fail_if(buxton_direct_set_label(&c, &key, &label) == false,
347                 "Failed to set group label.");
348         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
349                 "Retrieving group label failed.");
350         fail_if(!streq("*", dlabel.value),
351                 "Retrieved group label is incorrect.");
352
353         free(dlabel.value);
354         buxton_direct_close(&c);
355 }
356 END_TEST
357
358 START_TEST(buxton_name_label_check)
359 {
360         BuxtonControl c;
361         BuxtonData data, result;
362         BuxtonString label, dlabel;
363         _BuxtonKey key;
364
365         /* create the group first, and validate the label */
366         key.layer = buxton_string_pack("test-gdbm");
367         key.group = buxton_string_pack("group-foo");
368         key.name.value = NULL;
369         key.type = STRING;
370         label = buxton_string_pack("*");
371
372         c.client.uid = 0;
373         fail_if(buxton_direct_open(&c) == false,
374                 "Direct open failed without daemon.");
375         fail_if(buxton_direct_create_group(&c, &key, NULL) == false,
376                 "Creating group failed.");
377         fail_if(buxton_direct_set_label(&c, &key, &label) == false,
378                 "Failed to set group label.");
379         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
380                 "Retrieving group label failed.");
381         fail_if(!streq("*", dlabel.value),
382                 "Retrieved group label is incorrect.");
383         free(dlabel.value);
384         free(result.store.d_string.value);
385
386         /* then create the name (key), and validate the label */
387         key.name = buxton_string_pack("name-foo");
388         data.type = STRING;
389         data.store.d_string = buxton_string_pack("value1-foo");
390         fail_if(buxton_direct_set_value(&c, &key, &data, NULL) == false,
391                 "Failed to set key name-foo.");
392         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
393                 "Failed to get value for name-foo 1");
394         fail_if(!streq("value1-foo", result.store.d_string.value),
395                 "Retrieved key value is incorrect 1");
396         fail_if(!streq(dlabel.value, "_"), "Failed to set default label");
397         free(dlabel.value);
398         free(result.store.d_string.value);
399         fail_if(buxton_direct_set_label(&c, &key, &label) == false,
400                 "Failed to set name label.");
401         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
402                 "Failed to get value for name-foo 2");
403         fail_if(!streq("value1-foo", result.store.d_string.value),
404                 "Retrieved key value is incorrect 2");
405         fail_if(!streq("*", dlabel.value),
406                 "Retrieved key label is incorrect.");
407         free(dlabel.value);
408         free(result.store.d_string.value);
409
410         /* modify the same key, with a new value, and validate the label */
411         data.store.d_string = buxton_string_pack("value2-foo");
412         fail_if(buxton_direct_set_value(&c, &key, &data, NULL) == false,
413                 "Failed to modify key name-foo.");
414         fail_if(buxton_direct_get_value_for_layer(&c, &key, &result, &dlabel, NULL),
415                 "Failed to get new value for name-foo.");
416         fail_if(!streq("value2-foo", result.store.d_string.value),
417                 "New key value is incorrect.");
418         fail_if(!streq("*", dlabel.value),
419                 "Key label has been modified.");
420
421         /* modify the key label directly once it has been created */
422         fail_if(buxton_direct_set_label(&c, &key, &label) == false,
423                 "Failed to modify label on key.");
424
425         free(dlabel.value);
426         free(result.store.d_string.value);
427
428         buxton_direct_close(&c);
429 }
430 END_TEST
431
432 static int run_callback_test_value = 0;
433 static void run_callback_cb_test(BuxtonResponse response, void *data)
434 {
435         _BuxtonResponse *r = (_BuxtonResponse *)response;
436         BuxtonData *d;
437         bool *b;
438
439         fail_if(r->type != BUXTON_CONTROL_SET, "Unexpected response type");
440
441         fail_if(!streq(r->key->group.value, "group"),
442                 "Failed to set key's group");
443
444         switch (run_callback_test_value) {
445         case 0:
446                 /* first pass through */
447                 run_callback_test_value = 1;
448                 break;
449         case 1:
450                 /* second pass through */
451                 fail_if(r->data->len != 1, "Failed setup array size");
452                 d = buxton_array_get(r->data, 0);
453                 fail_if(!d, "Failed to set array element");
454                 fail_if(d->type != INT32, "Failed to setup array element value");
455                 run_callback_test_value = 2;
456                 break;
457         case 2:
458                 /* third pass through */
459                 b = (bool *)data;
460                 *b = true;
461                 break;
462         default:
463                 fail("Unexpected test value");
464                 break;
465         }
466 }
467 START_TEST(run_callback_check)
468 {
469         bool data = false;
470         BuxtonData list[] = {
471                 {INT32, {.d_int32 = 1}}
472         };
473         _BuxtonKey key;
474         key.group = buxton_string_pack("group");
475
476         run_callback(NULL, (void *)&data, 1, list, BUXTON_CONTROL_SET, &key);
477         run_callback(run_callback_cb_test, NULL, 0, NULL, BUXTON_CONTROL_SET,
478                      &key);
479         fail_if(run_callback_test_value != 1,
480                 "Failed to update callback test value 1");
481         run_callback(run_callback_cb_test, NULL, 1, list, BUXTON_CONTROL_SET,
482                      &key);
483         fail_if(run_callback_test_value != 2,
484                 "Failed to update callback test value 2");
485         run_callback(run_callback_cb_test, (void *)&data, 0, NULL,
486                      BUXTON_CONTROL_SET, &key);
487         fail_if(!data, "Failed to update callback test value 3");
488 }
489 END_TEST
490
491 START_TEST(send_message_check)
492 {
493         _BuxtonClient client;
494         BuxtonArray *out_list = NULL;
495         BuxtonData *list = NULL;
496         int server;
497         uint8_t *dest = NULL;
498         uint8_t *source = NULL;
499         size_t size;
500         BuxtonData data;
501
502         setup_socket_pair(&(client.fd), &server);
503         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
504                 "Failed to set socket to non blocking");
505         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
506                 "Failed to set socket to non blocking");
507
508         fail_if(!setup_callbacks(),
509                 "Failed to setup callbacks");
510
511         out_list = buxton_array_new();
512         data.type = INT32;
513         data.store.d_int32 = 0;
514         fail_if(!buxton_array_add(out_list, &data),
515                 "Failed to add get response to array");
516         size = buxton_serialize_message(&source, BUXTON_CONTROL_STATUS,
517                                         0, out_list);
518         fail_if(size == 0, "Failed to serialize message");
519         fail_if(!send_message(&client, source, size, NULL, NULL, 0,
520                               BUXTON_CONTROL_STATUS, NULL),
521                 "Failed to write message 1");
522
523         cleanup_callbacks();
524         buxton_array_free(&out_list, NULL);
525         free(dest);
526         free(list);
527         close(server);
528         close(client.fd);
529 }
530 END_TEST
531
532 static void handle_response_cb_test(_BuxtonResponse *response, void *data)
533 {
534         bool *val = (bool *)data;
535         fail_if(!(*val), "Got unexpected response data");
536         *val = false;
537 }
538 START_TEST(handle_callback_response_check)
539 {
540         _BuxtonClient client;
541         BuxtonArray *out_list = NULL;
542         uint8_t *dest = NULL;
543         int server;
544         size_t size;
545         bool test_data;
546         BuxtonData data;
547         uint32_t msgid;
548         BuxtonData good[] = {
549                 {INT32, {.d_int32 = 0}}
550         };
551         BuxtonData good_unnotify[] = {
552                 {INT32,  {.d_int32 = 0   }},
553                 {STRING, {.d_string = {0}}},
554                 {UINT32, {.d_uint32 = 4  }}
555         };
556         BuxtonData bad1[] = {
557                 {INT64, {.d_int64 = 0}}
558         };
559         BuxtonData bad2[] = {
560                 {INT32, {.d_int32 = 1}}
561         };
562
563         setup_socket_pair(&(client.fd), &server);
564         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
565                 "Failed to set socket to non blocking");
566         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
567                 "Failed to set socket to non blocking");
568
569         /* done just to create a callback to be used */
570         fail_if(!setup_callbacks(),
571                 "Failed to initialeze response callbacks");
572         out_list = buxton_array_new();
573         data.type = INT32;
574         data.store.d_int32 = 0;
575         msgid = 1;
576         fail_if(!buxton_array_add(out_list, &data),
577                 "Failed to add data to array");
578         size = buxton_serialize_message(&dest, BUXTON_CONTROL_STATUS,
579                                         msgid, out_list);
580         buxton_array_free(&out_list, NULL);
581         fail_if(size == 0, "Failed to serialize message");
582
583         test_data = true;
584         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
585                               &test_data, msgid, BUXTON_CONTROL_SET, NULL),
586                 "Failed to send message %d", msgid);
587         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, bad1, 1);
588         fail_if(test_data, "Failed to set cb data non notify type");
589
590         test_data = true;
591         msgid = 2;
592         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
593                               &test_data, msgid, BUXTON_CONTROL_NOTIFY, NULL),
594                 "Failed to send message %d", msgid);
595         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, bad1, 1);
596         fail_if(test_data, "Failed to set notify bad1 data");
597
598         test_data = true;
599         msgid = 3;
600         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
601                               &test_data, msgid, BUXTON_CONTROL_NOTIFY, NULL),
602                 "Failed to send message %d", msgid);
603         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, bad2, 1);
604         fail_if(test_data, "Failed to set notify bad2 data");
605
606         test_data = true;
607         msgid = 4;
608         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
609                               &test_data, msgid, BUXTON_CONTROL_NOTIFY, NULL),
610                 "Failed to send message %d", msgid);
611         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, good, 1);
612         fail_if(!test_data, "Set notify good data");
613
614         /* ensure we run callback on duplicate msgid */
615         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
616                               &test_data, msgid, BUXTON_CONTROL_NOTIFY, NULL),
617                 "Failed to send message %d-2", msgid);
618         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, good, 1);
619         fail_if(test_data, "Failed to set notify duplicate msgid");
620
621         test_data = true;
622         handle_callback_response(BUXTON_CONTROL_CHANGED, msgid, good, 1);
623         fail_if(test_data, "Failed to set changed data");
624
625         /* ensure we don't remove callback on changed */
626         test_data = true;
627         handle_callback_response(BUXTON_CONTROL_CHANGED, msgid, good, 1);
628         fail_if(test_data, "Failed to set changed data");
629
630         test_data = true;
631         msgid = 6;
632         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
633                               &test_data, msgid, BUXTON_CONTROL_UNNOTIFY, NULL),
634                 "Failed to send message %d", msgid);
635         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, bad1, 1);
636         fail_if(test_data, "Failed to set unnotify bad1 data");
637
638         test_data = true;
639         msgid = 7;
640         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
641                               &test_data, msgid, BUXTON_CONTROL_UNNOTIFY, NULL),
642                 "Failed to send message %d", msgid);
643         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, bad2, 1);
644         fail_if(test_data, "Failed to set unnotify bad2 data");
645
646         test_data = true;
647         msgid = 8;
648         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
649                               &test_data, msgid, BUXTON_CONTROL_UNNOTIFY, NULL),
650                 "Failed to send message %d", msgid);
651         handle_callback_response(BUXTON_CONTROL_STATUS, msgid, good_unnotify, 1);
652         fail_if(!test_data, "Set unnotify good data");
653
654         test_data = true;
655         msgid = 4;
656         handle_callback_response(BUXTON_CONTROL_CHANGED, msgid, good, 1);
657         fail_if(!test_data, "Didn't remove changed callback");
658
659         cleanup_callbacks();
660         free(dest);
661         close(client.fd);
662         close(server);
663 }
664 END_TEST
665
666 START_TEST(buxton_wire_handle_response_check)
667 {
668         _BuxtonClient client;
669         BuxtonArray *out_list = NULL;
670         int server;
671         uint8_t *dest = NULL;
672         size_t size;
673         BuxtonData data;
674         bool test_data = true;
675
676         setup_socket_pair(&(client.fd), &server);
677         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
678                 "Failed to set socket to non blocking");
679         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
680                 "Failed to set socket to non blocking");
681
682         /* done just to create a callback to be used */
683         fail_if(!setup_callbacks(),
684                 "Failed to initialeze get response callbacks");
685         out_list = buxton_array_new();
686         data.type = INT32;
687         data.store.d_int32 = 0;
688         fail_if(!buxton_array_add(out_list, &data),
689                 "Failed to add get response to array");
690         size = buxton_serialize_message(&dest, BUXTON_CONTROL_STATUS,
691                                         0, out_list);
692         buxton_array_free(&out_list, NULL);
693         fail_if(size == 0, "Failed to serialize message");
694         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
695                               &test_data, 0, BUXTON_CONTROL_STATUS, NULL),
696                 "Failed to send message");
697
698         /* server */
699         fail_if(!_write(server, dest, size),
700                 "Failed to send get response");
701
702         /* client */
703         fail_if(buxton_wire_handle_response(&client) != 1,
704                 "Failed to handle response correctly");
705         fail_if(test_data, "Failed to update data");
706
707         cleanup_callbacks();
708         free(dest);
709         close(client.fd);
710         close(server);
711 }
712 END_TEST
713
714 START_TEST(buxton_wire_get_response_check)
715 {
716         _BuxtonClient client;
717         BuxtonArray *out_list = NULL;
718         int server;
719         uint8_t *dest = NULL;
720         size_t size;
721         BuxtonData data;
722         bool test_data = true;
723
724         setup_socket_pair(&(client.fd), &server);
725         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
726                 "Failed to set socket to non blocking");
727         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
728                 "Failed to set socket to non blocking");
729
730         /* done just to create a callback to be used */
731         fail_if(!setup_callbacks(),
732                 "Failed to initialeze callbacks");
733         out_list = buxton_array_new();
734         data.type = INT32;
735         data.store.d_int32 = 0;
736         fail_if(!buxton_array_add(out_list, &data),
737                 "Failed to add data to array");
738         size = buxton_serialize_message(&dest, BUXTON_CONTROL_STATUS,
739                                         0, out_list);
740         buxton_array_free(&out_list, NULL);
741         fail_if(size == 0, "Failed to serialize message");
742         fail_if(!send_message(&client, dest, size, handle_response_cb_test,
743                               &test_data, 0, BUXTON_CONTROL_STATUS, NULL),
744                 "Failed to send message");
745
746         /* server */
747         fail_if(!_write(server, dest, size),
748                 "Failed to send get response");
749
750         /* client */
751         fail_if(!buxton_wire_get_response(&client),
752                 "Failed to handle response correctly");
753         fail_if(test_data, "Failed to update data");
754
755         cleanup_callbacks();
756         free(dest);
757         close(client.fd);
758         close(server);
759 }
760 END_TEST
761
762 START_TEST(buxton_wire_set_value_check)
763 {
764         _BuxtonClient client;
765         int server;
766         ssize_t size;
767         BuxtonData *list = NULL;
768         uint8_t buf[4096];
769         ssize_t r;
770         _BuxtonKey key;
771         BuxtonControlMessage msg;
772         uint32_t msgid;
773
774         setup_socket_pair(&(client.fd), &server);
775         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
776                 "Failed to set socket to non blocking");
777         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
778                 "Failed to set socket to non blocking");
779
780         fail_if(!setup_callbacks(),
781                 "Failed to initialeze callbacks");
782
783         key.layer = buxton_string_pack("layer");
784         key.group = buxton_string_pack("group");
785         key.name = buxton_string_pack("name");
786         key.type = STRING;
787
788         fail_if(buxton_wire_set_value(&client, &key, "value", NULL,
789                                       NULL) != true,
790                 "Failed to properly set value");
791
792         r = read(server, buf, 4096);
793         fail_if(r < 0, "Read from client failed");
794         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
795         fail_if(size != 4, "Failed to get valid message from buffer");
796         fail_if(msg != BUXTON_CONTROL_SET,
797                 "Failed to get correct control type");
798         fail_if(list[0].type != STRING, "Failed to set correct layer type");
799         fail_if(list[1].type != STRING, "Failed to set correct group type");
800         fail_if(list[2].type != STRING, "Failed to set correct name type");
801         fail_if(list[3].type != STRING, "Failed to set correct value type");
802         fail_if(!streq(list[0].store.d_string.value, "layer"),
803                 "Failed to set correct layer");
804         fail_if(!streq(list[1].store.d_string.value, "group"),
805                 "Failed to set correct group");
806         fail_if(!streq(list[2].store.d_string.value, "name"),
807                 "Failed to set correct name");
808         fail_if(!streq(list[3].store.d_string.value, "value"),
809                 "Failed to set correct value");
810
811         free(list[0].store.d_string.value);
812         free(list[1].store.d_string.value);
813         free(list[2].store.d_string.value);
814         free(list[3].store.d_string.value);
815         free(list);
816         cleanup_callbacks();
817         close(client.fd);
818         close(server);
819 }
820 END_TEST
821
822 START_TEST(buxton_wire_set_label_check)
823 {
824         _BuxtonClient client;
825         int server;
826         ssize_t size;
827         BuxtonData *list = NULL;
828         uint8_t buf[4096];
829         ssize_t r;
830         _BuxtonKey key;
831         BuxtonString value;
832         BuxtonControlMessage msg;
833         uint32_t msgid;
834
835         client.uid = 0;
836         setup_socket_pair(&(client.fd), &server);
837         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
838                 "Failed to set socket to non blocking");
839         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
840                 "Failed to set socket to non blocking");
841
842         fail_if(!setup_callbacks(),
843                 "Failed to initialize callbacks");
844
845         /* first, set a label on a group */
846         key.layer = buxton_string_pack("layer");
847         key.group = buxton_string_pack("group");
848         key.name.value = NULL;
849         value = buxton_string_pack("*");
850         fail_if(buxton_wire_set_label(&client, &key, &value, NULL,
851                                       NULL) != true,
852                 "Failed to properly set label");
853
854         r = read(server, buf, 4096);
855         fail_if(r < 0, "Read from client failed");
856         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
857         fail_if(size != 3, "Failed to get valid message from buffer");
858         fail_if(msg != BUXTON_CONTROL_SET_LABEL,
859                 "Failed to get correct control type");
860         fail_if(list[0].type != STRING, "Failed to set correct layer type");
861         fail_if(list[1].type != STRING, "Failed to set correct group type");
862         fail_if(list[2].type != STRING, "Failed to set correct label type");
863         fail_if(!streq(list[0].store.d_string.value, "layer"),
864                 "Failed to set correct layer");
865         fail_if(!streq(list[1].store.d_string.value, "group"),
866                 "Failed to set correct group");
867         fail_if(!streq(list[2].store.d_string.value, "*"),
868                 "Failed to set correct label");
869
870         free(list[0].store.d_string.value);
871         free(list[1].store.d_string.value);
872         free(list[2].store.d_string.value);
873         free(list);
874
875         /* ... then, set a label on a key */
876         key.layer = buxton_string_pack("layer");
877         key.group = buxton_string_pack("group");
878         key.name = buxton_string_pack("name");
879         value = buxton_string_pack("*");
880         fail_if(buxton_wire_set_label(&client, &key, &value, NULL,
881                                       NULL) != true,
882                 "Failed to properly set label");
883
884         r = read(server, buf, 4096);
885         fail_if(r < 0, "Read from client failed");
886         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
887         fail_if(size != 4, "Failed to get valid message from buffer");
888         fail_if(msg != BUXTON_CONTROL_SET_LABEL,
889                 "Failed to get correct control type");
890         fail_if(list[0].type != STRING, "Failed to set correct layer type");
891         fail_if(list[1].type != STRING, "Failed to set correct group type");
892         fail_if(list[2].type != STRING, "Failed to set correct name type");
893         fail_if(list[3].type != STRING, "Failed to set correct label type");
894         fail_if(!streq(list[0].store.d_string.value, "layer"),
895                 "Failed to set correct layer");
896         fail_if(!streq(list[1].store.d_string.value, "group"),
897                 "Failed to set correct group");
898         fail_if(!streq(list[2].store.d_string.value, "name"),
899                 "Failed to set correct name");
900         fail_if(!streq(list[3].store.d_string.value, "*"),
901                 "Failed to set correct label");
902
903         free(list[0].store.d_string.value);
904         free(list[1].store.d_string.value);
905         free(list[2].store.d_string.value);
906         free(list[3].store.d_string.value);
907         free(list);
908
909         cleanup_callbacks();
910         close(client.fd);
911         close(server);
912 }
913 END_TEST
914
915 START_TEST(buxton_wire_get_value_check)
916 {
917         _BuxtonClient client;
918         int server;
919         ssize_t size;
920         BuxtonData *list = NULL;
921         uint8_t buf[4096];
922         ssize_t r;
923         _BuxtonKey key;
924         BuxtonControlMessage msg;
925         uint32_t msgid;
926
927         setup_socket_pair(&(client.fd), &server);
928         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
929                 "Failed to set socket to non blocking");
930         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
931                 "Failed to set socket to non blocking");
932
933         fail_if(!setup_callbacks(),
934                 "Failed to initialeze callbacks");
935
936         key.layer = buxton_string_pack("layer");
937         key.group = buxton_string_pack("group");
938         key.name = buxton_string_pack("name");
939         key.type = STRING;
940         fail_if(buxton_wire_get_value(&client, &key, NULL,
941                                       NULL) != true,
942                 "Failed to properly get value 1");
943
944         r = read(server, buf, 4096);
945         fail_if(r < 0, "Read from client failed 1");
946         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
947         fail_if(size != 4, "Failed to get valid message from buffer 1");
948         fail_if(msg != BUXTON_CONTROL_GET,
949                 "Failed to get correct control type 1");
950         fail_if(list[0].type != STRING, "Failed to set correct layer type 1");
951         fail_if(list[1].type != STRING, "Failed to set correct group type 1");
952         fail_if(list[2].type != STRING, "Failed to set correct name type 1");
953         fail_if(list[3].type != UINT32, "Failed to set correct type type 1");
954         fail_if(!streq(list[0].store.d_string.value, "layer"),
955                 "Failed to set correct layer 1");
956         fail_if(!streq(list[1].store.d_string.value, "group"),
957                 "Failed to set correct group 1");
958         fail_if(!streq(list[2].store.d_string.value, "name"),
959                 "Failed to set correct name 1");
960         fail_if(list[3].store.d_uint32 != STRING,
961                 "Failed to set correct type 1");
962
963         free(list[0].store.d_string.value);
964         free(list[1].store.d_string.value);
965         free(list[2].store.d_string.value);
966         free(list);
967
968         key.layer.value = NULL;
969         fail_if(buxton_wire_get_value(&client, &key, NULL,
970                                       NULL) != true,
971                 "Failed to properly get value 2");
972
973         r = read(server, buf, 4096);
974         fail_if(r < 0, "Read from client failed 2");
975         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
976         fail_if(size != 3, "Failed to get valid message from buffer 2");
977         fail_if(msg != BUXTON_CONTROL_GET,
978                 "Failed to get correct control type 2");
979         fail_if(list[0].type != STRING, "Failed to set correct group type 2");
980         fail_if(list[1].type != STRING, "Failed to set correct name type 2");
981         fail_if(list[2].type != UINT32, "Failed to set correct type type 2");
982         fail_if(!streq(list[0].store.d_string.value, "group"),
983                 "Failed to set correct group 2");
984         fail_if(!streq(list[1].store.d_string.value, "name"),
985                 "Failed to set correct name 2");
986         fail_if(list[2].store.d_uint32 != STRING,
987                 "Failed to set correct type 2");
988
989         free(list[0].store.d_string.value);
990         free(list[1].store.d_string.value);
991         free(list);
992
993         cleanup_callbacks();
994         close(client.fd);
995         close(server);
996 }
997 END_TEST
998
999 START_TEST(buxton_wire_unset_value_check)
1000 {
1001         _BuxtonClient client;
1002         int server;
1003         ssize_t size;
1004         BuxtonData *list = NULL;
1005         uint8_t buf[4096];
1006         ssize_t r;
1007         _BuxtonKey key;
1008         BuxtonControlMessage msg;
1009         uint32_t msgid;
1010
1011         setup_socket_pair(&(client.fd), &server);
1012         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
1013                 "Failed to set socket to non blocking");
1014         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1015                 "Failed to set socket to non blocking");
1016
1017         fail_if(!setup_callbacks(),
1018                 "Failed to initialeze callbacks");
1019
1020         key.layer = buxton_string_pack("layer");
1021         key.group = buxton_string_pack("group");
1022         key.name = buxton_string_pack("name");
1023         key.type = STRING;
1024         fail_if(!buxton_wire_unset_value(&client, &key, NULL,
1025                                          NULL),
1026                 "Failed to properly unset value");
1027
1028         r = read(server, buf, 4096);
1029         fail_if(r < 0, "Read from client failed");
1030         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
1031         fail_if(size != 4, "Failed to get valid message from buffer");
1032         fail_if(msg != BUXTON_CONTROL_UNSET,
1033                 "Failed to get correct control type");
1034         fail_if(list[0].type != STRING, "Failed to set correct layer type");
1035         fail_if(list[1].type != STRING, "Failed to set correct group type");
1036         fail_if(list[2].type != STRING, "Failed to set correct name type");
1037         fail_if(list[3].type != UINT32, "Failed to set correct type type");
1038         fail_if(!streq(list[0].store.d_string.value, "layer"),
1039                 "Failed to set correct layer");
1040         fail_if(!streq(list[1].store.d_string.value, "group"),
1041                 "Failed to set correct group");
1042         fail_if(!streq(list[2].store.d_string.value, "name"),
1043                 "Failed to set correct group");
1044         fail_if(list[3].store.d_uint32 != STRING,
1045                 "Failed to set correct type");
1046
1047         free(list[0].store.d_string.value);
1048         free(list[1].store.d_string.value);
1049         free(list[2].store.d_string.value);
1050         free(list);
1051
1052         cleanup_callbacks();
1053         close(client.fd);
1054         close(server);
1055 }
1056 END_TEST
1057
1058 START_TEST(buxton_wire_create_group_check)
1059 {
1060         _BuxtonClient client;
1061         int server;
1062         ssize_t size;
1063         BuxtonData *list = NULL;
1064         uint8_t buf[4096];
1065         ssize_t r;
1066         _BuxtonKey key;
1067         BuxtonControlMessage msg;
1068         uint32_t msgid;
1069
1070         client.uid = 0;
1071         setup_socket_pair(&(client.fd), &server);
1072         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
1073                 "Failed to set socket to non blocking");
1074         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1075                 "Failed to set socket to non blocking");
1076
1077         fail_if(!setup_callbacks(),
1078                 "Failed to initialize callbacks");
1079
1080         key.layer = buxton_string_pack("layer");
1081         key.group = buxton_string_pack("group");
1082         key.name.value = NULL;
1083         fail_if(buxton_wire_create_group(&client, &key, NULL,
1084                                          NULL) != true,
1085                 "Failed to send message");
1086
1087         r = read(server, buf, 4096);
1088         fail_if(r < 0, "Read from client failed");
1089         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
1090         fail_if(size != 2, "Failed to get valid message from buffer");
1091         fail_if(msg != BUXTON_CONTROL_CREATE_GROUP,
1092                 "Failed to get correct control type");
1093         fail_if(list[0].type != STRING, "Failed to set correct layer type");
1094         fail_if(list[1].type != STRING, "Failed to set correct group type");
1095         fail_if(!streq(list[0].store.d_string.value, "layer"),
1096                 "Failed to set correct layer");
1097         fail_if(!streq(list[1].store.d_string.value, "group"),
1098                 "Failed to set correct group");
1099
1100         free(list[0].store.d_string.value);
1101         free(list[1].store.d_string.value);
1102         free(list);
1103         cleanup_callbacks();
1104         close(client.fd);
1105         close(server);
1106 }
1107 END_TEST
1108
1109 START_TEST(buxton_wire_remove_group_check)
1110 {
1111         _BuxtonClient client;
1112         int server;
1113         ssize_t size;
1114         BuxtonData *list = NULL;
1115         uint8_t buf[4096];
1116         ssize_t r;
1117         _BuxtonKey key;
1118         BuxtonControlMessage msg;
1119         uint32_t msgid;
1120
1121         client.uid = 0;
1122         setup_socket_pair(&(client.fd), &server);
1123         fail_if(fcntl(client.fd, F_SETFL, O_NONBLOCK),
1124                 "Failed to set socket to non blocking");
1125         fail_if(fcntl(server, F_SETFL, O_NONBLOCK),
1126                 "Failed to set socket to non blocking");
1127
1128         fail_if(!setup_callbacks(),
1129                 "Failed to initialize callbacks");
1130
1131         key.layer = buxton_string_pack("layer");
1132         key.group = buxton_string_pack("group");
1133         key.name.value = NULL;
1134         fail_if(buxton_wire_remove_group(&client, &key, NULL,
1135                                          NULL) != true,
1136                 "Failed to send message");
1137
1138         r = read(server, buf, 4096);
1139         fail_if(r < 0, "Read from client failed");
1140         size = buxton_deserialize_message(buf, &msg, (size_t)r, &msgid, &list);
1141         fail_if(size != 2, "Failed to get valid message from buffer");
1142         fail_if(msg != BUXTON_CONTROL_REMOVE_GROUP,
1143                 "Failed to get correct control type");
1144         fail_if(list[0].type != STRING, "Failed to set correct layer type");
1145         fail_if(list[1].type != STRING, "Failed to set correct group type");
1146         fail_if(!streq(list[0].store.d_string.value, "layer"),
1147                 "Failed to set correct layer");
1148         fail_if(!streq(list[1].store.d_string.value, "group"),
1149                 "Failed to set correct group");
1150
1151         free(list[0].store.d_string.value);
1152         free(list[1].store.d_string.value);
1153         free(list);
1154         cleanup_callbacks();
1155         close(client.fd);
1156         close(server);
1157 }
1158 END_TEST
1159
1160 static Suite *
1161 buxton_suite(void)
1162 {
1163         Suite *s;
1164         TCase *tc;
1165
1166         s = suite_create("buxton");
1167
1168         tc = tcase_create("buxton_client_lib_functions");
1169         tcase_add_test(tc, buxton_direct_init_db_check);
1170         tcase_add_test(tc, buxton_direct_open_check);
1171         tcase_add_test(tc, buxton_direct_create_group_check);
1172         tcase_add_test(tc, buxton_direct_remove_group_check);
1173         tcase_add_test(tc, buxton_direct_set_value_check);
1174         tcase_add_test(tc, buxton_direct_get_value_for_layer_check);
1175         tcase_add_test(tc, buxton_direct_get_value_check);
1176         tcase_add_test(tc, buxton_memory_backend_check);
1177         tcase_add_test(tc, buxton_key_check);
1178         tcase_add_test(tc, buxton_set_label_check);
1179         tcase_add_test(tc, buxton_group_label_check);
1180         tcase_add_test(tc, buxton_name_label_check);
1181         suite_add_tcase(s, tc);
1182
1183         tc = tcase_create("buxton_protocol_functions");
1184         tcase_add_test(tc, run_callback_check);
1185         tcase_add_test(tc, handle_callback_response_check);
1186         tcase_add_test(tc, send_message_check);
1187         tcase_add_test(tc, buxton_wire_handle_response_check);
1188         tcase_add_test(tc, buxton_wire_get_response_check);
1189         tcase_add_test(tc, buxton_wire_set_value_check);
1190         tcase_add_test(tc, buxton_wire_set_label_check);
1191         tcase_add_test(tc, buxton_wire_get_value_check);
1192         tcase_add_test(tc, buxton_wire_unset_value_check);
1193         tcase_add_test(tc, buxton_wire_create_group_check);
1194         tcase_add_test(tc, buxton_wire_remove_group_check);
1195         suite_add_tcase(s, tc);
1196
1197         return s;
1198 }
1199
1200 int main(void)
1201 {
1202         int number_failed;
1203         Suite *s;
1204         SRunner *sr;
1205
1206         putenv("BUXTON_CONF_FILE=" ABS_TOP_BUILDDIR "/test/test.conf");
1207         putenv("BUXTON_ROOT_CHECK=0");
1208         s = buxton_suite();
1209         sr = srunner_create(s);
1210         srunner_run_all(sr, CK_VERBOSE);
1211         number_failed = srunner_ntests_failed(sr);
1212         srunner_free(sr);
1213
1214         return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1215 }
1216
1217
1218 /*
1219  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1220  *
1221  * Local variables:
1222  * c-basic-offset: 8
1223  * tab-width: 8
1224  * indent-tabs-mode: t
1225  * End:
1226  *
1227  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1228  * :indentSize=8:tabSize=8:noTabs=false:
1229  */