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 22static void 23t_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 38static void 39t_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 53static void 54t_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 71static void 72t_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 83static void 84t_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 95static void 96t_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 107static void 108t_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 121static void 122t_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 135static void 136t_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 148static void 149t_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 160static void 161t_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 172static void 173t_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 184static void 185t_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 205static void 206t_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 237static void 238t_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 249static void 250t_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 261static void 262t_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 273static void 274t_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 285static void 286t_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 297static void 298t_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 309static void 310t_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 325static void 326t_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 342static void 343t_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 358static void 359t_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 371static void 372t_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 384static void 385t_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 400static void 401t_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 413static void 414t_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 426static void 427t_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 442static void 443t_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 467static void 468t_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 492static void 493t_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 518static void 519t_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 560static void 561t_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 603static void 604t_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 635static void 636t_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 681static void 682t_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 728static void 729t_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 759static void 760t_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 790static void 791t_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 829static void 830t_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 859static void 860t_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 878static void 879t_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 934CU_pSuite 935t_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