liblightify
test-lightify.c
Go to the documentation of this file.
1 /*
2  lightify test suite
3 
4  liblightify -- library to control OSRAM's LIGHTIFY
5 
6 Copyright (c) 2015, Tobias Frost <tobi@coldtobi.de>
7 All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
11  * Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13  * Redistributions in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in the
15  documentation and/or other materials provided with the distribution.
16  * Neither the name of the author nor the
17  names of its contributors may be used to endorse or promote products
18  derived from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
24 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 
32 #include <check.h>
33 #include <errno.h>
34 #include <stdio.h>
35 
37 
38 #include <assert.h>
39 
41 
42 struct fake_socket {
43  char *buf_read;
44  char *buf_write;
45  int size_read;
47  int err_read; // << for error injection
48  int err_write; // << for error injection
50 
51 
52 void print_protocol_mismatch_write(struct fake_socket *mfs, const unsigned char *should) {
53  char buf[512] ="\nWROTE:\n\n";
54 
55  int found = 0;
56  int i = 0;
57  for (i = 0; i < mfs->size_write; i++) {
58  unsigned int one, two;
59  one = 0xff & mfs->buf_write[i];
60  two = 0xff & should[i];
61  sprintf(buf + strlen(buf), " %02x%c=%02x", one,
62  (one == two ? '=' : '!'), two);
63  if (one != two) found =1;
64  }
65  if (found) ck_abort_msg(buf);
66 }
67 
68 void print_protocol_mismatch_read(struct fake_socket *mfs, const unsigned char *should) {
69  char buf[512] ="\nREAD\n\n";
70 
71  int i = 0;
72  int found = 0;
73  for (i = 0; i < mfs->size_read; i++) {
74  unsigned int one, two;
75  one = 0xff & mfs->buf_read[i];
76  two = 0xff & should[i];
77  sprintf(buf + strlen(buf), " %02x%c=%02x", one,
78  (one == two ? '=' : '!'), two);
79  if (one != two) found =1;
80  }
81  if (found) ck_abort_msg(buf);
82 }
83 
84 
85 // testdata
86 
87 // expected string to be sent to the gateway when scanning for nodes
88 const static char scanfornodes_query[] = {0x07,0x00,0x00,0x13,0x01,0x00,0x00,0x00,0x01 };
89 
90 // dummy response for the scan for nodes command
91 // (wiresharked, but edited to avoid same data e.g for the colors ;-)
92 // MAC64 set to 0xdeadbeef12345678
93 const static char scanfornodes_answer[] = {
94  0x33, 0x00, 0x01, 0x13, 0x01, 0x00, 0x00, 0x00,
95  0x00, 0x01, 0x00, 0x55, 0xaa,
96  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
97  0x02, 0x01, 0x02, 0x03, 0x07,
98  0x02, 0xcd, 0xab, 0x00, 0x64, 0x8e,
99  0x0a, 0xf0, 0xf1, 0xf2, 0xf3, 0x4c, 0x69, 0x63,
100  0x68, 0x74, 0x20, 0x30, 0x31, 0x00, 0x00, 0x00,
101  0x00, 0x00, 0x00, 0x00, 0x00
102 };
103 
104 
105 const static char turnonlight_query_broadcast[] = {
106  0x0f, 0x00, 0x00, 0x32, 0x02, 0x00, 0x00, 0x00,
107  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108  0x01
109 };
110 
111 const static char turnonlight_answer_broadcast[] = {
112  0x12, 0x00, 0x01, 0x32, 0x02, 0x00, 0x00, 0x00,
113  0x00, 0x01, 0x00,
114  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
115  0x00
116 };
117 
118 const static char turnofflight_query_broadcast[] = {
119  0x0f, 0x00, 0x00, 0x32, 0x04, 0x00, 0x00, 0x00,
120  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
121  0x00
122 };
123 
124 const static char turnofflight_answer_broadcast[] = {
125  0x12, 0x00, 0x01, 0x32, 0x04, 0x00, 0x00, 0x00,
126  0x00, 0x01, 0x00,
127  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
128  0x00
129 };
130 
131 const static char turnonlight2_query_broadcast[] = {
132  0x0f, 0x00, 0x00, 0x32, 0x05, 0x00, 0x00, 0x00,
133  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
134  0x01
135 };
136 
137 const static char turnonlight2_answer_broadcast[] = {
138  0x12, 0x00, 0x01, 0x32, 0x05, 0x00, 0x00, 0x00,
139  0x00, 0x01, 0x00,
140  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
141  0x00
142 };
143 
144 
145 const static char turnonlight_query_node[] = {
146  0x0f, 0x00, 0x00, 0x32, 0x03, 0x00, 0x00, 0x00,
147  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
148  0x01
149 };
150 
151 const static char turnonlight_answer_node[] = {
152  0x12, 0x00, 0x01, 0x32, 0x03, 0x00, 0x00, 0x00,
153  0x00, 0x01, 0x00,
154  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
155  0x00
156 };
157 
158 
159 const static char changecct_query_node[] = {
160  0x12, 0x00, 0x00, 0x33, 0x06, 0x00, 0x00, 0x00,
161  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
162  0x8C, 0x0A, 0x0a, 0x00
163 };
164 
165 const static char changecct_answer_node[] = {
166  0x12, 0x00, 0x01, 0x33, 0x06, 0x00, 0x00, 0x00,
167  0x00, 0x01, 0x00,
168  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
169  0x00
170 };
171 
172 const static char setrgbw_query_node[] = {
173  0x14, 0x00, 0x00, 0x36, 0x07, 0x00, 0x00, 0x00,
174  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
175  0x01, 0x02, 0x03, 0x04, 0x0a, 0x00
176 };
177 
178 const static char setrgbw_answer_node[] = {
179  0x12, 0x00, 0x01, 0x36, 0x07, 0x00, 0x00, 0x00,
180  0x00, 0x01, 0x00,
181  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
182  0x00
183 };
184 
185 const static char setbright_query_node[] = {
186  0x11, 0x00, 0x00, 0x31, 0x08, 0x00, 0x00, 0x00,
187  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
188  0x12, 0x0a, 0x00
189 };
190 
191 const static char setbright_answer_node[] = {
192  0x12, 0x00, 0x01, 0x31, 0x08, 0x00, 0x00, 0x00,
193  0x00, 0x01, 0x00,
194  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
195  0x00
196 };
197 
198 const static char requpdate_query_node[] = {
199  0x0e, 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, 0x00,
200  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
201 };
202 
203 const static char requpdate_answer_node[] = {
204  0x1d, 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, 0x00,
205  0x00, 0x01, 0x00,
206  0x78, 0x56, 0x34, 0x12, 0xef, 0xbe, 0xad, 0xde,
207  0x00,
208  0x02, 0x01, 0x55, 0x8C, 0x0A, 0x10, 0x11, 0x12, 0x13
209 };
210 
211 
212 const static char req_getgroups[] = {
213  0x07, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x35
214 };
215 
216 const static char req_getgroups_answer[] = {
217  0x3f, 0x00, 0x01, 0x1e, 0x01, 0x00, 0x00, 0x00,
218  0x00, 0x03, 0x00,
219  0x01, 0x00, 0x47, 0x72, 0x75, 0x70, 0x70, 0x65,
220  0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221  0x00, 0x00,
222  0x02, 0x00, 0x47, 0x72, 0x75, 0x70, 0x70, 0x65,
223  0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224  0x00, 0x00,
225  0x03, 0x00, 0x47, 0x72, 0x75, 0x70, 0x70, 0x65,
226  0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227  0x00, 0x00
228 };
229 
230 void setup(void) {
231  int err = lightify_new(&_ctx, NULL);
232  printf("setup done\n");
233 }
234 
235 void teardown(void) {
236  if (_ctx)
237  lightify_free(_ctx);
238  printf("teardown done\n");
239  _ctx = NULL;
240 }
241 
242 // short helper to setup our answer and free stuff if necessary.
243 static void helper_mfs_setup_answer(struct fake_socket *mfs,
244  const char *our_answer, size_t answer_len) {
245  if (mfs->buf_read)
246  free(mfs->buf_read);
247  mfs->buf_read = malloc(answer_len);
248  memcpy(mfs->buf_read, our_answer, answer_len);
249  mfs->size_read = answer_len;
250  if (mfs->buf_write)
251  free(mfs->buf_write);
252  mfs->buf_write = NULL;
253  mfs->size_write = 0;
254 }
255 
256 START_TEST(lightify_context_base_NULL_checks)
257  {
258 
259  // tests ABI default behaviour when supplying a NULL pointer to the context
260 
261  printf("now testing context::userdata\n");
262  ck_assert_ptr_eq(lightify_get_userdata(NULL), NULL);
263  ck_assert_int_eq(lightify_set_userdata(NULL,NULL), -EINVAL);
264 
265  printf("now testing context::log\n");
266  ck_assert_int_eq(lightify_set_log_priority(NULL,0), -EINVAL);
267  ck_assert_int_eq(lightify_get_log_priority(NULL), -EINVAL);
268  ck_assert_int_eq(lightify_set_log_fn(NULL,NULL), -EINVAL);
269 
270  printf("now testing context::socket\n");
271  ck_assert_int_eq(lightify_set_socket_fn(NULL,NULL,NULL), -EINVAL);
272  //ck_assert_int_eq(lightify_set_socket_fn((void*)1,(void*)1,NULL), -EINVAL);
273  //ck_assert_int_eq(lightify_set_socket_fn((void*)1,NULL,(void*)1), -EINVAL);
274 
275  printf("now testing context::context\n");
276  ck_assert_int_eq(lightify_free(NULL), -EINVAL);
277 
278  printf("now testing context::nodes\n");
279  ck_assert_ptr_eq(lightify_node_get_next(NULL,NULL), NULL);
280 
281  printf("now testing context::groups\n");
282  ck_assert_int_eq(lightify_group_request_scan(NULL), -EINVAL);
283  ck_assert_ptr_eq(lightify_group_get_next(NULL,NULL), NULL);
284  ck_assert_ptr_eq(lightify_group_get_previous(NULL,(struct lightify_group*)1), NULL);
285  ck_assert_ptr_eq(lightify_group_get_previous((struct lightify_ctx*)1,NULL), NULL);
286  ck_assert_int_eq(lightify_group_get_id(NULL), -EINVAL);
287  ck_assert_ptr_eq(lightify_group_get_name(NULL), NULL);
288 
289  }END_TEST
290 
291 START_TEST(lightify_context_object)
292  {
293  // testing obtaining an ctx object
294  struct lightify_ctx *ctx;
295 
296  printf("now testing context\n");
297  // creation of the object.
298  int err = lightify_new(&ctx, NULL);
299  ck_assert_int_eq(err, 0);
300  ck_assert_ptr_ne(ctx, 0);
301 
302  ck_assert_int_eq(lightify_free(ctx), 0);
303  }END_TEST
304 
306  Suite *s;
307  TCase *tc_context;
308 
309  s = suite_create("liblithify_ABI");
310  tc_context = tcase_create("testfixture basic tests");
311  tcase_add_test(tc_context, lightify_context_object);
312  suite_add_tcase(s, tc_context);
313  return s;
314 }
315 
316 START_TEST(lightify_context_userdata)
317  {
318  // userdata default value and if it is settable
319  struct lightify_ctx *ctx;
320  int err = lightify_new(&ctx, NULL);
321 
322  ck_assert_ptr_eq(lightify_get_userdata(ctx), 0);
323  lightify_set_userdata(ctx, (void*) 42);
324  ck_assert_ptr_eq(lightify_get_userdata(ctx), (void* )42);
325 
326  }END_TEST
327 
328 START_TEST(lightify_context_skt)
329  {
330 
331  struct lightify_ctx *ctx;
332  int err = lightify_new(&ctx, NULL);
333  // default fd not set, so should error out
334  err = lightify_skt_getfd(ctx);
335  ck_assert((err < 0));
336 
337  // is it setable and retains its value?
338  err = lightify_skt_setfd(ctx, 1);
339  err = lightify_skt_getfd(ctx);
340  ck_assert_int_eq(err, 1);
341  }END_TEST
342 
343 Suite *liblightify_API_suite(void) {
344  Suite *s;
345  TCase *tc;
346  s = suite_create("liblightify");
347 
348  /* Core test case */
349  tc = tcase_create("API_misuse");
350 
351  tcase_add_test(tc, lightify_context_base_NULL_checks);
352  suite_add_tcase(s, tc);
353 
354  tc = tcase_create("context_API_check");
355  tcase_add_test(tc, lightify_context_userdata);
356  suite_add_tcase(s, tc);
357 
358  tc = tcase_create("context_skt_API_check");
359  tcase_add_test(tc, lightify_context_skt);
360  suite_add_tcase(s, tc);
361 
362  return s;
363 }
364 
365 int my_write_to_socket(struct lightify_ctx *ctx, unsigned char *msg,
366  size_t size) {
367 
368  struct fake_socket *fs = (struct fake_socket*) lightify_get_userdata(ctx);
369  assert(fs);
370 
371  printf("my_write_from_socket: size=%d, msg=%p\n", size, msg);
372 
373  if (!fs->buf_write) {
374  fs->buf_write = malloc(size);
375  fs->size_write = 0;
376  } else {
377  fs->buf_write = realloc(fs->buf_write, fs->size_write + size);
378  }
379  assert(fs->buf_write);
380 
381  memcpy(fs->buf_write + fs->size_write, msg, size);
382  fs->size_write += size;
383 
384  return (fs->err_write < 0 ? fs->err_write : size);
385 }
386 
387 int my_read_from_socket(struct lightify_ctx *ctx, unsigned char *msg,
388  size_t size) {
389 
390  size_t read_size;
391  struct fake_socket *fs = (struct fake_socket*) lightify_get_userdata(ctx);
392  assert(fs);
393  assert(fs->buf_read);
394 
395  printf("my_read_from_socket: size=%d, msg=%p\n", size, msg);
396 
397  read_size = fs->size_read;
398  if (read_size > size)
399  read_size = size;
400 
401  if (read_size) {
402  memcpy(msg, fs->buf_read, read_size);
403  fs->size_read -= read_size;
404  if (fs->size_read)
405  memmove(fs->buf_read, fs->buf_read + read_size, fs->size_read);
406  }
407 
408  return (fs->err_read < 0 ? fs->err_read : read_size);
409 }
410 
411 START_TEST(lightify_tst_scan_nodes)
412  {
413  // scan for nodes using static data
414  // tests also the overriding of the io functions :)
415 
416  int err;
417  struct fake_socket *mfs = calloc(1, sizeof(struct fake_socket));
418  helper_mfs_setup_answer(mfs, scanfornodes_answer,
419  sizeof(scanfornodes_answer));
420 
423  ck_assert_int_eq(err, 0);
424 
425  err = lightify_set_userdata(_ctx, mfs);
426  ck_assert_int_eq(err, 0);
427 
428  err = lightify_node_request_scan(_ctx);
429  ck_assert_int_eq(err, 1);
430 
431  ck_assert_int_eq(mfs->size_write, sizeof(scanfornodes_query));
432  err = memcmp(mfs->buf_write, scanfornodes_query, mfs->size_write);
433  ck_assert_int_eq(err, 0);
434 
435  // check if we can access the node
436  struct lightify_node *node, *node2;
437 
438  node = lightify_node_get_next(_ctx, NULL);
439  ck_assert_ptr_ne(node, NULL);
440 
441  node2 = lightify_node_get_next(_ctx, node);
442  ck_assert_ptr_eq(node2, NULL);
443 
444  // check if we can get the name
445  const char *name = lightify_node_get_name(node);
446  ck_assert_ptr_ne(name, NULL);
447  ck_assert_int_eq(strcmp("Licht 01", name), 0);
448 
449  // check if we can get the CCT
450  int cct = lightify_node_get_cct(node);
451  ck_assert_int_eq(cct, 2702);
452 
453  // check if we can get the MAC
454  uint64_t mac = lightify_node_get_nodeadr(node);
455  ck_assert(mac == 0xdeadbeef12345678);
456 
457  // check that we can search via MAC.
458  node2 = lightify_node_get_from_mac(_ctx, mac);
459  ck_assert_ptr_eq(node,node2);
460 
461  // check that we won't get a result on a bogus MAC.
462  node2 = lightify_node_get_from_mac(_ctx, mac+1);
463  ck_assert_ptr_eq(node2,NULL);
464 
465  // check if we can get the node adr
466  uint16_t zoneadr = lightify_node_get_zoneadr(node);
467  ck_assert_uint_eq(zoneadr, 0xaa55);
468 
469  // check if we can extract the group adr
470  uint16_t grp = lightify_node_get_grpadr(node);
471  ck_assert_uint_eq(grp, 0xabcd);
472 
473  // check if we can get the colors
474  uint8_t color;
475 
476  color = lightify_node_get_red(node);
477  ck_assert_int_eq(color, 0xf0);
478 
479  color = lightify_node_get_green(node);
480  ck_assert_int_eq(color, 0xf1);
481 
482  color = lightify_node_get_blue(node);
483  ck_assert_int_eq(color, 0xf2);
484 
485  color = lightify_node_get_white(node);
486  ck_assert_int_eq(color, 0xf3);
487 
488  // Check we delete node information when scanfornodes fails.
489  // we do that by repeating the scan, but with the now invalid token,
490  // so we should get EPROTO here.
491  helper_mfs_setup_answer(mfs, scanfornodes_answer,
492  sizeof(scanfornodes_answer));
493 
494  err = lightify_node_request_scan(_ctx);
495  ck_assert_int_eq(err, -EPROTO);
496 
497  // There must be no node.
498  node = lightify_node_get_next(_ctx,NULL);
499  ck_assert_ptr_eq(node, NULL);
500 
501  // undo functions and userdata.
502  err = lightify_set_socket_fn(_ctx, NULL, NULL);
503  ck_assert_int_eq(err, 0);
504 
505  err = lightify_set_userdata(_ctx, NULL);
506  ck_assert_int_eq(err, 0);
507 
508  free(mfs->buf_write);
509  free(mfs->buf_read);
510  free(mfs);
511  }END_TEST
512 
514  Suite *s;
515  TCase *tc;
516  s = suite_create("liblightify_functional_nodes");
517 
518  /* Core test case */
519  tc = tcase_create("lightify_tst_scan_nodes");
520 
521  tcase_add_unchecked_fixture(tc, setup, teardown);
522  tcase_add_test(tc, lightify_tst_scan_nodes);
523  suite_add_tcase(s, tc);
524 
525  return s;
526 }
527 
528 START_TEST(lightify_tst_manipulate_nodes)
529  {
530 
531  // setup: scan for nodes with static data as response (to setup nodes)
532  // and then issue commands at it to compare with static result data.
533 
534  /* setup part -- already checked in another testcase */
535  int err;
536  struct fake_socket *mfs = calloc(1, sizeof(struct fake_socket));
537  helper_mfs_setup_answer(mfs, scanfornodes_answer,
538  sizeof(scanfornodes_answer));
539 
541  lightify_set_userdata(_ctx, mfs);
542  err = lightify_node_request_scan(_ctx);
543  ck_assert_int_ge(err, 0);
544 
545  // test: turn on light, broadcast
546  do {
547  helper_mfs_setup_answer(mfs, turnonlight_answer_broadcast,
548  sizeof(turnonlight_answer_broadcast));
549 
550  // test: turn on light, broadcast
551  err = lightify_node_request_onoff(_ctx, NULL, 1);
552  ck_assert_int_eq(err, 0);
553  err = memcmp(mfs->buf_write, turnonlight_query_broadcast,
554  mfs->size_write);
555  ck_assert_int_eq(err, 0);
556 
557  // test: turn on light, addessing node
558  helper_mfs_setup_answer(mfs, turnonlight_answer_node,
559  sizeof(turnonlight_answer_node));
560  err = lightify_node_request_onoff(_ctx,
561  lightify_node_get_next(_ctx, NULL), 1);
562  ck_assert_int_eq(err, 0);
563 
564  err = memcmp(mfs->buf_write, turnonlight_query_node,
565  mfs->size_write);
566  if (err) {
567  char buf[512];
568  buf[0] = '\n';
569  buf[1] = '0';
570 
571  int i = 0;
572  for (i = 0; i < mfs->size_write; i++) {
573  unsigned int one, two;
574  one = 0xff & mfs->buf_write[i];
575  two = 0xff & turnonlight_query_node[i];
576  sprintf(buf + strlen(buf), " %02x%c=%02x", one,
577  (one == two ? '=' : '!'), two);
578  }
579  ck_abort_msg(buf);
580  }
581  ck_assert_int_eq(err, 0);
582 
583  // check if cache has been updated.
584  struct lightify_node *node = NULL;
585  while( node = lightify_node_get_next(_ctx, node)) {
586  err = lightify_node_is_on(node);
587  ck_assert_int_eq(err, 1);
588  }
589 
590  // Broadcast off.
591  helper_mfs_setup_answer(mfs, turnofflight_answer_broadcast,
592  sizeof(turnofflight_answer_broadcast));
593  err = lightify_node_request_onoff(_ctx, NULL, 0);
594  if ( err < 0) {
595  print_protocol_mismatch_write(mfs,turnofflight_query_broadcast);
596  print_protocol_mismatch_read(mfs,turnofflight_answer_broadcast);
597  }
598 
599  node = NULL;
600  while( node = lightify_node_get_next(_ctx, node)) {
601  err = lightify_node_is_on(node);
602  ck_assert_int_eq(err, 0);
603  }
604 
605  // Broadcast on.
606  helper_mfs_setup_answer(mfs, turnonlight2_answer_broadcast,
607  sizeof(turnonlight2_answer_broadcast));
608  err = lightify_node_request_onoff(_ctx, NULL, 1);
609  if ( err < 0) {
610  print_protocol_mismatch_write(mfs,turnonlight2_query_broadcast);
611  print_protocol_mismatch_read(mfs,turnonlight2_answer_broadcast);
612  }
613  node = NULL;
614  while( node = lightify_node_get_next(_ctx, node)) {
615  err = lightify_node_is_on(node);
616  ck_assert_int_eq(err, 1);
617  }
618  } while(0);
619 
620  // Test change CCT.
621  do {
622  helper_mfs_setup_answer(mfs, changecct_answer_node,
623  sizeof(changecct_answer_node));
624  err = lightify_node_request_cct(_ctx, lightify_node_get_next(_ctx, NULL),
625  2700, 10);
626  if ( err < 0) {
627  print_protocol_mismatch_write(mfs,changecct_query_node);
628  print_protocol_mismatch_read(mfs,changecct_answer_node);
629  }
630  ck_assert_int_eq(err, 0);
631 
632  // Check if the cache has been updated
634  ck_assert_int_eq(err, 2700);
635 
636  } while(0);
637 
638  // Test RBGW
639  do {
640  helper_mfs_setup_answer(mfs, setrgbw_answer_node,
641  sizeof(setrgbw_answer_node));
642  err = lightify_node_request_rgbw(_ctx, lightify_node_get_next(_ctx, NULL),
643  1,2,3,4,10);
644  if ( err < 0) {
645  print_protocol_mismatch_write(mfs,setrgbw_query_node);
646  print_protocol_mismatch_read(mfs,setrgbw_answer_node);
647  }
648  ck_assert_int_eq(err, 0);
649 
650  // Check if the cache has been updated
652  ck_assert_int_eq(err, 1);
654  ck_assert_int_eq(err, 2);
656  ck_assert_int_eq(err, 3);
658  ck_assert_int_eq(err, 4);
659  } while (0);
660 
661  // Test brightness
662  do {
663  helper_mfs_setup_answer(mfs, setbright_answer_node,
664  sizeof(setbright_answer_node));
666  0x12,10);
667  if ( err < 0) {
668  print_protocol_mismatch_write(mfs,setbright_query_node);
669  print_protocol_mismatch_read(mfs,setbright_answer_node);
670  }
671  ck_assert_int_eq(err, 0);
672 
673  // Check if the cache has been updated
675  ck_assert_int_eq(err, 0x12);
676  } while (0);
677 
678  // Test updating node information
679  do {
680  helper_mfs_setup_answer(mfs, requpdate_answer_node,
681  sizeof(requpdate_answer_node));
682  err = lightify_node_request_update(_ctx, lightify_node_get_next(_ctx, NULL));
683  if ( err < 0) {
684  print_protocol_mismatch_write(mfs,requpdate_query_node);
685  print_protocol_mismatch_read(mfs,requpdate_answer_node);
686  }
687  ck_assert_int_eq(err, 0);
688  // Check if the cache has been updated
689  struct lightify_node* node = lightify_node_get_next(_ctx, NULL);
690  ck_assert_int_eq(lightify_node_get_onlinestate(node),2);
691  ck_assert_int_eq(lightify_node_is_on(node),0x01);
692  ck_assert_int_eq(lightify_node_get_brightness(node), 0x55);
693  ck_assert_int_eq(lightify_node_get_cct(node),0xa8c);
694  ck_assert_int_eq(lightify_node_get_red(node),0x10);
695  ck_assert_int_eq(lightify_node_get_green(node),0x11);
696  ck_assert_int_eq(lightify_node_get_blue(node),0x12);
697  ck_assert_int_eq(lightify_node_get_white(node),0x13);
698  } while (0);
699 
700  }END_TEST
701 
703  Suite *s;
704  TCase *tc;
705  s = suite_create("liblightify_functional_manipulate_node");
706 
707  /* Core test case */
708  tc = tcase_create("liblightify_functional_manipulate_node");
709 
710  tcase_add_unchecked_fixture(tc, setup, teardown);
711  tcase_add_test(tc, lightify_tst_manipulate_nodes);
712  suite_add_tcase(s, tc);
713 
714  return s;
715 }
716 
717 START_TEST(lightify_tst_groups_basic) {
718 
719  int err;
720  struct fake_socket *mfs = calloc(1, sizeof(struct fake_socket));
721  struct lightify_group *group, *group2;
722 
724  lightify_set_userdata(_ctx, mfs);
725 
726  // query groups
727  {
728  helper_mfs_setup_answer(mfs, req_getgroups_answer,
729  sizeof(req_getgroups_answer));
730 
731  err = lightify_group_request_scan(_ctx);
732 
733  if ( err < 0) {
734  print_protocol_mismatch_write(mfs,req_getgroups);
735  print_protocol_mismatch_read(mfs,req_getgroups_answer);
736  }
737 
738  // The sample recorded answer has 3 Groups in it.
739  ck_assert_int_eq(err, 3);
740  } while(0);
741 
742  // Obtain pointer to group
743  {
744  // Get first group
745  group = lightify_group_get_next(_ctx, NULL);
746  ck_assert(group);
747  // Second.
748  group2 = lightify_group_get_next(_ctx,group);
749  ck_assert(group2);
750  // Thrird
751  group2 = lightify_group_get_next(_ctx,group2);
752  ck_assert(group2);
753  // no Fourth
754  group2 = lightify_group_get_next(_ctx,group2);
755  ck_assert(!group2);
756  } while(0);
757 
758  // Check if name and id is ok for those speciems..
759  {
760  group = lightify_group_get_next(_ctx, NULL);
761  ck_assert_int_eq(strcmp("Gruppe1", lightify_group_get_name(group)),0);
762  ck_assert_int_eq(lightify_group_get_id(group), 1);
763  group = lightify_group_get_next(_ctx, group);
764  ck_assert_int_eq(strcmp("Gruppe2", lightify_group_get_name(group)),0);
765  ck_assert_int_eq(lightify_group_get_id(group), 2);
766  group = lightify_group_get_next(_ctx, group);
767  ck_assert_int_eq(strcmp("Gruppe3", lightify_group_get_name(group)),0);
768  ck_assert_int_eq(lightify_group_get_id(group), 3);
769  } while(0);
770 
771 
772 
773 
774 }END_TEST
775 
777  Suite *s;
778  TCase *tc;
779  s = suite_create("lightify_tst_groups_basic");
780 
781  /* Core test case */
782  tc = tcase_create("lightify_tst_groups_basic");
783 
784  tcase_add_unchecked_fixture(tc, setup, teardown);
785  tcase_add_test(tc, lightify_tst_groups_basic);
786  suite_add_tcase(s, tc);
787 
788  return s;
789 }
790 
791 
792 int main(void) {
793  int number_failed;
794  Suite *s;
795  SRunner *sr;
796 
797  sr = srunner_create(liblightify_testfixture());
798  srunner_add_suite(sr, liblightify_API_suite());
799  srunner_add_suite(sr, liblightify_functional_nodes());
800  srunner_add_suite(sr, liblightify_functional_manipulate_node());
801  srunner_add_suite(sr, liblightify_tst_groups_basic());
802 
803  srunner_set_tap(sr, "-");
804  srunner_set_fork_status(sr, CK_NOFORK);
805  srunner_run_all(sr, CK_VERBOSE);
806  number_failed = srunner_ntests_failed(sr);
807  srunner_free(sr);
808 
809  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
810 }
char * name
Definition: node.c:61
#define err(ctx, arg...)
LIGHTIFY_EXPORT int lightify_node_request_rgbw(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int r, unsigned int g, unsigned int b, unsigned int w, unsigned int fadetime)
Definition: context.c:959
char * buf_write
Definition: test-lightify.c:44
int lightify_skt_setfd(struct lightify_ctx *ctx, int socket)
Definition: socket.c:204
END_TEST Suite * liblightify_testfixture(void)
int lightify_set_log_fn(struct lightify_ctx *ctx, void(*log_fn)(struct lightify_ctx *ctx, int priority, const char *file, int line, const char *fn, const char *format, va_list args))
Definition: log.c:89
LIGHTIFY_EXPORT int lightify_free(struct lightify_ctx *ctx)
Definition: context.c:494
LIGHTIFY_EXPORT int lightify_node_request_scan(struct lightify_ctx *ctx)
Definition: context.c:505
const char * lightify_node_get_name(struct lightify_node *node)
Definition: node.c:164
LIGHTIFY_EXPORT int lightify_node_request_onoff(struct lightify_ctx *ctx, struct lightify_node *node, int onoff)
Definition: context.c:922
int lightify_node_get_brightness(struct lightify_node *node)
Definition: node.c:274
int lightify_set_log_priority(struct lightify_ctx *ctx, int priority)
Definition: log.c:105
LIGHTIFY_EXPORT int lightify_group_request_scan(struct lightify_ctx *ctx)
Definition: context.c:1082
int lightify_skt_getfd(struct lightify_ctx *ctx)
Definition: socket.c:210
END_TEST Suite * liblightify_API_suite(void)
void print_protocol_mismatch_read(struct fake_socket *mfs, const unsigned char *should)
Definition: test-lightify.c:68
uint64_t lightify_node_get_nodeadr(struct lightify_node *node)
Definition: node.c:175
LIGHTIFY_EXPORT void * lightify_get_userdata(struct lightify_ctx *ctx)
Definition: context.c:417
LIGHTIFY_EXPORT struct lightify_group * lightify_group_get_next(struct lightify_ctx *ctx, struct lightify_group *current)
Definition: groups.c:134
END_TEST Suite * liblightify_tst_groups_basic(void)
int lightify_node_is_on(struct lightify_node *node)
Definition: node.c:286
LIGHTIFY_EXPORT int lightify_group_get_id(struct lightify_group *grp)
Definition: groups.c:128
LIGHTIFY_EXPORT int lightify_set_socket_fn(struct lightify_ctx *ctx, write_to_socket_fn fpw, read_from_socket_fn fpr)
Definition: context.c:430
struct lightify_ctx * _ctx
Definition: test-lightify.c:40
LIGHTIFY_EXPORT struct lightify_node * lightify_node_get_next(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: context.c:402
int my_write_to_socket(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
END_TEST Suite * liblightify_functional_manipulate_node(void)
int main(void)
struct fake_socket my_fakesocket
uint16_t lightify_node_get_grpadr(struct lightify_node *node)
Definition: node.c:197
int lightify_node_get_red(struct lightify_node *node)
Definition: node.c:219
void setup(void)
void print_protocol_mismatch_write(struct fake_socket *mfs, const unsigned char *should)
Definition: test-lightify.c:52
int lightify_node_get_cct(struct lightify_node *node)
Definition: node.c:263
LIGHTIFY_EXPORT int lightify_node_request_brightness(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int level, unsigned int fadetime)
Definition: context.c:975
void teardown(void)
int lightify_node_get_white(struct lightify_node *node)
Definition: node.c:252
int my_read_from_socket(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
LIGHTIFY_EXPORT int lightify_set_userdata(struct lightify_ctx *ctx, void *userdata)
Definition: context.c:423
END_TEST Suite * liblightify_functional_nodes(void)
LIGHTIFY_EXPORT int lightify_new(struct lightify_ctx **ctx, void *reserved)
Definition: context.c:445
START_TEST(lightify_context_base_NULL_checks)
int lightify_get_log_priority(struct lightify_ctx *ctx)
Definition: log.c:99
LIGHTIFY_EXPORT struct lightify_node * lightify_node_get_from_mac(struct lightify_ctx *ctx, uint64_t mac)
Definition: context.c:314
int lightify_node_get_onlinestate(struct lightify_node *node)
Definition: node.c:297
LIGHTIFY_EXPORT struct lightify_group * lightify_group_get_previous(struct lightify_ctx *ctx, struct lightify_group *current)
Definition: groups.c:140
LIGHTIFY_EXPORT int lightify_node_request_update(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: context.c:987
int lightify_node_get_green(struct lightify_node *node)
Definition: node.c:241
LIGHTIFY_EXPORT int lightify_node_request_cct(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int cct, unsigned int fadetime)
Definition: context.c:947
int lightify_node_get_blue(struct lightify_node *node)
Definition: node.c:230
char * buf_read
Definition: test-lightify.c:43
LIGHTIFY_EXPORT const char * lightify_group_get_name(struct lightify_group *grp)
Definition: groups.c:117
uint16_t lightify_node_get_zoneadr(struct lightify_node *node)
Definition: node.c:186
int cct
Definition: node.c:67