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