xref: /spdk/test/unit/lib/json/json_util.c/json_util_ut.c (revision 927f1fd57bd004df581518466ec4c1b8083e5d23)
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