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