xref: /spdk/test/unit/lib/json/json_util.c/json_util_ut.c (revision 8a0a98d35e21f282088edf28b9e8da66ec390e3a)
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 #define NUM_SETUP(x) \
41 	snprintf(buf, sizeof(buf), "%s", x); \
42 	v.type = SPDK_JSON_VAL_NUMBER; \
43 	v.start = buf; \
44 	v.len = sizeof(x) - 1
45 
46 #define NUM_UINT16_PASS(s, i) \
47 	NUM_SETUP(s); \
48 	CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) == 0); \
49 	CU_ASSERT(u16 == i)
50 
51 #define NUM_UINT16_FAIL(s) \
52 	NUM_SETUP(s); \
53 	CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) != 0)
54 
55 #define NUM_INT32_PASS(s, i) \
56 	NUM_SETUP(s); \
57 	CU_ASSERT(spdk_json_number_to_int32(&v, &i32) == 0); \
58 	CU_ASSERT(i32 == i)
59 
60 #define NUM_INT32_FAIL(s) \
61 	NUM_SETUP(s); \
62 	CU_ASSERT(spdk_json_number_to_int32(&v, &i32) != 0)
63 
64 #define NUM_UINT64_PASS(s, i) \
65 	NUM_SETUP(s); \
66 	CU_ASSERT(spdk_json_number_to_uint64(&v, &u64) == 0); \
67 	CU_ASSERT(u64 == i)
68 
69 #define NUM_UINT64_FAIL(s) \
70 	NUM_SETUP(s); \
71 	CU_ASSERT(spdk_json_number_to_uint64(&v, &u64) != 0)
72 
73 static void
74 test_strequal(void)
75 {
76 	struct spdk_json_val v;
77 
78 	v.type = SPDK_JSON_VAL_STRING;
79 	v.start = "test";
80 	v.len = sizeof("test") - 1;
81 	CU_ASSERT(spdk_json_strequal(&v, "test") == true);
82 	CU_ASSERT(spdk_json_strequal(&v, "TEST") == false);
83 	CU_ASSERT(spdk_json_strequal(&v, "hello") == false);
84 	CU_ASSERT(spdk_json_strequal(&v, "t") == false);
85 
86 	v.type = SPDK_JSON_VAL_NAME;
87 	CU_ASSERT(spdk_json_strequal(&v, "test") == true);
88 
89 	v.type = SPDK_JSON_VAL_NUMBER;
90 	CU_ASSERT(spdk_json_strequal(&v, "test") == false);
91 
92 	v.type = SPDK_JSON_VAL_STRING;
93 	v.start = "test\0hello";
94 	v.len = sizeof("test\0hello") - 1;
95 	CU_ASSERT(spdk_json_strequal(&v, "test") == false);
96 }
97 
98 static void
99 test_num_to_uint16(void)
100 {
101 	struct spdk_json_val v;
102 	char buf[100];
103 	uint16_t u16 = 0;
104 
105 	NUM_SETUP("1234");
106 	CU_ASSERT(spdk_json_number_to_uint16(&v, &u16) == 0);
107 	CU_ASSERT(u16 == 1234);
108 
109 	NUM_UINT16_PASS("0", 0);
110 	NUM_UINT16_PASS("1234", 1234);
111 	NUM_UINT16_PASS("1234.00000", 1234);
112 	NUM_UINT16_PASS("1.2e1", 12);
113 	NUM_UINT16_PASS("12340e-1", 1234);
114 
115 	NUM_UINT16_FAIL("1.2");
116 	NUM_UINT16_FAIL("-1234");
117 	NUM_UINT16_FAIL("1.2E0");
118 	NUM_UINT16_FAIL("1.234e1");
119 	NUM_UINT16_FAIL("12341e-1");
120 }
121 
122 static void
123 test_num_to_int32(void)
124 {
125 	struct spdk_json_val v;
126 	char buf[100];
127 	int32_t i32 = 0;
128 
129 	NUM_SETUP("1234");
130 	CU_ASSERT(spdk_json_number_to_int32(&v, &i32) == 0);
131 	CU_ASSERT(i32 == 1234);
132 
133 
134 	NUM_INT32_PASS("0", 0);
135 	NUM_INT32_PASS("1234", 1234);
136 	NUM_INT32_PASS("-1234", -1234);
137 	NUM_INT32_PASS("1234.00000", 1234);
138 	NUM_INT32_PASS("1.2e1", 12);
139 	NUM_INT32_PASS("12340e-1", 1234);
140 	NUM_INT32_PASS("-0", 0);
141 
142 	NUM_INT32_FAIL("1.2");
143 	NUM_INT32_FAIL("1.2E0");
144 	NUM_INT32_FAIL("1.234e1");
145 	NUM_INT32_FAIL("12341e-1");
146 }
147 
148 static void
149 test_num_to_uint64(void)
150 {
151 	struct spdk_json_val v;
152 	char buf[100];
153 	uint64_t u64 = 0;
154 
155 	NUM_SETUP("1234");
156 	CU_ASSERT(spdk_json_number_to_uint64(&v, &u64) == 0);
157 	CU_ASSERT(u64 == 1234);
158 
159 
160 	NUM_UINT64_PASS("0", 0);
161 	NUM_UINT64_PASS("1234", 1234);
162 	NUM_UINT64_PASS("1234.00000", 1234);
163 	NUM_UINT64_PASS("1.2e1", 12);
164 	NUM_UINT64_PASS("12340e-1", 1234);
165 	NUM_UINT64_PASS("123456780e-1", 12345678);
166 
167 	NUM_UINT64_FAIL("1.2");
168 	NUM_UINT64_FAIL("-1234");
169 	NUM_UINT64_FAIL("1.2E0");
170 	NUM_UINT64_FAIL("1.234e1");
171 	NUM_UINT64_FAIL("12341e-1");
172 	NUM_UINT64_FAIL("123456781e-1");
173 }
174 
175 static void
176 test_decode_object(void)
177 {
178 	struct my_object {
179 		char *my_name;
180 		uint32_t my_int;
181 		bool my_bool;
182 	};
183 	struct spdk_json_val object[] = {
184 		{"", 6, SPDK_JSON_VAL_OBJECT_BEGIN},
185 		{"first", 5, SPDK_JSON_VAL_NAME},
186 		{"HELLO", 5, SPDK_JSON_VAL_STRING},
187 		{"second", 6, SPDK_JSON_VAL_NAME},
188 		{"234", 3, SPDK_JSON_VAL_NUMBER},
189 		{"third", 5, SPDK_JSON_VAL_NAME},
190 		{"", 1, SPDK_JSON_VAL_TRUE},
191 		{"", 0, SPDK_JSON_VAL_OBJECT_END},
192 	};
193 
194 	struct spdk_json_object_decoder decoders[] = {
195 		{"first", offsetof(struct my_object, my_name), spdk_json_decode_string, false},
196 		{"second", offsetof(struct my_object, my_int), spdk_json_decode_uint32, false},
197 		{"third", offsetof(struct my_object, my_bool), spdk_json_decode_bool, false},
198 		{"fourth", offsetof(struct my_object, my_bool), spdk_json_decode_bool, true},
199 	};
200 	struct my_object output = {
201 		.my_name = NULL,
202 		.my_int = 0,
203 		.my_bool = false,
204 	};
205 	uint32_t answer = 234;
206 	char *answer_str = "HELLO";
207 	bool answer_bool = true;
208 
209 	/* Passing Test: object containing simple types */
210 	CU_ASSERT(spdk_json_decode_object(object, decoders, 4, &output) == 0);
211 	SPDK_CU_ASSERT_FATAL(output.my_name != NULL);
212 	CU_ASSERT(memcmp(output.my_name, answer_str, 6) == 0);
213 	CU_ASSERT(output.my_int == answer);
214 	CU_ASSERT(output.my_bool == answer_bool);
215 
216 	/* Failing Test: member with no matching decoder */
217 	/* i.e. I remove the matching decoder from the boolean argument */
218 	CU_ASSERT(spdk_json_decode_object(object, decoders, 2, &output) != 0);
219 
220 	/* Failing Test: non-optional decoder with no corresponding member */
221 
222 	decoders[3].optional = false;
223 	CU_ASSERT(spdk_json_decode_object(object, decoders, 4, &output) != 0);
224 
225 	/* return to base state */
226 	decoders[3].optional = true;
227 
228 	/* Failing Test: duplicated names for json values */
229 	object[3].start = "first";
230 	object[3].len = 5;
231 	CU_ASSERT(spdk_json_decode_object(object, decoders, 3, &output) != 0);
232 
233 	/* return to base state */
234 	object[3].start = "second";
235 	object[3].len = 6;
236 
237 	/* Failing Test: invalid value for decoder */
238 	object[2].start = "HELO";
239 	CU_ASSERT(spdk_json_decode_object(object, decoders, 3, &output) != 0);
240 
241 	/* return to base state */
242 	object[2].start = "HELLO";
243 
244 	/* Failing Test: not an object */
245 	object[0].type = SPDK_JSON_VAL_ARRAY_BEGIN;
246 	CU_ASSERT(spdk_json_decode_object(object, decoders, 3, &output) != 0);
247 
248 	free(output.my_name);
249 }
250 
251 static void
252 test_decode_array(void)
253 {
254 	struct spdk_json_val values[4];
255 	uint32_t my_int[2] = {0, 0};
256 	char *my_string[2] = {NULL, NULL};
257 	size_t out_size;
258 
259 	/* passing integer test */
260 	values[0].type = SPDK_JSON_VAL_ARRAY_BEGIN;
261 	values[0].len = 2;
262 	values[1].type = SPDK_JSON_VAL_NUMBER;
263 	values[1].len = 4;
264 	values[1].start = "1234";
265 	values[2].type = SPDK_JSON_VAL_NUMBER;
266 	values[2].len = 4;
267 	values[2].start = "5678";
268 	values[3].type = SPDK_JSON_VAL_ARRAY_END;
269 	CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size,
270 					 sizeof(uint32_t)) == 0);
271 	CU_ASSERT(my_int[0] == 1234);
272 	CU_ASSERT(my_int[1] == 5678);
273 	CU_ASSERT(out_size == 2);
274 
275 	/* array length exceeds max */
276 	values[0].len = 3;
277 	CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size,
278 					 sizeof(uint32_t)) != 0);
279 
280 	/* mixed types */
281 	values[0].len = 2;
282 	values[2].type = SPDK_JSON_VAL_STRING;
283 	values[2].len = 5;
284 	values[2].start = "HELLO";
285 	CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size,
286 					 sizeof(uint32_t)) != 0);
287 
288 	/* no array start */
289 	values[0].type = SPDK_JSON_VAL_NUMBER;
290 	values[2].type = SPDK_JSON_VAL_NUMBER;
291 	values[2].len = 4;
292 	values[2].start = "5678";
293 	CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size,
294 					 sizeof(uint32_t)) != 0);
295 
296 	/* mismatched array type and parser */
297 	values[0].type = SPDK_JSON_VAL_ARRAY_BEGIN;
298 	values[1].type = SPDK_JSON_VAL_STRING;
299 	values[1].len = 5;
300 	values[1].start = "HELLO";
301 	values[2].type = SPDK_JSON_VAL_STRING;
302 	values[2].len = 5;
303 	values[2].start = "WORLD";
304 	CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_uint32, my_int, 2, &out_size,
305 					 sizeof(uint32_t)) != 0);
306 
307 	/* passing String example */
308 	CU_ASSERT(spdk_json_decode_array(values, spdk_json_decode_string, my_string, 2, &out_size,
309 					 sizeof(char *)) == 0);
310 	SPDK_CU_ASSERT_FATAL(my_string[0] != NULL);
311 	SPDK_CU_ASSERT_FATAL(my_string[1] != NULL);
312 	CU_ASSERT(memcmp(my_string[0], "HELLO", 6) == 0);
313 	CU_ASSERT(memcmp(my_string[1], "WORLD", 6) == 0);
314 	CU_ASSERT(out_size == 2);
315 
316 	free(my_string[0]);
317 	free(my_string[1]);
318 }
319 
320 static void
321 test_decode_bool(void)
322 {
323 	struct spdk_json_val v;
324 	bool b;
325 
326 	/* valid bool (true) */
327 	v.type = SPDK_JSON_VAL_TRUE;
328 	b = false;
329 	CU_ASSERT(spdk_json_decode_bool(&v, &b) == 0);
330 	CU_ASSERT(b == true);
331 
332 	/* valid bool (false) */
333 	v.type = SPDK_JSON_VAL_FALSE;
334 	b = true;
335 	CU_ASSERT(spdk_json_decode_bool(&v, &b) == 0);
336 	CU_ASSERT(b == false);
337 
338 	/* incorrect type */
339 	v.type = SPDK_JSON_VAL_NULL;
340 	CU_ASSERT(spdk_json_decode_bool(&v, &b) != 0);
341 }
342 
343 static void
344 test_decode_int32(void)
345 {
346 	struct spdk_json_val v;
347 	int32_t i;
348 
349 	/* correct type and valid value */
350 	v.type = SPDK_JSON_VAL_NUMBER;
351 	v.start = "33";
352 	v.len = 2;
353 	i = 0;
354 	CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0);
355 	CU_ASSERT(i == 33)
356 
357 	/* correct type and invalid value (float) */
358 	v.start = "32.45";
359 	v.len = 5;
360 	i = 0;
361 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
362 
363 	/* incorrect type */
364 	v.type = SPDK_JSON_VAL_STRING;
365 	v.start = "String";
366 	v.len = 6;
367 	i = 0;
368 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
369 
370 	/* incorrect type */
371 	v.type = SPDK_JSON_VAL_TRUE;
372 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
373 
374 	/* edge case (integer max) */
375 	v.type = SPDK_JSON_VAL_NUMBER;
376 	v.start = "2147483647";
377 	v.len = 10;
378 	i = 0;
379 	CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0);
380 	CU_ASSERT(i == 2147483647);
381 
382 	/* invalid value (overflow) */
383 	v.start = "2147483648";
384 	i = 0;
385 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
386 
387 	/* edge case (integer min) */
388 	v.type = SPDK_JSON_VAL_NUMBER;
389 	v.start = "-2147483648";
390 	v.len = 11;
391 	i = 0;
392 	CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0);
393 	CU_ASSERT(i == -2147483648);
394 
395 	/* invalid value (overflow) */
396 	v.start = "-2147483649";
397 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
398 
399 	/* valid exponent */
400 	v.start = "4e3";
401 	v.len = 3;
402 	i = 0;
403 	CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0);
404 	CU_ASSERT(i == 4000);
405 
406 	/* invalid negative exponent */
407 	v.start = "-400e-4";
408 	v.len = 7;
409 	i = 0;
410 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
411 
412 	/* invalid negative exponent */
413 	v.start = "400e-4";
414 	v.len = 6;
415 	i = 0;
416 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
417 
418 	/* valid negative exponent */
419 	v.start = "-400e-2";
420 	v.len = 7;
421 	i = 0;
422 	CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0);
423 	CU_ASSERT(i == -4)
424 
425 	/* invalid exponent (overflow) */
426 	v.start = "-2e32";
427 	v.len = 5;
428 	i = 0;
429 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
430 
431 	/* valid exponent with decimal */
432 	v.start = "2.13e2";
433 	v.len = 6;
434 	i = 0;
435 	CU_ASSERT(spdk_json_decode_int32(&v, &i) == 0);
436 	CU_ASSERT(i == 213)
437 
438 	/* invalid exponent with decimal */
439 	v.start = "2.134e2";
440 	v.len = 7;
441 	i = 0;
442 	CU_ASSERT(spdk_json_decode_int32(&v, &i) != 0);
443 }
444 
445 static void
446 test_decode_uint16(void)
447 {
448 	struct spdk_json_val v;
449 	uint32_t i;
450 
451 	/* incorrect type */
452 	v.type = SPDK_JSON_VAL_STRING;
453 	v.start = "Strin";
454 	v.len = 5;
455 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
456 
457 	/* invalid value (float) */
458 	v.type = SPDK_JSON_VAL_NUMBER;
459 	v.start = "123.4";
460 	v.len = 5;
461 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
462 
463 	/* edge case (0) */
464 	v.start = "0";
465 	v.len = 1;
466 	i = 456;
467 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0);
468 	CU_ASSERT(i == 0);
469 
470 	/* invalid value (negative) */
471 	v.start = "-1";
472 	v.len = 2;
473 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
474 
475 	/* edge case (maximum) */
476 	v.start = "65535";
477 	v.len = 5;
478 	i = 0;
479 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0);
480 	CU_ASSERT(i == 65535);
481 
482 	/* invalid value (overflow) */
483 	v.start = "65536";
484 	v.len = 5;
485 	i = 0;
486 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
487 
488 	/* valid exponent */
489 	v.start = "66E2";
490 	v.len = 4;
491 	i = 0;
492 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0);
493 	CU_ASSERT(i == 6600);
494 
495 	/* invalid exponent (overflow) */
496 	v.start = "66E3";
497 	v.len = 4;
498 	i = 0;
499 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
500 
501 	/* invalid exponent (decimal) */
502 	v.start = "65.535E2";
503 	v.len = 7;
504 	i = 0;
505 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
506 
507 	/* valid exponent with decimal */
508 	v.start = "65.53E2";
509 	v.len = 7;
510 	i = 0;
511 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0);
512 	CU_ASSERT(i == 6553);
513 
514 	/* invalid negative exponent */
515 	v.start = "40e-2";
516 	v.len = 5;
517 	i = 0;
518 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
519 
520 	/* invalid negative exponent */
521 	v.start = "-40e-1";
522 	v.len = 6;
523 	i = 0;
524 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) != 0);
525 
526 	/* valid negative exponent */
527 	v.start = "40e-1";
528 	v.len = 5;
529 	i = 0;
530 	CU_ASSERT(spdk_json_decode_uint16(&v, &i) == 0);
531 	CU_ASSERT(i == 4);
532 }
533 
534 static void
535 test_decode_uint32(void)
536 {
537 	struct spdk_json_val v;
538 	uint32_t i;
539 
540 	/* incorrect type */
541 	v.type = SPDK_JSON_VAL_STRING;
542 	v.start = "String";
543 	v.len = 6;
544 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
545 
546 	/* invalid value (float) */
547 	v.type = SPDK_JSON_VAL_NUMBER;
548 	v.start = "123.45";
549 	v.len = 6;
550 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
551 
552 	/* edge case (0) */
553 	v.start = "0";
554 	v.len = 1;
555 	i = 456;
556 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0);
557 	CU_ASSERT(i == 0);
558 
559 	/* invalid value (negative) */
560 	v.start = "-1";
561 	v.len = 2;
562 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
563 
564 	/* edge case (maximum) */
565 	v.start = "4294967295";
566 	v.len = 10;
567 	i = 0;
568 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0);
569 	CU_ASSERT(i == 4294967295);
570 
571 	/* invalid value (overflow) */
572 	v.start = "4294967296";
573 	v.len = 10;
574 	i = 0;
575 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
576 
577 	/* valid exponent */
578 	v.start = "42E2";
579 	v.len = 4;
580 	i = 0;
581 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0);
582 	CU_ASSERT(i == 4200);
583 
584 	/* invalid exponent (overflow) */
585 	v.start = "42e32";
586 	v.len = 5;
587 	i = 0;
588 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
589 
590 	/* invalid exponent (decimal) */
591 	v.start = "42.323E2";
592 	v.len = 8;
593 	i = 0;
594 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
595 
596 	/* valid exponent with decimal */
597 	v.start = "42.32E2";
598 	v.len = 7;
599 	i = 0;
600 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0);
601 	CU_ASSERT(i == 4232);
602 
603 	/* invalid negative exponent */
604 	v.start = "400e-4";
605 	v.len = 6;
606 	i = 0;
607 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
608 
609 	/* invalid negative exponent */
610 	v.start = "-400e-2";
611 	v.len = 7;
612 	i = 0;
613 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) != 0);
614 
615 	/* valid negative exponent */
616 	v.start = "400e-2";
617 	v.len = 6;
618 	i = 0;
619 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0);
620 	CU_ASSERT(i == 4);
621 
622 	/* valid negative exponent */
623 	v.start = "10e-1";
624 	v.len = 5;
625 	i = 0;
626 	CU_ASSERT(spdk_json_decode_uint32(&v, &i) == 0);
627 	CU_ASSERT(i == 1)
628 }
629 
630 static void
631 test_decode_uint64(void)
632 {
633 	struct spdk_json_val v;
634 	uint64_t i;
635 
636 	/* incorrect type */
637 	v.type = SPDK_JSON_VAL_STRING;
638 	v.start = "String";
639 	v.len = 6;
640 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
641 
642 	/* invalid value (float) */
643 	v.type = SPDK_JSON_VAL_NUMBER;
644 	v.start = "123.45";
645 	v.len = 6;
646 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
647 
648 	/* edge case (0) */
649 	v.start = "0";
650 	v.len = 1;
651 	i = 456;
652 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0);
653 	CU_ASSERT(i == 0);
654 
655 	/* invalid value (negative) */
656 	v.start = "-1";
657 	v.len = 2;
658 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
659 
660 	/* edge case (maximum) */
661 	v.start = "18446744073709551615";
662 	v.len = 20;
663 	i = 0;
664 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0);
665 	CU_ASSERT(i == 18446744073709551615U);
666 
667 	/* invalid value (overflow) */
668 	v.start = "18446744073709551616";
669 	v.len = 20;
670 	i = 0;
671 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
672 
673 	/* valid exponent */
674 	v.start = "42E2";
675 	v.len = 4;
676 	i = 0;
677 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0);
678 	CU_ASSERT(i == 4200);
679 
680 	/* invalid exponent (overflow) */
681 	v.start = "42e64";
682 	v.len = 5;
683 	i = 0;
684 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
685 
686 	/* invalid exponent (decimal) */
687 	v.start = "42.323E2";
688 	v.len = 8;
689 	i = 0;
690 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
691 
692 	/* valid exponent with decimal */
693 	v.start = "42.32E2";
694 	v.len = 7;
695 	i = 0;
696 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0);
697 	CU_ASSERT(i == 4232);
698 
699 	/* invalid negative exponent */
700 	v.start = "400e-4";
701 	v.len = 6;
702 	i = 0;
703 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
704 
705 	/* invalid negative exponent */
706 	v.start = "-400e-2";
707 	v.len = 7;
708 	i = 0;
709 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) != 0);
710 
711 	/* valid negative exponent */
712 	v.start = "400e-2";
713 	v.len = 6;
714 	i = 0;
715 	CU_ASSERT(spdk_json_decode_uint64(&v, &i) == 0);
716 	CU_ASSERT(i == 4)
717 }
718 
719 static void
720 test_decode_string(void)
721 {
722 	struct spdk_json_val v;
723 	char *value = NULL;
724 
725 	/* Passing Test: Standard */
726 	v.type = SPDK_JSON_VAL_STRING;
727 	v.start = "HELLO";
728 	v.len = 5;
729 	CU_ASSERT(spdk_json_decode_string(&v, &value) == 0);
730 	SPDK_CU_ASSERT_FATAL(value != NULL);
731 	CU_ASSERT(memcmp(value, v.start, 6) == 0);
732 
733 	/* Edge Test: Empty String */
734 	v.start = "";
735 	v.len = 0;
736 	CU_ASSERT(spdk_json_decode_string(&v, &value) == 0);
737 	SPDK_CU_ASSERT_FATAL(value != NULL);
738 	CU_ASSERT(memcmp(value, v.start, 1) == 0);
739 
740 	/*
741 	 * Failing Test: Null Terminator In String
742 	 * It is valid for a json string to contain \u0000 and the parser will accept it.
743 	 * However, a null terminated C string cannot contain '\0' and should be rejected
744 	 * if that character is found before the end of the string.
745 	 */
746 	v.start = "HELO";
747 	v.len = 5;
748 	CU_ASSERT(spdk_json_decode_string(&v, &value) != 0);
749 
750 	/* Failing Test: Wrong Type */
751 	v.start = "45673";
752 	v.type = SPDK_JSON_VAL_NUMBER;
753 	CU_ASSERT(spdk_json_decode_string(&v, &value) != 0);
754 
755 	/* Passing Test: Special Characters */
756 	v.type = SPDK_JSON_VAL_STRING;
757 	v.start = "HE\bLL\tO\\WORLD";
758 	v.len = 13;
759 	CU_ASSERT(spdk_json_decode_string(&v, &value) == 0);
760 	SPDK_CU_ASSERT_FATAL(value != NULL);
761 	CU_ASSERT(memcmp(value, v.start, 14) == 0);
762 
763 	free(value);
764 }
765 
766 int main(int argc, char **argv)
767 {
768 	CU_pSuite	suite = NULL;
769 	unsigned int	num_failures;
770 
771 	if (CU_initialize_registry() != CUE_SUCCESS) {
772 		return CU_get_error();
773 	}
774 
775 	suite = CU_add_suite("json", NULL, NULL);
776 	if (suite == NULL) {
777 		CU_cleanup_registry();
778 		return CU_get_error();
779 	}
780 
781 	if (
782 		CU_add_test(suite, "strequal", test_strequal) == NULL ||
783 		CU_add_test(suite, "num_to_uint16", test_num_to_uint16) == NULL ||
784 		CU_add_test(suite, "num_to_int32", test_num_to_int32) == NULL ||
785 		CU_add_test(suite, "num_to_uint64", test_num_to_uint64) == NULL ||
786 		CU_add_test(suite, "decode_object", test_decode_object) == NULL ||
787 		CU_add_test(suite, "decode_array", test_decode_array) == NULL ||
788 		CU_add_test(suite, "decode_bool", test_decode_bool) == NULL ||
789 		CU_add_test(suite, "decode_uint16", test_decode_uint16) == NULL ||
790 		CU_add_test(suite, "decode_int32", test_decode_int32) == NULL ||
791 		CU_add_test(suite, "decode_uint32", test_decode_uint32) == NULL ||
792 		CU_add_test(suite, "decode_uint64", test_decode_uint64) == NULL ||
793 		CU_add_test(suite, "decode_string", test_decode_string) == NULL) {
794 		CU_cleanup_registry();
795 		return CU_get_error();
796 	}
797 
798 	CU_basic_set_mode(CU_BRM_VERBOSE);
799 
800 	CU_basic_run_tests();
801 
802 	num_failures = CU_get_number_of_failures();
803 	CU_cleanup_registry();
804 
805 	return num_failures;
806 }
807