1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 38 #include "json/json_util.c" 39 40 /* For spdk_json_parse() */ 41 #include "json/json_parse.c" 42 43 #define NUM_SETUP(x) \ 44 snprintf(buf, sizeof(buf), "%s", x); \ 45 v.type = SPDK_JSON_VAL_NUMBER; \ 46 v.start = buf; \ 47 v.len = sizeof(x) - 1 48 49 #define NUM_UINT16_PASS(s, i) \ 50 NUM_SETUP(s); \ 51 CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) == 0); \ 52 CU_ASSERT(u16 == i) 53 54 #define NUM_UINT16_FAIL(s) \ 55 NUM_SETUP(s); \ 56 CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) != 0) 57 58 #define NUM_INT32_PASS(s, i) \ 59 NUM_SETUP(s); \ 60 CU_ASSERT(spdk_json_number_to_int32(&v, &i32) == 0); \ 61 CU_ASSERT(i32 == i) 62 63 #define NUM_INT32_FAIL(s) \ 64 NUM_SETUP(s); \ 65 CU_ASSERT(spdk_json_number_to_int32(&v, &i32) != 0) 66 67 #define NUM_UINT64_PASS(s, i) \ 68 NUM_SETUP(s); \ 69 CU_ASSERT(spdk_json_number_to_uint64(&v, &u64) == 0); \ 70 CU_ASSERT(u64 == i) 71 72 #define NUM_UINT64_FAIL(s) \ 73 NUM_SETUP(s); \ 74 CU_ASSERT(spdk_json_number_to_uint64(&v, &u64) != 0) 75 76 static void 77 test_strequal(void) 78 { 79 struct spdk_json_val v; 80 81 v.type = SPDK_JSON_VAL_STRING; 82 v.start = "test"; 83 v.len = sizeof("test") - 1; 84 CU_ASSERT(spdk_json_strequal(&v, "test") == true); 85 CU_ASSERT(spdk_json_strequal(&v, "TEST") == false); 86 CU_ASSERT(spdk_json_strequal(&v, "hello") == false); 87 CU_ASSERT(spdk_json_strequal(&v, "t") == false); 88 89 v.type = SPDK_JSON_VAL_NAME; 90 CU_ASSERT(spdk_json_strequal(&v, "test") == true); 91 92 v.type = SPDK_JSON_VAL_NUMBER; 93 CU_ASSERT(spdk_json_strequal(&v, "test") == false); 94 95 v.type = SPDK_JSON_VAL_STRING; 96 v.start = "test\0hello"; 97 v.len = sizeof("test\0hello") - 1; 98 CU_ASSERT(spdk_json_strequal(&v, "test") == false); 99 } 100 101 static void 102 test_num_to_uint16(void) 103 { 104 struct spdk_json_val v; 105 char buf[100]; 106 uint16_t u16 = 0; 107 108 NUM_SETUP("1234"); 109 CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) == 0); 110 CU_ASSERT(u16 == 1234); 111 112 NUM_UINT16_PASS("0", 0); 113 NUM_UINT16_PASS("1234", 1234); 114 NUM_UINT16_PASS("1234.00000", 1234); 115 NUM_UINT16_PASS("1.2e1", 12); 116 NUM_UINT16_PASS("12340e-1", 1234); 117 118 NUM_UINT16_FAIL("1.2"); 119 NUM_UINT16_FAIL("-1234"); 120 NUM_UINT16_FAIL("1.2E0"); 121 NUM_UINT16_FAIL("1.234e1"); 122 NUM_UINT16_FAIL("12341e-1"); 123 } 124 125 static void 126 test_num_to_int32(void) 127 { 128 struct spdk_json_val v; 129 char buf[100]; 130 int32_t i32 = 0; 131 132 NUM_SETUP("1234"); 133 CU_ASSERT(spdk_json_number_to_int32(&v, &i32) == 0); 134 CU_ASSERT(i32 == 1234); 135 136 137 NUM_INT32_PASS("0", 0); 138 NUM_INT32_PASS("1234", 1234); 139 NUM_INT32_PASS("-1234", -1234); 140 NUM_INT32_PASS("1234.00000", 1234); 141 NUM_INT32_PASS("1.2e1", 12); 142 NUM_INT32_PASS("12340e-1", 1234); 143 NUM_INT32_PASS("-0", 0); 144 145 NUM_INT32_FAIL("1.2"); 146 NUM_INT32_FAIL("1.2E0"); 147 NUM_INT32_FAIL("1.234e1"); 148 NUM_INT32_FAIL("12341e-1"); 149 } 150 151 static void 152 test_num_to_uint64(void) 153 { 154 struct spdk_json_val v; 155 char buf[100]; 156 uint64_t u64 = 0; 157 158 NUM_SETUP("1234"); 159 CU_ASSERT(spdk_json_number_to_uint64(&v, &u64) == 0); 160 CU_ASSERT(u64 == 1234); 161 162 163 NUM_UINT64_PASS("0", 0); 164 NUM_UINT64_PASS("1234", 1234); 165 NUM_UINT64_PASS("1234.00000", 1234); 166 NUM_UINT64_PASS("1.2e1", 12); 167 NUM_UINT64_PASS("12340e-1", 1234); 168 NUM_UINT64_PASS("123456780e-1", 12345678); 169 170 NUM_UINT64_FAIL("1.2"); 171 NUM_UINT64_FAIL("-1234"); 172 NUM_UINT64_FAIL("1.2E0"); 173 NUM_UINT64_FAIL("1.234e1"); 174 NUM_UINT64_FAIL("12341e-1"); 175 NUM_UINT64_FAIL("123456781e-1"); 176 } 177 178 static void 179 test_decode_object(void) 180 { 181 struct my_object { 182 char *my_name; 183 uint32_t my_int; 184 bool my_bool; 185 }; 186 struct spdk_json_val object[] = { 187 {"", 6, SPDK_JSON_VAL_OBJECT_BEGIN}, 188 {"first", 5, SPDK_JSON_VAL_NAME}, 189 {"HELLO", 5, SPDK_JSON_VAL_STRING}, 190 {"second", 6, SPDK_JSON_VAL_NAME}, 191 {"234", 3, SPDK_JSON_VAL_NUMBER}, 192 {"third", 5, SPDK_JSON_VAL_NAME}, 193 {"", 1, SPDK_JSON_VAL_TRUE}, 194 {"", 0, SPDK_JSON_VAL_OBJECT_END}, 195 }; 196 197 struct spdk_json_object_decoder decoders[] = { 198 {"first", offsetof(struct my_object, my_name), spdk_json_decode_string, false}, 199 {"second", offsetof(struct my_object, my_int), spdk_json_decode_uint32, false}, 200 {"third", offsetof(struct my_object, my_bool), spdk_json_decode_bool, false}, 201 {"fourth", offsetof(struct my_object, my_bool), spdk_json_decode_bool, true}, 202 }; 203 struct my_object output = { 204 .my_name = NULL, 205 .my_int = 0, 206 .my_bool = false, 207 }; 208 uint32_t answer = 234; 209 char *answer_str = "HELLO"; 210 bool answer_bool = true; 211 212 /* Passing Test: object containing simple types */ 213 CU_ASSERT(spdk_json_decode_object(object, decoders, 4, &output) == 0); 214 SPDK_CU_ASSERT_FATAL(output.my_name != NULL); 215 CU_ASSERT(memcmp(output.my_name, answer_str, 6) == 0); 216 CU_ASSERT(output.my_int == answer); 217 CU_ASSERT(output.my_bool == answer_bool); 218 219 /* Failing Test: member with no matching decoder */ 220 /* i.e. I remove the matching decoder from the boolean argument */ 221 CU_ASSERT(spdk_json_decode_object(object, decoders, 2, &output) != 0); 222 223 /* Failing Test: non-optional decoder with no corresponding member */ 224 225 decoders[3].optional = false; 226 CU_ASSERT(spdk_json_decode_object(object, decoders, 4, &output) != 0); 227 228 /* return to base state */ 229 decoders[3].optional = true; 230 231 /* Failing Test: duplicated names for json values */ 232 object[3].start = "first"; 233 object[3].len = 5; 234 CU_ASSERT(spdk_json_decode_object(object, decoders, 3, &output) != 0); 235 236 /* return to base state */ 237 object[3].start = "second"; 238 object[3].len = 6; 239 240 /* Failing Test: invalid value for decoder */ 241 object[2].start = "HELO"; 242 CU_ASSERT(spdk_json_decode_object(object, decoders, 3, &output) != 0); 243 244 /* return to base state */ 245 object[2].start = "HELLO"; 246 247 /* Failing Test: not an object */ 248 object[0].type = SPDK_JSON_VAL_ARRAY_BEGIN; 249 CU_ASSERT(spdk_json_decode_object(object, decoders, 3, &output) != 0); 250 251 free(output.my_name); 252 } 253 254 static void 255 test_decode_array(void) 256 { 257 struct spdk_json_val values[4]; 258 uint32_t my_int[2] = {0, 0}; 259 char *my_string[2] = {NULL, NULL}; 260 size_t out_size; 261 262 /* passing integer test */ 263 values[0].type = SPDK_JSON_VAL_ARRAY_BEGIN; 264 values[0].len = 2; 265 values[1].type = SPDK_JSON_VAL_NUMBER; 266 values[1].len = 4; 267 values[1].start = "1234"; 268 values[2].type = SPDK_JSON_VAL_NUMBER; 269 values[2].len = 4; 270 values[2].start = "5678"; 271 values[3].type = SPDK_JSON_VAL_ARRAY_END; 272 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 273 sizeof(uint32_t)) == 0); 274 CU_ASSERT(my_int[0] == 1234); 275 CU_ASSERT(my_int[1] == 5678); 276 CU_ASSERT(out_size == 2); 277 278 /* array length exceeds max */ 279 values[0].len = 3; 280 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 281 sizeof(uint32_t)) != 0); 282 283 /* mixed types */ 284 values[0].len = 2; 285 values[2].type = SPDK_JSON_VAL_STRING; 286 values[2].len = 5; 287 values[2].start = "HELLO"; 288 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 289 sizeof(uint32_t)) != 0); 290 291 /* no array start */ 292 values[0].type = SPDK_JSON_VAL_NUMBER; 293 values[2].type = SPDK_JSON_VAL_NUMBER; 294 values[2].len = 4; 295 values[2].start = "5678"; 296 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 297 sizeof(uint32_t)) != 0); 298 299 /* mismatched array type and parser */ 300 values[0].type = SPDK_JSON_VAL_ARRAY_BEGIN; 301 values[1].type = SPDK_JSON_VAL_STRING; 302 values[1].len = 5; 303 values[1].start = "HELLO"; 304 values[2].type = SPDK_JSON_VAL_STRING; 305 values[2].len = 5; 306 values[2].start = "WORLD"; 307 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 308 sizeof(uint32_t)) != 0); 309 310 /* passing String example */ 311 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_string, my_string, 2, &out_size, 312 sizeof(char *)) == 0); 313 SPDK_CU_ASSERT_FATAL(my_string[0] != NULL); 314 SPDK_CU_ASSERT_FATAL(my_string[1] != NULL); 315 CU_ASSERT(memcmp(my_string[0], "HELLO", 6) == 0); 316 CU_ASSERT(memcmp(my_string[1], "WORLD", 6) == 0); 317 CU_ASSERT(out_size == 2); 318 319 free(my_string[0]); 320 free(my_string[1]); 321 } 322 323 static void 324 test_decode_bool(void) 325 { 326 struct spdk_json_val v; 327 bool b; 328 329 /* valid bool (true) */ 330 v.type = SPDK_JSON_VAL_TRUE; 331 b = false; 332 CU_ASSERT(spdk_json_decode_bool(&v, &b) == 0); 333 CU_ASSERT(b == true); 334 335 /* valid bool (false) */ 336 v.type = SPDK_JSON_VAL_FALSE; 337 b = true; 338 CU_ASSERT(spdk_json_decode_bool(&v, &b) == 0); 339 CU_ASSERT(b == false); 340 341 /* incorrect type */ 342 v.type = SPDK_JSON_VAL_NULL; 343 CU_ASSERT(spdk_json_decode_bool(&v, &b) != 0); 344 } 345 346 static void 347 test_decode_int32(void) 348 { 349 struct spdk_json_val v; 350 int32_t i; 351 352 /* correct type and valid value */ 353 v.type = SPDK_JSON_VAL_NUMBER; 354 v.start = "33"; 355 v.len = 2; 356 i = 0; 357 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 358 CU_ASSERT(i == 33); 359 360 /* correct type and invalid value (float) */ 361 v.start = "32.45"; 362 v.len = 5; 363 i = 0; 364 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 365 366 /* incorrect type */ 367 v.type = SPDK_JSON_VAL_STRING; 368 v.start = "String"; 369 v.len = 6; 370 i = 0; 371 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 372 373 /* incorrect type */ 374 v.type = SPDK_JSON_VAL_TRUE; 375 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 376 377 /* edge case (integer max) */ 378 v.type = SPDK_JSON_VAL_NUMBER; 379 v.start = "2147483647"; 380 v.len = 10; 381 i = 0; 382 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 383 CU_ASSERT(i == 2147483647); 384 385 /* invalid value (overflow) */ 386 v.start = "2147483648"; 387 i = 0; 388 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 389 390 /* edge case (integer min) */ 391 v.type = SPDK_JSON_VAL_NUMBER; 392 v.start = "-2147483648"; 393 v.len = 11; 394 i = 0; 395 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 396 CU_ASSERT(i == -2147483648); 397 398 /* invalid value (overflow) */ 399 v.start = "-2147483649"; 400 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 401 402 /* valid exponent */ 403 v.start = "4e3"; 404 v.len = 3; 405 i = 0; 406 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 407 CU_ASSERT(i == 4000); 408 409 /* invalid negative exponent */ 410 v.start = "-400e-4"; 411 v.len = 7; 412 i = 0; 413 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 414 415 /* invalid negative exponent */ 416 v.start = "400e-4"; 417 v.len = 6; 418 i = 0; 419 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 420 421 /* valid negative exponent */ 422 v.start = "-400e-2"; 423 v.len = 7; 424 i = 0; 425 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 426 CU_ASSERT(i == -4); 427 428 /* invalid exponent (overflow) */ 429 v.start = "-2e32"; 430 v.len = 5; 431 i = 0; 432 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 433 434 /* valid exponent with decimal */ 435 v.start = "2.13e2"; 436 v.len = 6; 437 i = 0; 438 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 439 CU_ASSERT(i == 213); 440 441 /* invalid exponent with decimal */ 442 v.start = "2.134e2"; 443 v.len = 7; 444 i = 0; 445 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 446 } 447 448 static void 449 test_decode_uint16(void) 450 { 451 struct spdk_json_val v; 452 uint32_t i; 453 454 /* incorrect type */ 455 v.type = SPDK_JSON_VAL_STRING; 456 v.start = "Strin"; 457 v.len = 5; 458 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 459 460 /* invalid value (float) */ 461 v.type = SPDK_JSON_VAL_NUMBER; 462 v.start = "123.4"; 463 v.len = 5; 464 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 465 466 /* edge case (0) */ 467 v.start = "0"; 468 v.len = 1; 469 i = 456; 470 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 471 CU_ASSERT(i == 0); 472 473 /* invalid value (negative) */ 474 v.start = "-1"; 475 v.len = 2; 476 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 477 478 /* edge case (maximum) */ 479 v.start = "65535"; 480 v.len = 5; 481 i = 0; 482 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 483 CU_ASSERT(i == 65535); 484 485 /* invalid value (overflow) */ 486 v.start = "65536"; 487 v.len = 5; 488 i = 0; 489 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 490 491 /* valid exponent */ 492 v.start = "66E2"; 493 v.len = 4; 494 i = 0; 495 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 496 CU_ASSERT(i == 6600); 497 498 /* invalid exponent (overflow) */ 499 v.start = "66E3"; 500 v.len = 4; 501 i = 0; 502 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 503 504 /* invalid exponent (decimal) */ 505 v.start = "65.535E2"; 506 v.len = 7; 507 i = 0; 508 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 509 510 /* valid exponent with decimal */ 511 v.start = "65.53E2"; 512 v.len = 7; 513 i = 0; 514 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 515 CU_ASSERT(i == 6553); 516 517 /* invalid negative exponent */ 518 v.start = "40e-2"; 519 v.len = 5; 520 i = 0; 521 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 522 523 /* invalid negative exponent */ 524 v.start = "-40e-1"; 525 v.len = 6; 526 i = 0; 527 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 528 529 /* valid negative exponent */ 530 v.start = "40e-1"; 531 v.len = 5; 532 i = 0; 533 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 534 CU_ASSERT(i == 4); 535 } 536 537 static void 538 test_decode_uint32(void) 539 { 540 struct spdk_json_val v; 541 uint32_t i; 542 543 /* incorrect type */ 544 v.type = SPDK_JSON_VAL_STRING; 545 v.start = "String"; 546 v.len = 6; 547 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 548 549 /* invalid value (float) */ 550 v.type = SPDK_JSON_VAL_NUMBER; 551 v.start = "123.45"; 552 v.len = 6; 553 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 554 555 /* edge case (0) */ 556 v.start = "0"; 557 v.len = 1; 558 i = 456; 559 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 560 CU_ASSERT(i == 0); 561 562 /* invalid value (negative) */ 563 v.start = "-1"; 564 v.len = 2; 565 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 566 567 /* edge case (maximum) */ 568 v.start = "4294967295"; 569 v.len = 10; 570 i = 0; 571 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 572 CU_ASSERT(i == 4294967295); 573 574 /* invalid value (overflow) */ 575 v.start = "4294967296"; 576 v.len = 10; 577 i = 0; 578 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 579 580 /* valid exponent */ 581 v.start = "42E2"; 582 v.len = 4; 583 i = 0; 584 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 585 CU_ASSERT(i == 4200); 586 587 /* invalid exponent (overflow) */ 588 v.start = "42e32"; 589 v.len = 5; 590 i = 0; 591 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 592 593 /* invalid exponent (decimal) */ 594 v.start = "42.323E2"; 595 v.len = 8; 596 i = 0; 597 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 598 599 /* valid exponent with decimal */ 600 v.start = "42.32E2"; 601 v.len = 7; 602 i = 0; 603 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 604 CU_ASSERT(i == 4232); 605 606 /* invalid negative exponent */ 607 v.start = "400e-4"; 608 v.len = 6; 609 i = 0; 610 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 611 612 /* invalid negative exponent */ 613 v.start = "-400e-2"; 614 v.len = 7; 615 i = 0; 616 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 617 618 /* valid negative exponent */ 619 v.start = "400e-2"; 620 v.len = 6; 621 i = 0; 622 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 623 CU_ASSERT(i == 4); 624 625 /* valid negative exponent */ 626 v.start = "10e-1"; 627 v.len = 5; 628 i = 0; 629 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 630 CU_ASSERT(i == 1); 631 } 632 633 static void 634 test_decode_uint64(void) 635 { 636 struct spdk_json_val v; 637 uint64_t i; 638 639 /* incorrect type */ 640 v.type = SPDK_JSON_VAL_STRING; 641 v.start = "String"; 642 v.len = 6; 643 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 644 645 /* invalid value (float) */ 646 v.type = SPDK_JSON_VAL_NUMBER; 647 v.start = "123.45"; 648 v.len = 6; 649 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 650 651 /* edge case (0) */ 652 v.start = "0"; 653 v.len = 1; 654 i = 456; 655 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 656 CU_ASSERT(i == 0); 657 658 /* invalid value (negative) */ 659 v.start = "-1"; 660 v.len = 2; 661 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 662 663 /* edge case (maximum) */ 664 v.start = "18446744073709551615"; 665 v.len = 20; 666 i = 0; 667 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 668 CU_ASSERT(i == 18446744073709551615U); 669 670 /* invalid value (overflow) */ 671 v.start = "18446744073709551616"; 672 v.len = 20; 673 i = 0; 674 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 675 676 /* valid exponent */ 677 v.start = "42E2"; 678 v.len = 4; 679 i = 0; 680 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 681 CU_ASSERT(i == 4200); 682 683 /* invalid exponent (overflow) */ 684 v.start = "42e64"; 685 v.len = 5; 686 i = 0; 687 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 688 689 /* invalid exponent (decimal) */ 690 v.start = "42.323E2"; 691 v.len = 8; 692 i = 0; 693 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 694 695 /* valid exponent with decimal */ 696 v.start = "42.32E2"; 697 v.len = 7; 698 i = 0; 699 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 700 CU_ASSERT(i == 4232); 701 702 /* invalid negative exponent */ 703 v.start = "400e-4"; 704 v.len = 6; 705 i = 0; 706 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 707 708 /* invalid negative exponent */ 709 v.start = "-400e-2"; 710 v.len = 7; 711 i = 0; 712 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 713 714 /* valid negative exponent */ 715 v.start = "400e-2"; 716 v.len = 6; 717 i = 0; 718 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 719 CU_ASSERT(i == 4); 720 } 721 722 static void 723 test_decode_string(void) 724 { 725 struct spdk_json_val v; 726 char *value = NULL; 727 728 /* Passing Test: Standard */ 729 v.type = SPDK_JSON_VAL_STRING; 730 v.start = "HELLO"; 731 v.len = 5; 732 CU_ASSERT(spdk_json_decode_string(&v, &value) == 0); 733 SPDK_CU_ASSERT_FATAL(value != NULL); 734 CU_ASSERT(memcmp(value, v.start, 6) == 0); 735 736 /* Edge Test: Empty String */ 737 v.start = ""; 738 v.len = 0; 739 CU_ASSERT(spdk_json_decode_string(&v, &value) == 0); 740 SPDK_CU_ASSERT_FATAL(value != NULL); 741 CU_ASSERT(memcmp(value, v.start, 1) == 0); 742 743 /* 744 * Failing Test: Null Terminator In String 745 * It is valid for a json string to contain \u0000 and the parser will accept it. 746 * However, a null terminated C string cannot contain '\0' and should be rejected 747 * if that character is found before the end of the string. 748 */ 749 v.start = "HELO"; 750 v.len = 5; 751 CU_ASSERT(spdk_json_decode_string(&v, &value) != 0); 752 753 /* Failing Test: Wrong Type */ 754 v.start = "45673"; 755 v.type = SPDK_JSON_VAL_NUMBER; 756 CU_ASSERT(spdk_json_decode_string(&v, &value) != 0); 757 758 /* Passing Test: Special Characters */ 759 v.type = SPDK_JSON_VAL_STRING; 760 v.start = "HE\bLL\tO\\WORLD"; 761 v.len = 13; 762 CU_ASSERT(spdk_json_decode_string(&v, &value) == 0); 763 SPDK_CU_ASSERT_FATAL(value != NULL); 764 CU_ASSERT(memcmp(value, v.start, 14) == 0); 765 766 free(value); 767 } 768 769 char ut_json_text[] = 770 "{" 771 " \"string\": \"Some string data\"," 772 " \"object\": { " 773 " \"another_string\": \"Yet anoter string data\"," 774 " \"array name with space\": [1, [], {} ]" 775 " }," 776 " \"array\": [ \"Text\", 2, {} ]" 777 "}" 778 ; 779 780 static void 781 test_find(void) 782 { 783 struct spdk_json_val *values, *key, *val, *key2, *val2; 784 ssize_t values_cnt; 785 ssize_t rc; 786 787 values_cnt = spdk_json_parse(ut_json_text, strlen(ut_json_text), NULL, 0, NULL, 0); 788 SPDK_CU_ASSERT_FATAL(values_cnt > 0); 789 790 values = calloc(values_cnt, sizeof(struct spdk_json_val)); 791 SPDK_CU_ASSERT_FATAL(values != NULL); 792 793 rc = spdk_json_parse(ut_json_text, strlen(ut_json_text), values, values_cnt, NULL, 0); 794 SPDK_CU_ASSERT_FATAL(values_cnt == rc); 795 796 key = val = NULL; 797 rc = spdk_json_find(values, "string", &key, &val, SPDK_JSON_VAL_STRING); 798 CU_ASSERT(rc == 0); 799 800 CU_ASSERT(key != NULL && spdk_json_strequal(key, "string") == true); 801 CU_ASSERT(val != NULL && spdk_json_strequal(val, "Some string data") == true); 802 803 key = val = NULL; 804 rc = spdk_json_find(values, "object", &key, &val, SPDK_JSON_VAL_OBJECT_BEGIN); 805 CU_ASSERT(rc == 0); 806 807 CU_ASSERT(key != NULL && spdk_json_strequal(key, "object") == true); 808 809 /* Find key in "object" by passing SPDK_JSON_VAL_ANY to match any type */ 810 key2 = val2 = NULL; 811 rc = spdk_json_find(val, "array name with space", &key2, &val2, SPDK_JSON_VAL_ANY); 812 CU_ASSERT(rc == 0); 813 CU_ASSERT(key2 != NULL && spdk_json_strequal(key2, "array name with space") == true); 814 CU_ASSERT(val2 != NULL && val2->type == SPDK_JSON_VAL_ARRAY_BEGIN); 815 816 /* Find the "array" key in "object" by passing SPDK_JSON_VAL_ARRAY_BEGIN to match only array */ 817 key2 = val2 = NULL; 818 rc = spdk_json_find(val, "array name with space", &key2, &val2, SPDK_JSON_VAL_ARRAY_BEGIN); 819 CU_ASSERT(rc == 0); 820 CU_ASSERT(key2 != NULL && spdk_json_strequal(key2, "array name with space") == true); 821 CU_ASSERT(val2 != NULL && val2->type == SPDK_JSON_VAL_ARRAY_BEGIN); 822 823 /* Negative test - key doesn't exist */ 824 key2 = val2 = NULL; 825 rc = spdk_json_find(val, "this_key_does_not_exist", &key2, &val2, SPDK_JSON_VAL_ANY); 826 CU_ASSERT(rc == -ENOENT); 827 828 /* Negative test - key type doesn't match */ 829 key2 = val2 = NULL; 830 rc = spdk_json_find(val, "another_string", &key2, &val2, SPDK_JSON_VAL_ARRAY_BEGIN); 831 CU_ASSERT(rc == -EDOM); 832 833 free(values); 834 } 835 836 static void 837 test_iterating(void) 838 { 839 struct spdk_json_val *values; 840 struct spdk_json_val *string_key; 841 struct spdk_json_val *object_key, *object_val; 842 struct spdk_json_val *array_key, *array_val; 843 struct spdk_json_val *another_string_key; 844 struct spdk_json_val *array_name_with_space_key, *array_name_with_space_val; 845 struct spdk_json_val *it; 846 ssize_t values_cnt; 847 ssize_t rc; 848 849 values_cnt = spdk_json_parse(ut_json_text, strlen(ut_json_text), NULL, 0, NULL, 0); 850 SPDK_CU_ASSERT_FATAL(values_cnt > 0); 851 852 values = calloc(values_cnt, sizeof(struct spdk_json_val)); 853 SPDK_CU_ASSERT_FATAL(values != NULL); 854 855 rc = spdk_json_parse(ut_json_text, strlen(ut_json_text), values, values_cnt, NULL, 0); 856 SPDK_CU_ASSERT_FATAL(values_cnt == rc); 857 858 /* Iterate over object keys. JSON spec doesn't guarantee order of keys in object but 859 * SPDK implementation implicitly does. 860 */ 861 string_key = spdk_json_object_first(values); 862 CU_ASSERT(spdk_json_strequal(string_key, "string") == true); 863 864 object_key = spdk_json_next(string_key); 865 object_val = spdk_json_value(object_key); 866 CU_ASSERT(spdk_json_strequal(object_key, "object") == true); 867 868 array_key = spdk_json_next(object_key); 869 array_val = spdk_json_value(array_key); 870 CU_ASSERT(spdk_json_strequal(array_key, "array") == true); 871 872 /* NULL '}' */ 873 CU_ASSERT(spdk_json_next(array_key) == NULL); 874 875 /* Iterate over subobjects */ 876 another_string_key = spdk_json_object_first(object_val); 877 CU_ASSERT(spdk_json_strequal(another_string_key, "another_string") == true); 878 879 array_name_with_space_key = spdk_json_next(another_string_key); 880 array_name_with_space_val = spdk_json_value(array_name_with_space_key); 881 CU_ASSERT(spdk_json_strequal(array_name_with_space_key, "array name with space") == true); 882 883 CU_ASSERT(spdk_json_next(array_name_with_space_key) == NULL); 884 885 /* Iterate over array in subobject */ 886 it = spdk_json_array_first(array_name_with_space_val); 887 SPDK_CU_ASSERT_FATAL(it != NULL); 888 CU_ASSERT(it->type == SPDK_JSON_VAL_NUMBER); 889 890 it = spdk_json_next(it); 891 SPDK_CU_ASSERT_FATAL(it != NULL); 892 CU_ASSERT(it->type == SPDK_JSON_VAL_ARRAY_BEGIN); 893 894 it = spdk_json_next(it); 895 SPDK_CU_ASSERT_FATAL(it != NULL); 896 CU_ASSERT(it->type == SPDK_JSON_VAL_OBJECT_BEGIN); 897 898 it = spdk_json_next(it); 899 CU_ASSERT(it == NULL); 900 901 /* Iterate over array in root object */ 902 it = spdk_json_array_first(array_val); 903 SPDK_CU_ASSERT_FATAL(it != NULL); 904 CU_ASSERT(it->type == SPDK_JSON_VAL_STRING); 905 906 it = spdk_json_next(it); 907 SPDK_CU_ASSERT_FATAL(it != NULL); 908 CU_ASSERT(it->type == SPDK_JSON_VAL_NUMBER); 909 910 it = spdk_json_next(it); 911 SPDK_CU_ASSERT_FATAL(it != NULL); 912 CU_ASSERT(it->type == SPDK_JSON_VAL_OBJECT_BEGIN); 913 914 /* Array end */ 915 it = spdk_json_next(it); 916 CU_ASSERT(it == NULL); 917 918 free(values); 919 } 920 921 int main(int argc, char **argv) 922 { 923 CU_pSuite suite = NULL; 924 unsigned int num_failures; 925 926 CU_set_error_action(CUEA_ABORT); 927 CU_initialize_registry(); 928 929 suite = CU_add_suite("json", NULL, NULL); 930 931 CU_ADD_TEST(suite, test_strequal); 932 CU_ADD_TEST(suite, test_num_to_uint16); 933 CU_ADD_TEST(suite, test_num_to_int32); 934 CU_ADD_TEST(suite, test_num_to_uint64); 935 CU_ADD_TEST(suite, test_decode_object); 936 CU_ADD_TEST(suite, test_decode_array); 937 CU_ADD_TEST(suite, test_decode_bool); 938 CU_ADD_TEST(suite, test_decode_uint16); 939 CU_ADD_TEST(suite, test_decode_int32); 940 CU_ADD_TEST(suite, test_decode_uint32); 941 CU_ADD_TEST(suite, test_decode_uint64); 942 CU_ADD_TEST(suite, test_decode_string); 943 CU_ADD_TEST(suite, test_find); 944 CU_ADD_TEST(suite, test_iterating); 945 946 CU_basic_set_mode(CU_BRM_VERBOSE); 947 948 CU_basic_run_tests(); 949 950 num_failures = CU_get_number_of_failures(); 951 CU_cleanup_registry(); 952 953 return num_failures; 954 } 955