1 /* libcoap unit tests
2 *
3 * Copyright (C) 2012,2015 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
11 #include "test_common.h"
12 #include "test_options.h"
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 /************************************************************************
19 ** decoder tests
20 ************************************************************************/
21
22 static void
t_parse_option1(void)23 t_parse_option1(void) {
24 /* delta == 0, length == 0, value == 0 */
25 coap_str_const_t teststr = { 1, (const uint8_t *)"" };
26
27 size_t result;
28 coap_option_t option;
29
30 /* result = coap_opt_parse(teststr.s, teststr.s + teststr.length, &option); */
31 result = coap_opt_parse(teststr.s, teststr.length, &option);
32 CU_ASSERT(result == 1);
33 CU_ASSERT(option.delta == 0);
34 CU_ASSERT(option.length == 0);
35 /* FIXME: value? */
36 }
37
38 static void
t_parse_option2(void)39 t_parse_option2(void) {
40 /* delta == 12, length == 1, value == 0 */
41 coap_str_const_t teststr = { 2, (const uint8_t *)"\xc1" };
42
43 size_t result;
44 coap_option_t option;
45
46 result = coap_opt_parse(teststr.s, teststr.length, &option);
47 CU_ASSERT(result == 2);
48 CU_ASSERT(option.delta == 12);
49 CU_ASSERT(option.length == 1);
50 CU_ASSERT(option.value == teststr.s + 1);
51 }
52
53 static void
t_parse_option3(void)54 t_parse_option3(void) {
55 /* delta == 3, length == 12, value == 0 */
56 coap_str_const_t teststr = { 13, (const uint8_t *)"\x3c\x00\x01\x02\x03\x04"
57 "\x05\x06\x07\x08\x09\x0a\x0b" };
58
59 size_t result;
60 coap_option_t option;
61
62 result = coap_opt_parse(teststr.s, teststr.length, &option);
63 CU_ASSERT(result == 13);
64 CU_ASSERT(option.delta == 3);
65 CU_ASSERT(option.length == 12);
66 CU_ASSERT(option.value == teststr.s + 1);
67 /* CU_ASSERT(memcmp(option.value, teststr.s + 1, 12) == 0); */
68 }
69
70 static void
t_parse_option4(void)71 t_parse_option4(void) {
72 /* delta == 15, length == 3, value == 0 */
73 coap_str_const_t teststr = { 2, (const uint8_t *)"\xf3" };
74
75 size_t result;
76 coap_option_t option;
77
78 result = coap_opt_parse(teststr.s, teststr.length, &option);
79 CU_ASSERT(result == 0);
80 }
81
82 static void
t_parse_option5(void)83 t_parse_option5(void) {
84 /* delta == 3, length == 15, value == 0 */
85 coap_str_const_t teststr = { 2, (const uint8_t *)"\x3f" };
86
87 size_t result;
88 coap_option_t option;
89
90 result = coap_opt_parse(teststr.s, teststr.length, &option);
91 CU_ASSERT(result == 0);
92 }
93
94 static void
t_parse_option6(void)95 t_parse_option6(void) {
96 /* delta == 15, length == 15 */
97 coap_str_const_t teststr = { 1, (const uint8_t *)"\xff" };
98
99 size_t result;
100 coap_option_t option;
101
102 result = coap_opt_parse(teststr.s, teststr.length, &option);
103 CU_ASSERT(result == 0);
104 }
105
106 static void
t_parse_option7(void)107 t_parse_option7(void) {
108 /* delta == 20, length == 0 */
109 coap_str_const_t teststr = { 2, (const uint8_t *)"\xd0\x07" };
110
111 size_t result;
112 coap_option_t option;
113
114 result = coap_opt_parse(teststr.s, teststr.length, &option);
115 CU_ASSERT(result == 2);
116 CU_ASSERT(option.delta == 20);
117 CU_ASSERT(option.length == 0);
118 }
119
120 static void
t_parse_option8(void)121 t_parse_option8(void) {
122 /* delta == 780, length == 0 */
123 coap_str_const_t teststr = { 3, (const uint8_t *)"\xe0\x01\xff" };
124
125 size_t result;
126 coap_option_t option;
127
128 result = coap_opt_parse(teststr.s, teststr.length, &option);
129 CU_ASSERT(result == 3);
130 CU_ASSERT(option.delta == 780);
131 CU_ASSERT(option.length == 0);
132 }
133
134 static void
t_parse_option9(void)135 t_parse_option9(void) {
136 /* delta == 65535, length == 0 */
137 coap_str_const_t teststr = { 3, (const uint8_t *)"\xe0\xfe\xf2" };
138
139 size_t result;
140 coap_option_t option;
141
142 result = coap_opt_parse(teststr.s, teststr.length, &option);
143 CU_ASSERT(result == 3);
144 CU_ASSERT(option.delta == 65535);
145 }
146
147 static void
t_parse_option10(void)148 t_parse_option10(void) {
149 /* delta > 65535 (illegal), length == 0 */
150 coap_str_const_t teststr = { 3, (const uint8_t *)"\xe0\xff\xff" };
151
152 size_t result;
153 coap_option_t option;
154
155 result = coap_opt_parse(teststr.s, teststr.length, &option);
156 CU_ASSERT(result == 0);
157 }
158
159 static void
t_parse_option11(void)160 t_parse_option11(void) {
161 /* illegal delta value (option too short) */
162 coap_str_const_t teststr = { 1, (const uint8_t *)"\xd0" };
163
164 size_t result;
165 coap_option_t option;
166
167 result = coap_opt_parse(teststr.s, teststr.length, &option);
168 CU_ASSERT(result == 0);
169 }
170
171 static void
t_parse_option12(void)172 t_parse_option12(void) {
173 /* delta == 280, length == 500 */
174 coap_str_const_t teststr = { 3, (const uint8_t *)"\xee\xff\x0b" };
175
176 size_t result;
177 coap_option_t option;
178
179 result = coap_opt_parse(teststr.s, teststr.length, &option);
180 CU_ASSERT(result == 0);
181 }
182
183 static void
t_parse_option13(void)184 t_parse_option13(void) {
185 /* delta == 280, length == 500 */
186 unsigned char _data[505];
187 coap_string_t teststr = { sizeof(_data), _data };
188 teststr.s[0] = 0xee;
189 teststr.s[1] = 0x00;
190 teststr.s[2] = 0x0b;
191 teststr.s[3] = 0x00;
192 teststr.s[4] = 0xe7;
193
194 size_t result;
195 coap_option_t option;
196
197 result = coap_opt_parse(teststr.s, teststr.length, &option);
198 CU_ASSERT(result == sizeof(_data));
199 CU_ASSERT(option.delta == 280);
200 CU_ASSERT(option.length == 500);
201 CU_ASSERT(option.value == &_data[5]);
202 }
203
204 static void
t_parse_option14(void)205 t_parse_option14(void) {
206 /* delta == 268, length == 65535 */
207 unsigned char *data;
208 unsigned int length = 4 + 65535;
209
210 data = (unsigned char *)malloc(length);
211 if (!data) {
212 CU_FAIL("internal error in test framework -- insufficient memory\n");
213 return;
214 }
215
216 data[0] = 0xde;
217 data[1] = 0xff;
218 data[2] = 0xfe;
219 data[3] = 0xf2;
220
221 size_t result;
222 coap_option_t option;
223
224 result = coap_opt_parse(data, length, &option);
225 CU_ASSERT(result == length);
226 CU_ASSERT(option.delta == 268);
227 CU_ASSERT(option.length == 65535);
228 CU_ASSERT(option.value == &data[4]);
229 free(data);
230 }
231
232 /************************************************************************
233 ** encoder tests
234 ************************************************************************/
235
236 static void
t_encode_option1(void)237 t_encode_option1(void) {
238 char teststr[] = { 0x00 };
239 unsigned char buf[40];
240 size_t result;
241
242 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 0, 0);
243 CU_ASSERT(result == sizeof(teststr));
244
245 CU_ASSERT(memcmp(buf, teststr, result) == 0);
246 }
247
248 static void
t_encode_option2(void)249 t_encode_option2(void) {
250 uint8_t teststr[] = { 0x5d, 0xff };
251 unsigned char buf[40];
252 size_t result;
253
254 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 5, 268);
255 CU_ASSERT(result == sizeof(teststr));
256
257 CU_ASSERT(memcmp(buf, teststr, result) == 0);
258 }
259
260 static void
t_encode_option3(void)261 t_encode_option3(void) {
262 uint8_t teststr[] = { 0xd1, 0x01 };
263 unsigned char buf[40];
264 size_t result;
265
266 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 14, 1);
267 CU_ASSERT(result == sizeof(teststr));
268
269 CU_ASSERT(memcmp(buf, teststr, result) == 0);
270 }
271
272 static void
t_encode_option4(void)273 t_encode_option4(void) {
274 uint8_t teststr[] = { 0xdd, 0xff, 0xab };
275 unsigned char buf[40];
276 size_t result;
277
278 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 268, 184);
279 CU_ASSERT(result == sizeof(teststr));
280
281 CU_ASSERT(memcmp(buf, teststr, result) == 0);
282 }
283
284 static void
t_encode_option5(void)285 t_encode_option5(void) {
286 uint8_t teststr[] = { 0xed, 0x13, 0x00, 0xff };
287 unsigned char buf[40];
288 size_t result;
289
290 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 5133, 268);
291 CU_ASSERT(result == sizeof(teststr));
292
293 CU_ASSERT(memcmp(buf, teststr, result) == 0);
294 }
295
296 static void
t_encode_option6(void)297 t_encode_option6(void) {
298 uint8_t teststr[] = { 0xee, 0xfe, 0xf2, 0xfe, 0xf2 };
299 unsigned char buf[40];
300 size_t result;
301
302 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 65535, 65535);
303 CU_ASSERT(result == sizeof(teststr));
304
305 CU_ASSERT(memcmp(buf, teststr, result) == 0);
306 }
307
308 static void
t_encode_option7(void)309 t_encode_option7(void) {
310 uint8_t teststr[] = { 0x35, 'v', 'a', 'l', 'u', 'e' };
311 const size_t valoff = 1;
312 unsigned char buf[40];
313 size_t result;
314
315 result = coap_opt_encode((coap_opt_t *)buf, sizeof(buf), 3,
316 (unsigned char *)teststr + valoff,
317 sizeof(teststr) - valoff);
318
319 CU_ASSERT(result == sizeof(teststr));
320
321 CU_ASSERT(memcmp(buf, teststr, result) == 0);
322 }
323
324 static void
t_encode_option8(void)325 t_encode_option8(void) {
326 /* value does not fit in message buffer */
327 unsigned char buf[40];
328 size_t result;
329
330 result = coap_opt_encode((coap_opt_t *)buf, 8, 15,
331 (const uint8_t *)"something", 9);
332
333 CU_ASSERT(result == 0);
334
335 result = coap_opt_encode((coap_opt_t *)buf, 1, 15,
336 (const uint8_t *)"something", 9);
337
338 CU_ASSERT(result == 0);
339 }
340
341 static void
t_encode_option9(void)342 t_encode_option9(void) {
343 uint8_t teststr[] = { 0xe1, 0x00, 0x00 };
344 unsigned char buf[40] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
345 size_t result;
346
347 result = coap_opt_setheader((coap_opt_t *)buf, sizeof(buf), 269, 1);
348 CU_ASSERT(result == sizeof(teststr));
349
350 CU_ASSERT(memcmp(buf, teststr, result) == 0);
351 }
352
353 /************************************************************************
354 ** accessor tests
355 ************************************************************************/
356
357 static void
t_access_option1(void)358 t_access_option1(void) {
359 const uint8_t teststr[] = { 0x12, 'a', 'b' };
360 coap_option_t opt;
361
362 CU_ASSERT(sizeof(teststr) == coap_opt_parse((const coap_opt_t *)teststr,
363 sizeof(teststr), &opt));
364 CU_ASSERT(opt.delta == 1);
365 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 2);
366 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), teststr + 1);
367 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == sizeof(teststr));
368 }
369
370 static void
t_access_option2(void)371 t_access_option2(void) {
372 const uint8_t teststr[] = { 0xe2, 0x18, 0xfd, 'a', 'b' };
373 coap_option_t opt;
374
375 CU_ASSERT(sizeof(teststr) == coap_opt_parse((const coap_opt_t *)teststr,
376 sizeof(teststr), &opt));
377 CU_ASSERT(opt.delta == 6666);
378 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 2);
379 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), teststr + 3);
380 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == sizeof(teststr));
381 }
382
383 static void
t_access_option3(void)384 t_access_option3(void) {
385 const uint8_t teststr[] = { 0xed, 0x18, 0x0a, 0x00, 'a', 'b', 'c', 'd',
386 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
387 'm'
388 };
389 coap_option_t opt;
390
391 CU_ASSERT(sizeof(teststr) == coap_opt_parse((const coap_opt_t *)teststr,
392 sizeof(teststr), &opt));
393 CU_ASSERT(opt.delta == 6423);
394 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 13);
395 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), teststr + 4);
396 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == sizeof(teststr));
397 }
398
399 static void
t_access_option4(void)400 t_access_option4(void) {
401 const uint8_t teststr[] = { 0xde, 0xff, 0xfe, 0xf2, 'a', 'b', 'c' };
402 coap_option_t opt;
403
404 CU_ASSERT(0 == coap_opt_parse((const coap_opt_t *)teststr,
405 sizeof(teststr), &opt));
406 CU_ASSERT(opt.delta == 268);
407 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 65535);
408 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), teststr + 4);
409 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == 65535 + 4);
410 }
411
412 static void
t_access_option5(void)413 t_access_option5(void) {
414 const uint8_t teststr[] = { 0xee, 0xfe, 0xf2, 0x00, 0xdd, 'a', 'b', 'c' };
415 coap_option_t opt;
416
417 CU_ASSERT(0 == coap_opt_parse((const coap_opt_t *)teststr,
418 sizeof(teststr), &opt));
419 CU_ASSERT(opt.delta == 65535);
420 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 490);
421 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), teststr + 5);
422 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == 495);
423 }
424
425 static void
t_access_option6(void)426 t_access_option6(void) {
427 coap_log_t level = coap_get_log_level();
428 const uint8_t teststr[] = { 0xf2, 'a', 'b' };
429 coap_option_t opt;
430
431 coap_set_log_level(LOG_CRIT);
432
433 CU_ASSERT(0 == coap_opt_parse((const coap_opt_t *)teststr,
434 sizeof(teststr), &opt));
435 coap_set_log_level(level);
436 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 0);
437 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), NULL);
438 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == 0);
439 }
440
441 static void
t_access_option7(void)442 t_access_option7(void) {
443 const uint8_t teststr[] = { 0x2f, 'a', 'b' };
444 coap_option_t opt;
445
446 CU_ASSERT(0 == coap_opt_parse((const coap_opt_t *)teststr,
447 sizeof(teststr), &opt));
448 CU_ASSERT(opt.delta == 2);
449 CU_ASSERT(coap_opt_length((const coap_opt_t *)teststr) == 0);
450 CU_ASSERT_PTR_EQUAL_C(coap_opt_value((const coap_opt_t *)teststr), NULL);
451 CU_ASSERT(coap_opt_size((const coap_opt_t *)teststr) == 0);
452 }
453
454 /************************************************************************
455 ** accessor tests
456 ************************************************************************/
457
458 #define TEST_MAX_SIZE 1000
459
460 #ifdef _MSC_VER
461 # define ALIGNED(x)
462 #else
463 # define ALIGNED(x) __attribute__ ((aligned (x)))
464 #endif
465
466 static void
t_iterate_option1(void)467 t_iterate_option1(void) {
468 /* CoAP PDU without token, options, or data */
469 uint8_t teststr[] ALIGNED(8) = {
470 0x00, 0x00, 0x00, 0x00
471 };
472
473 coap_pdu_t pdu = {
474 .max_size = TEST_MAX_SIZE,
475 .token = teststr,
476 .used_size = 0
477 };
478 coap_opt_iterator_t oi, *result;
479 coap_opt_t *option;
480
481 result = coap_option_iterator_init(&pdu, &oi, COAP_OPT_ALL);
482
483 CU_ASSERT(result == NULL);
484 CU_ASSERT(oi.bad == 1);
485
486 option = coap_option_next(&oi);
487 CU_ASSERT(oi.bad == 1);
488 CU_ASSERT(option == NULL);
489 }
490
491 static void
t_iterate_option2(void)492 t_iterate_option2(void) {
493 /* CoAP PDU with token but without options and data */
494 uint8_t teststr[3] ALIGNED(8) = {
495 't', 'o', 'k'
496 };
497
498 coap_pdu_t pdu = {
499 .max_size = TEST_MAX_SIZE,
500 .token_length = 3,
501 .token = teststr,
502 .used_size = sizeof(teststr)
503 };
504 coap_opt_iterator_t oi, *result;
505 coap_opt_t *option;
506
507 result = coap_option_iterator_init(&pdu, &oi, COAP_OPT_ALL);
508
509 CU_ASSERT(result == NULL);
510 CU_ASSERT(oi.bad == 1);
511
512 option = coap_option_next(&oi);
513 CU_ASSERT(oi.bad == 1);
514 CU_ASSERT(option == NULL);
515 }
516
517 static void
t_iterate_option3(void)518 t_iterate_option3(void) {
519 /* CoAP PDU with token and options */
520 uint8_t teststr[] ALIGNED(8) = {
521 't', 'o', 'k', 0x13,
522 'o', 'p', 't', 0x00, 0xd1, 0x10, 'x'
523 };
524
525 coap_pdu_t pdu = {
526 .max_size = TEST_MAX_SIZE,
527 .token_length = 3,
528 .token = teststr,
529 .used_size = sizeof(teststr)
530 };
531 coap_opt_iterator_t oi, *result;
532 coap_opt_t *option;
533
534 result = coap_option_iterator_init(&pdu, &oi, COAP_OPT_ALL);
535
536 CU_ASSERT_PTR_EQUAL(result, &oi);
537 CU_ASSERT(oi.bad == 0);
538
539 option = coap_option_next(&oi);
540 CU_ASSERT(oi.bad == 0);
541 CU_ASSERT(oi.number == 1);
542 CU_ASSERT_PTR_EQUAL(option, teststr + 3);
543
544 option = coap_option_next(&oi);
545 CU_ASSERT(oi.bad == 0);
546 CU_ASSERT(oi.number == 1);
547 CU_ASSERT_PTR_EQUAL(option, teststr + 7);
548
549 option = coap_option_next(&oi);
550 CU_ASSERT(oi.bad == 0);
551 CU_ASSERT(oi.number == 30);
552 CU_ASSERT_PTR_EQUAL(option, teststr + 8);
553
554 option = coap_option_next(&oi);
555 CU_ASSERT(oi.bad == 1);
556 CU_ASSERT_PTR_EQUAL(option, NULL);
557 }
558
559 static void
t_iterate_option4(void)560 t_iterate_option4(void) {
561 /* CoAP PDU with token, options, and data */
562 uint8_t teststr[] ALIGNED(8) = {
563 't', 'o', 'k', 0x13,
564 'o', 'p', 't', 0x00, 0xd1, 0x10, 'x', 0xff,
565 'd', 'a', 't', 'a'
566 };
567
568 coap_pdu_t pdu = {
569 .max_size = TEST_MAX_SIZE,
570 .token_length = 3,
571 .token = teststr,
572 .used_size = sizeof(teststr)
573 };
574 coap_opt_iterator_t oi, *result;
575 coap_opt_t *option;
576
577 result = coap_option_iterator_init(&pdu, &oi, COAP_OPT_ALL);
578
579 CU_ASSERT_PTR_EQUAL(result, &oi);
580 CU_ASSERT(oi.bad == 0);
581
582 option = coap_option_next(&oi);
583 CU_ASSERT(oi.bad == 0);
584 CU_ASSERT(oi.number == 1);
585 CU_ASSERT_PTR_EQUAL(option, teststr + 3);
586
587 option = coap_option_next(&oi);
588 CU_ASSERT(oi.bad == 0);
589 CU_ASSERT(oi.number == 1);
590 CU_ASSERT_PTR_EQUAL(option, teststr + 7);
591
592 option = coap_option_next(&oi);
593 CU_ASSERT(oi.bad == 0);
594 CU_ASSERT(oi.number == 30);
595 CU_ASSERT_PTR_EQUAL(option, teststr + 8);
596
597 option = coap_option_next(&oi);
598 CU_ASSERT(oi.bad == 1);
599 CU_ASSERT_PTR_EQUAL(option, NULL);
600 }
601
602 static void
t_iterate_option5(void)603 t_iterate_option5(void) {
604 /* CoAP PDU with malformed option */
605 uint8_t teststr[] ALIGNED(8) = {
606 0x52, 'o', 'p', 0xee,
607 0x12, 0x03, 0x00
608 };
609
610 coap_pdu_t pdu = {
611 .max_size = TEST_MAX_SIZE,
612 .token_length = 0,
613 .token = teststr,
614 .used_size = sizeof(teststr)
615 };
616 coap_opt_iterator_t oi, *result;
617 coap_opt_t *option;
618
619 result = coap_option_iterator_init(&pdu, &oi, COAP_OPT_ALL);
620
621 CU_ASSERT_PTR_EQUAL(result, &oi);
622 CU_ASSERT(oi.bad == 0);
623
624 option = coap_option_next(&oi);
625 CU_ASSERT(oi.bad == 0);
626 CU_ASSERT(oi.number == 5);
627 CU_ASSERT_PTR_EQUAL(option, teststr);
628
629 option = coap_option_next(&oi);
630 CU_ASSERT(oi.bad == 1);
631 CU_ASSERT_PTR_EQUAL(option, NULL);
632 }
633
634 static void
t_iterate_option6(void)635 t_iterate_option6(void) {
636 /* option filter */
637 /* CoAP PDU with token, options, and data */
638 uint8_t teststr[] ALIGNED(8) = {
639 0x80, 0x20, 0x00, 0x00,
640 0xc0, 0x00
641 };
642
643 coap_pdu_t pdu = {
644 .max_size = TEST_MAX_SIZE,
645 .token_length = 0,
646 .token = teststr,
647 .used_size = sizeof(teststr)
648 };
649 coap_opt_iterator_t oi, *result;
650 coap_opt_t *option;
651 coap_opt_filter_t filter;
652
653 coap_option_filter_clear(&filter);
654 coap_option_filter_set(&filter, 10); /* option nr 10 only */
655 result = coap_option_iterator_init(&pdu, &oi, &filter);
656
657 CU_ASSERT_PTR_EQUAL(result, &oi);
658 CU_ASSERT(oi.bad == 0);
659
660 option = coap_option_next(&oi);
661 CU_ASSERT(oi.bad == 0);
662 CU_ASSERT(oi.number == 10);
663 CU_ASSERT_PTR_EQUAL(option, teststr + 1);
664
665 option = coap_option_next(&oi);
666 CU_ASSERT(oi.bad == 0);
667 CU_ASSERT(oi.number == 10);
668 CU_ASSERT_PTR_EQUAL(option, teststr + 2);
669
670 option = coap_option_next(&oi);
671 CU_ASSERT(oi.bad == 0);
672 CU_ASSERT(oi.number == 10);
673 CU_ASSERT_PTR_EQUAL(option, teststr + 3);
674
675 option = coap_option_next(&oi);
676 CU_ASSERT(oi.bad == 1);
677 CU_ASSERT_PTR_EQUAL(option, NULL);
678 }
679
680 static void
t_iterate_option7(void)681 t_iterate_option7(void) {
682 /* option filter */
683 uint8_t teststr[] ALIGNED(8) = {
684 0x80, 0x20, 0x00, 0x00,
685 0xc0, 0x00, 0x10, 0x10, 0x00
686 };
687
688 coap_pdu_t pdu = {
689 .max_size = TEST_MAX_SIZE,
690 .token_length = 0,
691 .token = teststr,
692 .used_size = sizeof(teststr)
693 };
694 coap_opt_iterator_t oi, *result;
695 coap_opt_t *option;
696 coap_opt_filter_t filter;
697
698 /* search options nr 8 and 22 */
699 coap_option_filter_clear(&filter);
700 coap_option_filter_set(&filter, 8);
701 coap_option_filter_set(&filter, 22);
702 result = coap_option_iterator_init(&pdu, &oi, &filter);
703
704 CU_ASSERT_PTR_EQUAL(result, &oi);
705 CU_ASSERT(oi.bad == 0);
706
707 option = coap_option_next(&oi);
708 CU_ASSERT(oi.bad == 0);
709 CU_ASSERT(oi.number == 8);
710 CU_ASSERT_PTR_EQUAL(option, teststr);
711
712 option = coap_option_next(&oi);
713 CU_ASSERT(oi.bad == 0);
714 CU_ASSERT(oi.number == 22);
715 CU_ASSERT_PTR_EQUAL(option, teststr + 4);
716
717 option = coap_option_next(&oi);
718 CU_ASSERT(oi.bad == 0);
719 CU_ASSERT(oi.number == 22);
720 CU_ASSERT_PTR_EQUAL(option, teststr + 5);
721
722 option = coap_option_next(&oi);
723 CU_ASSERT(oi.bad == 1);
724 CU_ASSERT_PTR_EQUAL(option, NULL);
725 }
726
727 static void
t_iterate_option8(void)728 t_iterate_option8(void) {
729 /* option filter */
730 uint8_t teststr[] ALIGNED(8) = {
731 0x80, 0x20, 0x00, 0x00,
732 0xc0, 0x00, 0x10, 0x10, 0x00
733 };
734
735 coap_pdu_t pdu = {
736 .max_size = TEST_MAX_SIZE,
737 .token_length = 0,
738 .token = teststr,
739 .used_size = sizeof(teststr)
740 };
741 coap_opt_iterator_t oi, *result;
742 coap_opt_t *option;
743 coap_opt_filter_t filter;
744
745 /* search option nr 36 */
746 coap_option_filter_clear(&filter);
747 coap_option_filter_set(&filter, 36);
748 result = coap_option_iterator_init(&pdu, &oi, &filter);
749
750 CU_ASSERT_PTR_EQUAL(result, &oi);
751 CU_ASSERT(oi.bad == 0);
752
753 option = coap_option_next(&oi);
754 CU_ASSERT(oi.bad == 1);
755 CU_ASSERT_PTR_EQUAL(option, NULL);
756 }
757
758 static void
t_iterate_option9(void)759 t_iterate_option9(void) {
760 /* options filter: option number too large for filter */
761 uint8_t teststr[] ALIGNED(8) = {
762 0x80, 0x20, 0x00, 0x00,
763 0xc0, 0x00, 0x10, 0x10, 0x00
764 };
765
766 coap_pdu_t pdu = {
767 .max_size = TEST_MAX_SIZE,
768 .token_length = 0,
769 .token = teststr,
770 .used_size = sizeof(teststr)
771 };
772 coap_opt_iterator_t oi, *result;
773 coap_opt_t *option;
774 coap_opt_filter_t filter;
775
776 /* search option nr 100 */
777 coap_option_filter_clear(&filter);
778 coap_option_filter_set(&filter, 100);
779 result = coap_option_iterator_init(&pdu, &oi, &filter);
780
781 CU_ASSERT_PTR_EQUAL(result, &oi);
782 CU_ASSERT(oi.bad == 0);
783
784 option = coap_option_next(&oi);
785 CU_ASSERT(oi.bad == 1);
786 CU_ASSERT_PTR_EQUAL(option, NULL);
787 }
788
789 static void
t_iterate_option10(void)790 t_iterate_option10(void) {
791 /* options filter: option numbers in PDU exceed filter size */
792 uint8_t teststr[] ALIGNED(8) = {
793 0x80, 0x20, 0x00, 0x00,
794 0xd0, 0x26, 0xe0, 0x10, 0x00
795 };
796
797 coap_pdu_t pdu = {
798 .max_size = TEST_MAX_SIZE,
799 .token_length = 0,
800 .token = teststr,
801 .used_size = sizeof(teststr)
802 };
803 coap_opt_iterator_t oi, *result;
804 coap_opt_t *option;
805 coap_opt_filter_t filter;
806
807 /* search option nr 61 */
808 coap_option_filter_clear(&filter);
809 coap_option_filter_set(&filter, 61);
810 result = coap_option_iterator_init(&pdu, &oi, &filter);
811
812 CU_ASSERT_PTR_EQUAL(result, &oi);
813 CU_ASSERT(oi.bad == 0);
814
815 option = coap_option_next(&oi);
816 CU_ASSERT(oi.bad == 0);
817 CU_ASSERT_PTR_EQUAL(option, teststr + 4);
818
819 option = coap_option_next(&oi);
820 CU_ASSERT(oi.bad == 1);
821 CU_ASSERT_PTR_EQUAL(option, NULL);
822 }
823
824 /************************************************************************
825 ** filter tests
826 ************************************************************************/
827
828 static void
t_filter_option1(void)829 t_filter_option1(void) {
830 coap_opt_filter_t filter;
831
832 coap_option_filter_clear(&filter);
833
834 CU_ASSERT(coap_option_filter_set(&filter, 0) == 1);
835 CU_ASSERT(coap_option_filter_set(&filter, 37) == 1);
836 CU_ASSERT(coap_option_filter_set(&filter, 37) == 1);
837 CU_ASSERT(coap_option_filter_set(&filter, 43) == 1);
838 CU_ASSERT(coap_option_filter_set(&filter, 290) == 1);
839 CU_ASSERT(coap_option_filter_set(&filter, 65535) == 1);
840
841 CU_ASSERT(coap_option_filter_get(&filter, 0) == 1);
842 CU_ASSERT(coap_option_filter_get(&filter, 37) == 1);
843 CU_ASSERT(coap_option_filter_get(&filter, 43) == 1);
844 CU_ASSERT(coap_option_filter_get(&filter, 290) == 1);
845 CU_ASSERT(coap_option_filter_get(&filter, 65535) == 1);
846
847 CU_ASSERT(coap_option_filter_unset(&filter, 37) == 1);
848
849 CU_ASSERT(coap_option_filter_get(&filter, 0) == 1);
850 CU_ASSERT(coap_option_filter_get(&filter, 43) == 1);
851 CU_ASSERT(coap_option_filter_get(&filter, 290) == 1);
852 CU_ASSERT(coap_option_filter_get(&filter, 65535) == 1);
853
854 CU_ASSERT(coap_option_filter_get(&filter, 37) == 0);
855 CU_ASSERT(coap_option_filter_get(&filter, 89) == 0);
856 }
857
858 static void
t_filter_option2(void)859 t_filter_option2(void) {
860 coap_opt_filter_t filter;
861 int s;
862
863 coap_option_filter_clear(&filter);
864
865 /* fill all COAP_OPT_FILTER_SHORT slots */
866 for (s = 0; s < COAP_OPT_FILTER_SHORT; s++) {
867 CU_ASSERT(coap_option_filter_set(&filter, s));
868 }
869
870 /* adding a short option type must fail */
871 CU_ASSERT(coap_option_filter_set(&filter, COAP_OPT_FILTER_SHORT) == 0);
872
873 /* adding a long option type must succeed */
874 CU_ASSERT(coap_option_filter_set(&filter, 256) == 1);
875 }
876
877 static void
t_filter_option3(void)878 t_filter_option3(void) {
879 coap_opt_filter_t filter;
880 int l;
881
882 coap_option_filter_clear(&filter);
883
884 /* set COAP_OPT_FILTER_LONG long filters */
885 for (l = 0; l < COAP_OPT_FILTER_LONG; l++) {
886 CU_ASSERT(coap_option_filter_set(&filter, 256 + l) == 1);
887 }
888
889 /* the next must fail and must not be found */
890 CU_ASSERT(coap_option_filter_set(&filter, 256 + COAP_OPT_FILTER_LONG) == 0);
891 CU_ASSERT(coap_option_filter_get(&filter, 256 + COAP_OPT_FILTER_LONG) == 0);
892
893 /* remove one item */
894 CU_ASSERT(coap_option_filter_unset(&filter, 256) == 1);
895 CU_ASSERT(coap_option_filter_get(&filter, 256) == 0);
896
897 /* now, storing a new filter must succeed */
898 CU_ASSERT(coap_option_filter_set(&filter, 256 + COAP_OPT_FILTER_LONG) == 1);
899 CU_ASSERT(coap_option_filter_get(&filter, 256 + COAP_OPT_FILTER_LONG) == 1);
900
901 /* and all other items must be available as well */
902 for (l = 0; l < COAP_OPT_FILTER_LONG; l++) {
903 CU_ASSERT(coap_option_filter_get(&filter, 256 + l + 1) == 1);
904 }
905
906 /* set COAP_OPT_FILTER_SHORT short filters */
907 for (l = 0; l < COAP_OPT_FILTER_SHORT; l++) {
908 CU_ASSERT(coap_option_filter_set(&filter, l) == 1);
909 }
910
911 /* the next must fail and must not be found */
912 CU_ASSERT(coap_option_filter_set(&filter, COAP_OPT_FILTER_SHORT) == 0);
913 CU_ASSERT(coap_option_filter_get(&filter, COAP_OPT_FILTER_SHORT) == 0);
914
915 /* remove one item */
916 CU_ASSERT(coap_option_filter_unset(&filter, 0) == 1);
917 CU_ASSERT(coap_option_filter_get(&filter, 0) == 0);
918
919 /* now, storing a new filter must succeed */
920 CU_ASSERT(coap_option_filter_set(&filter, COAP_OPT_FILTER_SHORT) == 1);
921 CU_ASSERT(coap_option_filter_get(&filter, COAP_OPT_FILTER_SHORT) == 1);
922
923 /* and all other items must be available as well */
924 for (l = 0; l < COAP_OPT_FILTER_SHORT; l++) {
925 CU_ASSERT(coap_option_filter_get(&filter, l + 1) == 1);
926 }
927 }
928
929 /************************************************************************
930 ** initialization
931 ************************************************************************/
932
933 CU_pSuite
t_init_option_tests(void)934 t_init_option_tests(void) {
935 CU_pSuite suite[5];
936
937 suite[0] = CU_add_suite("option parser", NULL, NULL);
938 if (!suite[0]) { /* signal error */
939 fprintf(stderr, "W: cannot add option parser test suite (%s)\n",
940 CU_get_error_msg());
941
942 return NULL;
943 }
944
945 #define OPTION_TEST(n,s) \
946 if (!CU_add_test(suite[0], s, t_parse_option##n)) { \
947 fprintf(stderr, "W: cannot add option parser test (%s)\n", \
948 CU_get_error_msg()); \
949 }
950
951 OPTION_TEST(1, "parse option #1");
952 OPTION_TEST(2, "parse option #2");
953 OPTION_TEST(3, "parse option #3");
954 OPTION_TEST(4, "parse option #4");
955 OPTION_TEST(5, "parse option #5");
956 OPTION_TEST(6, "parse option #6");
957 OPTION_TEST(7, "parse option #7");
958 OPTION_TEST(8, "parse option #8");
959 OPTION_TEST(9, "parse option #9");
960 OPTION_TEST(10, "parse option #10");
961 OPTION_TEST(11, "parse option #11");
962 OPTION_TEST(12, "parse option #12");
963 OPTION_TEST(13, "parse option #13");
964 OPTION_TEST(14, "parse option #14");
965
966 if ((suite[1] = CU_add_suite("option encoder", NULL, NULL))) {
967 #define OPTION_ENCODER_TEST(n,s) \
968 if (!CU_add_test(suite[1], s, t_encode_option##n)) { \
969 fprintf(stderr, "W: cannot add option encoder test (%s)\n", \
970 CU_get_error_msg()); \
971 }
972
973 OPTION_ENCODER_TEST(1, "encode option #1");
974 OPTION_ENCODER_TEST(2, "encode option #2");
975 OPTION_ENCODER_TEST(3, "encode option #3");
976 OPTION_ENCODER_TEST(4, "encode option #4");
977 OPTION_ENCODER_TEST(5, "encode option #5");
978 OPTION_ENCODER_TEST(6, "encode option #6");
979 OPTION_ENCODER_TEST(7, "encode option #7");
980 OPTION_ENCODER_TEST(8, "encode option #8");
981 OPTION_ENCODER_TEST(9, "encode option #9");
982
983 } else {
984 fprintf(stderr, "W: cannot add option encoder test suite (%s)\n",
985 CU_get_error_msg());
986 }
987
988 if ((suite[2] = CU_add_suite("option accessors", NULL, NULL))) {
989 #define OPTION_ACCESSOR_TEST(n,s) \
990 if (!CU_add_test(suite[2], s, t_access_option##n)) { \
991 fprintf(stderr, "W: cannot add option accessor function test (%s)\n", \
992 CU_get_error_msg()); \
993 }
994
995 OPTION_ACCESSOR_TEST(1, "access option #1");
996 OPTION_ACCESSOR_TEST(2, "access option #2");
997 OPTION_ACCESSOR_TEST(3, "access option #3");
998 OPTION_ACCESSOR_TEST(4, "access option #4");
999 OPTION_ACCESSOR_TEST(5, "access option #5");
1000 OPTION_ACCESSOR_TEST(6, "access option #6");
1001 OPTION_ACCESSOR_TEST(7, "access option #7");
1002
1003 } else {
1004 fprintf(stderr, "W: cannot add option acessor function test suite (%s)\n",
1005 CU_get_error_msg());
1006 }
1007
1008 if ((suite[3] = CU_add_suite("option iterator", NULL, NULL))) {
1009 #define OPTION_ITERATOR_TEST(n,s) \
1010 if (!CU_add_test(suite[3], s, t_iterate_option##n)) { \
1011 fprintf(stderr, "W: cannot add option iterator test (%s)\n", \
1012 CU_get_error_msg()); \
1013 }
1014
1015 OPTION_ITERATOR_TEST(1, "option iterator #1");
1016 OPTION_ITERATOR_TEST(2, "option iterator #2");
1017 OPTION_ITERATOR_TEST(3, "option iterator #3");
1018 OPTION_ITERATOR_TEST(4, "option iterator #4");
1019 OPTION_ITERATOR_TEST(5, "option iterator #5");
1020 OPTION_ITERATOR_TEST(6, "option iterator #6");
1021 OPTION_ITERATOR_TEST(7, "option iterator #7");
1022 OPTION_ITERATOR_TEST(8, "option iterator #8");
1023 OPTION_ITERATOR_TEST(9, "option iterator #9");
1024 OPTION_ITERATOR_TEST(10, "option iterator #10");
1025
1026 } else {
1027 fprintf(stderr, "W: cannot add option iterator test suite (%s)\n",
1028 CU_get_error_msg());
1029 }
1030
1031 if ((suite[4] = CU_add_suite("option filter", NULL, NULL))) {
1032 #define OPTION_FILTER_TEST(n,s) \
1033 if (!CU_add_test(suite[4], s, t_filter_option##n)) { \
1034 fprintf(stderr, "W: cannot add option filter test (%s)\n", \
1035 CU_get_error_msg()); \
1036 }
1037
1038 OPTION_FILTER_TEST(1, "option filter #1");
1039 OPTION_FILTER_TEST(2, "option filter #2");
1040 OPTION_FILTER_TEST(3, "option filter #3");
1041
1042 } else {
1043 fprintf(stderr, "W: cannot add option filter test suite (%s)\n",
1044 CU_get_error_msg());
1045 }
1046
1047 return suite[0];
1048 }
1049
1050