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_free_object(void) 256 { 257 struct my_object { 258 char *my_name; 259 uint32_t my_int; 260 char *my_other_name; 261 char *empty_string; 262 }; 263 struct spdk_json_object_decoder decoders[] = { 264 {"first", offsetof(struct my_object, my_name), spdk_json_decode_string, false}, 265 {"second", offsetof(struct my_object, my_int), spdk_json_decode_uint32, false}, 266 {"third", offsetof(struct my_object, my_other_name), spdk_json_decode_string, true}, 267 {"fourth", offsetof(struct my_object, empty_string), spdk_json_decode_string, false}, 268 }; 269 struct my_object output = { 270 .my_name = strdup("hello"), 271 .my_int = 3, 272 .my_other_name = strdup("world"), 273 .empty_string = NULL 274 }; 275 276 SPDK_CU_ASSERT_FATAL(output.my_name != NULL); 277 SPDK_CU_ASSERT_FATAL(output.my_other_name != NULL); 278 279 spdk_json_free_object(decoders, 4, &output); 280 CU_ASSERT(output.my_name == NULL); 281 CU_ASSERT(output.my_other_name == NULL); 282 CU_ASSERT(output.empty_string == NULL); 283 } 284 285 static void 286 test_decode_array(void) 287 { 288 struct spdk_json_val values[4]; 289 uint32_t my_int[2] = {0, 0}; 290 char *my_string[2] = {NULL, NULL}; 291 size_t out_size; 292 293 /* passing integer test */ 294 values[0].type = SPDK_JSON_VAL_ARRAY_BEGIN; 295 values[0].len = 2; 296 values[1].type = SPDK_JSON_VAL_NUMBER; 297 values[1].len = 4; 298 values[1].start = "1234"; 299 values[2].type = SPDK_JSON_VAL_NUMBER; 300 values[2].len = 4; 301 values[2].start = "5678"; 302 values[3].type = SPDK_JSON_VAL_ARRAY_END; 303 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 304 sizeof(uint32_t)) == 0); 305 CU_ASSERT(my_int[0] == 1234); 306 CU_ASSERT(my_int[1] == 5678); 307 CU_ASSERT(out_size == 2); 308 309 /* array length exceeds max */ 310 values[0].len = 3; 311 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 312 sizeof(uint32_t)) != 0); 313 314 /* mixed types */ 315 values[0].len = 2; 316 values[2].type = SPDK_JSON_VAL_STRING; 317 values[2].len = 5; 318 values[2].start = "HELLO"; 319 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 320 sizeof(uint32_t)) != 0); 321 322 /* no array start */ 323 values[0].type = SPDK_JSON_VAL_NUMBER; 324 values[2].type = SPDK_JSON_VAL_NUMBER; 325 values[2].len = 4; 326 values[2].start = "5678"; 327 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 328 sizeof(uint32_t)) != 0); 329 330 /* mismatched array type and parser */ 331 values[0].type = SPDK_JSON_VAL_ARRAY_BEGIN; 332 values[1].type = SPDK_JSON_VAL_STRING; 333 values[1].len = 5; 334 values[1].start = "HELLO"; 335 values[2].type = SPDK_JSON_VAL_STRING; 336 values[2].len = 5; 337 values[2].start = "WORLD"; 338 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size, 339 sizeof(uint32_t)) != 0); 340 341 /* passing String example */ 342 CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_string, my_string, 2, &out_size, 343 sizeof(char *)) == 0); 344 SPDK_CU_ASSERT_FATAL(my_string[0] != NULL); 345 SPDK_CU_ASSERT_FATAL(my_string[1] != NULL); 346 CU_ASSERT(memcmp(my_string[0], "HELLO", 6) == 0); 347 CU_ASSERT(memcmp(my_string[1], "WORLD", 6) == 0); 348 CU_ASSERT(out_size == 2); 349 350 free(my_string[0]); 351 free(my_string[1]); 352 } 353 354 static void 355 test_decode_bool(void) 356 { 357 struct spdk_json_val v; 358 bool b; 359 360 /* valid bool (true) */ 361 v.type = SPDK_JSON_VAL_TRUE; 362 b = false; 363 CU_ASSERT(spdk_json_decode_bool(&v, &b) == 0); 364 CU_ASSERT(b == true); 365 366 /* valid bool (false) */ 367 v.type = SPDK_JSON_VAL_FALSE; 368 b = true; 369 CU_ASSERT(spdk_json_decode_bool(&v, &b) == 0); 370 CU_ASSERT(b == false); 371 372 /* incorrect type */ 373 v.type = SPDK_JSON_VAL_NULL; 374 CU_ASSERT(spdk_json_decode_bool(&v, &b) != 0); 375 } 376 377 static void 378 test_decode_int32(void) 379 { 380 struct spdk_json_val v; 381 int32_t i; 382 383 /* correct type and valid value */ 384 v.type = SPDK_JSON_VAL_NUMBER; 385 v.start = "33"; 386 v.len = 2; 387 i = 0; 388 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 389 CU_ASSERT(i == 33); 390 391 /* correct type and invalid value (float) */ 392 v.start = "32.45"; 393 v.len = 5; 394 i = 0; 395 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 396 397 /* incorrect type */ 398 v.type = SPDK_JSON_VAL_STRING; 399 v.start = "String"; 400 v.len = 6; 401 i = 0; 402 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 403 404 /* incorrect type */ 405 v.type = SPDK_JSON_VAL_TRUE; 406 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 407 408 /* edge case (integer max) */ 409 v.type = SPDK_JSON_VAL_NUMBER; 410 v.start = "2147483647"; 411 v.len = 10; 412 i = 0; 413 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 414 CU_ASSERT(i == 2147483647); 415 416 /* invalid value (overflow) */ 417 v.start = "2147483648"; 418 i = 0; 419 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 420 421 /* edge case (integer min) */ 422 v.type = SPDK_JSON_VAL_NUMBER; 423 v.start = "-2147483648"; 424 v.len = 11; 425 i = 0; 426 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 427 CU_ASSERT(i == -2147483648); 428 429 /* invalid value (overflow) */ 430 v.start = "-2147483649"; 431 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 432 433 /* valid exponent */ 434 v.start = "4e3"; 435 v.len = 3; 436 i = 0; 437 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 438 CU_ASSERT(i == 4000); 439 440 /* invalid negative exponent */ 441 v.start = "-400e-4"; 442 v.len = 7; 443 i = 0; 444 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 445 446 /* invalid negative exponent */ 447 v.start = "400e-4"; 448 v.len = 6; 449 i = 0; 450 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 451 452 /* valid negative exponent */ 453 v.start = "-400e-2"; 454 v.len = 7; 455 i = 0; 456 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 457 CU_ASSERT(i == -4); 458 459 /* invalid exponent (overflow) */ 460 v.start = "-2e32"; 461 v.len = 5; 462 i = 0; 463 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 464 465 /* valid exponent with decimal */ 466 v.start = "2.13e2"; 467 v.len = 6; 468 i = 0; 469 CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0); 470 CU_ASSERT(i == 213); 471 472 /* invalid exponent with decimal */ 473 v.start = "2.134e2"; 474 v.len = 7; 475 i = 0; 476 CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0); 477 } 478 479 static void 480 test_decode_uint16(void) 481 { 482 struct spdk_json_val v; 483 uint32_t i; 484 485 /* incorrect type */ 486 v.type = SPDK_JSON_VAL_STRING; 487 v.start = "Strin"; 488 v.len = 5; 489 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 490 491 /* invalid value (float) */ 492 v.type = SPDK_JSON_VAL_NUMBER; 493 v.start = "123.4"; 494 v.len = 5; 495 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 496 497 /* edge case (0) */ 498 v.start = "0"; 499 v.len = 1; 500 i = 456; 501 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 502 CU_ASSERT(i == 0); 503 504 /* invalid value (negative) */ 505 v.start = "-1"; 506 v.len = 2; 507 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 508 509 /* edge case (maximum) */ 510 v.start = "65535"; 511 v.len = 5; 512 i = 0; 513 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 514 CU_ASSERT(i == 65535); 515 516 /* invalid value (overflow) */ 517 v.start = "65536"; 518 v.len = 5; 519 i = 0; 520 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 521 522 /* valid exponent */ 523 v.start = "66E2"; 524 v.len = 4; 525 i = 0; 526 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 527 CU_ASSERT(i == 6600); 528 529 /* invalid exponent (overflow) */ 530 v.start = "66E3"; 531 v.len = 4; 532 i = 0; 533 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 534 535 /* invalid exponent (decimal) */ 536 v.start = "65.535E2"; 537 v.len = 7; 538 i = 0; 539 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 540 541 /* valid exponent with decimal */ 542 v.start = "65.53E2"; 543 v.len = 7; 544 i = 0; 545 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 546 CU_ASSERT(i == 6553); 547 548 /* invalid negative exponent */ 549 v.start = "40e-2"; 550 v.len = 5; 551 i = 0; 552 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 553 554 /* invalid negative exponent */ 555 v.start = "-40e-1"; 556 v.len = 6; 557 i = 0; 558 CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0); 559 560 /* valid negative exponent */ 561 v.start = "40e-1"; 562 v.len = 5; 563 i = 0; 564 CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0); 565 CU_ASSERT(i == 4); 566 } 567 568 static void 569 test_decode_uint32(void) 570 { 571 struct spdk_json_val v; 572 uint32_t i; 573 574 /* incorrect type */ 575 v.type = SPDK_JSON_VAL_STRING; 576 v.start = "String"; 577 v.len = 6; 578 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 579 580 /* invalid value (float) */ 581 v.type = SPDK_JSON_VAL_NUMBER; 582 v.start = "123.45"; 583 v.len = 6; 584 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 585 586 /* edge case (0) */ 587 v.start = "0"; 588 v.len = 1; 589 i = 456; 590 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 591 CU_ASSERT(i == 0); 592 593 /* invalid value (negative) */ 594 v.start = "-1"; 595 v.len = 2; 596 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 597 598 /* edge case (maximum) */ 599 v.start = "4294967295"; 600 v.len = 10; 601 i = 0; 602 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 603 CU_ASSERT(i == 4294967295); 604 605 /* invalid value (overflow) */ 606 v.start = "4294967296"; 607 v.len = 10; 608 i = 0; 609 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 610 611 /* valid exponent */ 612 v.start = "42E2"; 613 v.len = 4; 614 i = 0; 615 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 616 CU_ASSERT(i == 4200); 617 618 /* invalid exponent (overflow) */ 619 v.start = "42e32"; 620 v.len = 5; 621 i = 0; 622 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 623 624 /* invalid exponent (decimal) */ 625 v.start = "42.323E2"; 626 v.len = 8; 627 i = 0; 628 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 629 630 /* valid exponent with decimal */ 631 v.start = "42.32E2"; 632 v.len = 7; 633 i = 0; 634 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 635 CU_ASSERT(i == 4232); 636 637 /* invalid negative exponent */ 638 v.start = "400e-4"; 639 v.len = 6; 640 i = 0; 641 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 642 643 /* invalid negative exponent */ 644 v.start = "-400e-2"; 645 v.len = 7; 646 i = 0; 647 CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0); 648 649 /* valid negative exponent */ 650 v.start = "400e-2"; 651 v.len = 6; 652 i = 0; 653 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 654 CU_ASSERT(i == 4); 655 656 /* valid negative exponent */ 657 v.start = "10e-1"; 658 v.len = 5; 659 i = 0; 660 CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0); 661 CU_ASSERT(i == 1); 662 } 663 664 static void 665 test_decode_uint64(void) 666 { 667 struct spdk_json_val v; 668 uint64_t i; 669 670 /* incorrect type */ 671 v.type = SPDK_JSON_VAL_STRING; 672 v.start = "String"; 673 v.len = 6; 674 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 675 676 /* invalid value (float) */ 677 v.type = SPDK_JSON_VAL_NUMBER; 678 v.start = "123.45"; 679 v.len = 6; 680 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 681 682 /* edge case (0) */ 683 v.start = "0"; 684 v.len = 1; 685 i = 456; 686 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 687 CU_ASSERT(i == 0); 688 689 /* invalid value (negative) */ 690 v.start = "-1"; 691 v.len = 2; 692 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 693 694 /* edge case (maximum) */ 695 v.start = "18446744073709551615"; 696 v.len = 20; 697 i = 0; 698 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 699 CU_ASSERT(i == 18446744073709551615U); 700 701 /* invalid value (overflow) */ 702 v.start = "18446744073709551616"; 703 v.len = 20; 704 i = 0; 705 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 706 707 /* valid exponent */ 708 v.start = "42E2"; 709 v.len = 4; 710 i = 0; 711 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 712 CU_ASSERT(i == 4200); 713 714 /* invalid exponent (overflow) */ 715 v.start = "42e64"; 716 v.len = 5; 717 i = 0; 718 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 719 720 /* invalid exponent (decimal) */ 721 v.start = "42.323E2"; 722 v.len = 8; 723 i = 0; 724 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 725 726 /* valid exponent with decimal */ 727 v.start = "42.32E2"; 728 v.len = 7; 729 i = 0; 730 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 731 CU_ASSERT(i == 4232); 732 733 /* invalid negative exponent */ 734 v.start = "400e-4"; 735 v.len = 6; 736 i = 0; 737 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 738 739 /* invalid negative exponent */ 740 v.start = "-400e-2"; 741 v.len = 7; 742 i = 0; 743 CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0); 744 745 /* valid negative exponent */ 746 v.start = "400e-2"; 747 v.len = 6; 748 i = 0; 749 CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0); 750 CU_ASSERT(i == 4); 751 } 752 753 static void 754 test_decode_string(void) 755 { 756 struct spdk_json_val v; 757 char *value = NULL; 758 759 /* Passing Test: Standard */ 760 v.type = SPDK_JSON_VAL_STRING; 761 v.start = "HELLO"; 762 v.len = 5; 763 CU_ASSERT(spdk_json_decode_string(&v, &value) == 0); 764 SPDK_CU_ASSERT_FATAL(value != NULL); 765 CU_ASSERT(memcmp(value, v.start, 6) == 0); 766 767 /* Edge Test: Empty String */ 768 v.start = ""; 769 v.len = 0; 770 CU_ASSERT(spdk_json_decode_string(&v, &value) == 0); 771 SPDK_CU_ASSERT_FATAL(value != NULL); 772 CU_ASSERT(memcmp(value, v.start, 1) == 0); 773 774 /* 775 * Failing Test: Null Terminator In String 776 * It is valid for a json string to contain \u0000 and the parser will accept it. 777 * However, a null terminated C string cannot contain '\0' and should be rejected 778 * if that character is found before the end of the string. 779 */ 780 v.start = "HELO"; 781 v.len = 5; 782 CU_ASSERT(spdk_json_decode_string(&v, &value) != 0); 783 784 /* Failing Test: Wrong Type */ 785 v.start = "45673"; 786 v.type = SPDK_JSON_VAL_NUMBER; 787 CU_ASSERT(spdk_json_decode_string(&v, &value) != 0); 788 789 /* Passing Test: Special Characters */ 790 v.type = SPDK_JSON_VAL_STRING; 791 v.start = "HE\bLL\tO\\WORLD"; 792 v.len = 13; 793 CU_ASSERT(spdk_json_decode_string(&v, &value) == 0); 794 SPDK_CU_ASSERT_FATAL(value != NULL); 795 CU_ASSERT(memcmp(value, v.start, 14) == 0); 796 797 free(value); 798 } 799 800 char ut_json_text[] = 801 "{" 802 " \"string\": \"Some string data\"," 803 " \"object\": { " 804 " \"another_string\": \"Yet another string data\"," 805 " \"array name with space\": [1, [], {} ]" 806 " }," 807 " \"array\": [ \"Text\", 2, {} ]" 808 "}" 809 ; 810 811 static void 812 test_find(void) 813 { 814 struct spdk_json_val *values, *key, *val, *key2, *val2; 815 ssize_t values_cnt; 816 ssize_t rc; 817 818 values_cnt = spdk_json_parse(ut_json_text, strlen(ut_json_text), NULL, 0, NULL, 0); 819 SPDK_CU_ASSERT_FATAL(values_cnt > 0); 820 821 values = calloc(values_cnt, sizeof(struct spdk_json_val)); 822 SPDK_CU_ASSERT_FATAL(values != NULL); 823 824 rc = spdk_json_parse(ut_json_text, strlen(ut_json_text), values, values_cnt, NULL, 0); 825 SPDK_CU_ASSERT_FATAL(values_cnt == rc); 826 827 key = val = NULL; 828 rc = spdk_json_find(values, "string", &key, &val, SPDK_JSON_VAL_STRING); 829 CU_ASSERT(rc == 0); 830 831 CU_ASSERT(key != NULL && spdk_json_strequal(key, "string") == true); 832 CU_ASSERT(val != NULL && spdk_json_strequal(val, "Some string data") == true); 833 834 key = val = NULL; 835 rc = spdk_json_find(values, "object", &key, &val, SPDK_JSON_VAL_OBJECT_BEGIN); 836 CU_ASSERT(rc == 0); 837 838 CU_ASSERT(key != NULL && spdk_json_strequal(key, "object") == true); 839 840 /* Find key in "object" by passing SPDK_JSON_VAL_ANY to match any type */ 841 key2 = val2 = NULL; 842 rc = spdk_json_find(val, "array name with space", &key2, &val2, SPDK_JSON_VAL_ANY); 843 CU_ASSERT(rc == 0); 844 CU_ASSERT(key2 != NULL && spdk_json_strequal(key2, "array name with space") == true); 845 CU_ASSERT(val2 != NULL && val2->type == SPDK_JSON_VAL_ARRAY_BEGIN); 846 847 /* Find the "array" key in "object" by passing SPDK_JSON_VAL_ARRAY_BEGIN to match only array */ 848 key2 = val2 = NULL; 849 rc = spdk_json_find(val, "array name with space", &key2, &val2, SPDK_JSON_VAL_ARRAY_BEGIN); 850 CU_ASSERT(rc == 0); 851 CU_ASSERT(key2 != NULL && spdk_json_strequal(key2, "array name with space") == true); 852 CU_ASSERT(val2 != NULL && val2->type == SPDK_JSON_VAL_ARRAY_BEGIN); 853 854 /* Negative test - key doesn't exist */ 855 key2 = val2 = NULL; 856 rc = spdk_json_find(val, "this_key_does_not_exist", &key2, &val2, SPDK_JSON_VAL_ANY); 857 CU_ASSERT(rc == -ENOENT); 858 859 /* Negative test - key type doesn't match */ 860 key2 = val2 = NULL; 861 rc = spdk_json_find(val, "another_string", &key2, &val2, SPDK_JSON_VAL_ARRAY_BEGIN); 862 CU_ASSERT(rc == -EDOM); 863 864 free(values); 865 } 866 867 static void 868 test_iterating(void) 869 { 870 struct spdk_json_val *values; 871 struct spdk_json_val *string_key; 872 struct spdk_json_val *object_key, *object_val; 873 struct spdk_json_val *array_key, *array_val; 874 struct spdk_json_val *another_string_key; 875 struct spdk_json_val *array_name_with_space_key, *array_name_with_space_val; 876 struct spdk_json_val *it; 877 ssize_t values_cnt; 878 ssize_t rc; 879 880 values_cnt = spdk_json_parse(ut_json_text, strlen(ut_json_text), NULL, 0, NULL, 0); 881 SPDK_CU_ASSERT_FATAL(values_cnt > 0); 882 883 values = calloc(values_cnt, sizeof(struct spdk_json_val)); 884 SPDK_CU_ASSERT_FATAL(values != NULL); 885 886 rc = spdk_json_parse(ut_json_text, strlen(ut_json_text), values, values_cnt, NULL, 0); 887 SPDK_CU_ASSERT_FATAL(values_cnt == rc); 888 889 /* Iterate over object keys. JSON spec doesn't guarantee order of keys in object but 890 * SPDK implementation implicitly does. 891 */ 892 string_key = spdk_json_object_first(values); 893 CU_ASSERT(spdk_json_strequal(string_key, "string") == true); 894 895 object_key = spdk_json_next(string_key); 896 object_val = json_value(object_key); 897 CU_ASSERT(spdk_json_strequal(object_key, "object") == true); 898 899 array_key = spdk_json_next(object_key); 900 array_val = json_value(array_key); 901 CU_ASSERT(spdk_json_strequal(array_key, "array") == true); 902 903 /* NULL '}' */ 904 CU_ASSERT(spdk_json_next(array_key) == NULL); 905 906 /* Iterate over subobjects */ 907 another_string_key = spdk_json_object_first(object_val); 908 CU_ASSERT(spdk_json_strequal(another_string_key, "another_string") == true); 909 910 array_name_with_space_key = spdk_json_next(another_string_key); 911 array_name_with_space_val = json_value(array_name_with_space_key); 912 CU_ASSERT(spdk_json_strequal(array_name_with_space_key, "array name with space") == true); 913 914 CU_ASSERT(spdk_json_next(array_name_with_space_key) == NULL); 915 916 /* Iterate over array in subobject */ 917 it = spdk_json_array_first(array_name_with_space_val); 918 SPDK_CU_ASSERT_FATAL(it != NULL); 919 CU_ASSERT(it->type == SPDK_JSON_VAL_NUMBER); 920 921 it = spdk_json_next(it); 922 SPDK_CU_ASSERT_FATAL(it != NULL); 923 CU_ASSERT(it->type == SPDK_JSON_VAL_ARRAY_BEGIN); 924 925 it = spdk_json_next(it); 926 SPDK_CU_ASSERT_FATAL(it != NULL); 927 CU_ASSERT(it->type == SPDK_JSON_VAL_OBJECT_BEGIN); 928 929 it = spdk_json_next(it); 930 CU_ASSERT(it == NULL); 931 932 /* Iterate over array in root object */ 933 it = spdk_json_array_first(array_val); 934 SPDK_CU_ASSERT_FATAL(it != NULL); 935 CU_ASSERT(it->type == SPDK_JSON_VAL_STRING); 936 937 it = spdk_json_next(it); 938 SPDK_CU_ASSERT_FATAL(it != NULL); 939 CU_ASSERT(it->type == SPDK_JSON_VAL_NUMBER); 940 941 it = spdk_json_next(it); 942 SPDK_CU_ASSERT_FATAL(it != NULL); 943 CU_ASSERT(it->type == SPDK_JSON_VAL_OBJECT_BEGIN); 944 945 /* Array end */ 946 it = spdk_json_next(it); 947 CU_ASSERT(it == NULL); 948 949 free(values); 950 } 951 952 int main(int argc, char **argv) 953 { 954 CU_pSuite suite = NULL; 955 unsigned int num_failures; 956 957 CU_set_error_action(CUEA_ABORT); 958 CU_initialize_registry(); 959 960 suite = CU_add_suite("json", NULL, NULL); 961 962 CU_ADD_TEST(suite, test_strequal); 963 CU_ADD_TEST(suite, test_num_to_uint16); 964 CU_ADD_TEST(suite, test_num_to_int32); 965 CU_ADD_TEST(suite, test_num_to_uint64); 966 CU_ADD_TEST(suite, test_decode_object); 967 CU_ADD_TEST(suite, test_decode_array); 968 CU_ADD_TEST(suite, test_decode_bool); 969 CU_ADD_TEST(suite, test_decode_uint16); 970 CU_ADD_TEST(suite, test_decode_int32); 971 CU_ADD_TEST(suite, test_decode_uint32); 972 CU_ADD_TEST(suite, test_decode_uint64); 973 CU_ADD_TEST(suite, test_decode_string); 974 CU_ADD_TEST(suite, test_find); 975 CU_ADD_TEST(suite, test_iterating); 976 CU_ADD_TEST(suite, test_free_object); 977 978 CU_basic_set_mode(CU_BRM_VERBOSE); 979 980 CU_basic_run_tests(); 981 982 num_failures = CU_get_number_of_failures(); 983 CU_cleanup_registry(); 984 985 return num_failures; 986 } 987