xref: /spdk/test/unit/lib/json/json_util.c/json_util_ut.c (revision 9889ab2dc80e40dae92dcef361d53dcba722043d)
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 	if (CU_initialize_registry() != CUE_SUCCESS) {
927 		return CU_get_error();
928 	}
929 
930 	suite = CU_add_suite("json", NULL, NULL);
931 	if (suite == NULL) {
932 		CU_cleanup_registry();
933 		return CU_get_error();
934 	}
935 
936 	if (
937 		CU_add_test(suite, "strequal", test_strequal) == NULL ||
938 		CU_add_test(suite, "num_to_uint16", test_num_to_uint16) == NULL ||
939 		CU_add_test(suite, "num_to_int32", test_num_to_int32) == NULL ||
940 		CU_add_test(suite, "num_to_uint64", test_num_to_uint64) == NULL ||
941 		CU_add_test(suite, "decode_object", test_decode_object) == NULL ||
942 		CU_add_test(suite, "decode_array", test_decode_array) == NULL ||
943 		CU_add_test(suite, "decode_bool", test_decode_bool) == NULL ||
944 		CU_add_test(suite, "decode_uint16", test_decode_uint16) == NULL ||
945 		CU_add_test(suite, "decode_int32", test_decode_int32) == NULL ||
946 		CU_add_test(suite, "decode_uint32", test_decode_uint32) == NULL ||
947 		CU_add_test(suite, "decode_uint64", test_decode_uint64) == NULL ||
948 		CU_add_test(suite, "decode_string", test_decode_string) == NULL ||
949 		CU_add_test(suite, "find_object", test_find) == NULL ||
950 		CU_add_test(suite, "iterating", test_iterating) == NULL) {
951 		CU_cleanup_registry();
952 		return CU_get_error();
953 	}
954 
955 	CU_basic_set_mode(CU_BRM_VERBOSE);
956 
957 	CU_basic_run_tests();
958 
959 	num_failures = CU_get_number_of_failures();
960 	CU_cleanup_registry();
961 
962 	return num_failures;
963 }
964