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