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