Address JSON thread safety issues.
[asterisk/asterisk.git] / tests / test_json.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file \brief Test JSON API.
21  *
22  * While some of these tests are actually testing our JSON library wrapper, the bulk of
23  * them are exploratory tests to determine what the behavior of the underlying JSON
24  * library is. This also gives us a good indicator if that behavior changes between
25  * Jansson revisions.
26  *
27  * \author\verbatim David M. Lee, II <dlee@digium.com> \endverbatim
28  *
29  * \ingroup tests
30  */
31
32 /*** MODULEINFO
33         <depend>TEST_FRAMEWORK</depend>
34         <support_level>core</support_level>
35  ***/
36
37 #include "asterisk.h"
38
39 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40 #include "asterisk/json.h"
41 #include "asterisk/module.h"
42 #include "asterisk/test.h"
43
44 #define CATEGORY "/main/json/"
45
46 /*!
47  * Number of allocations from JSON library that have not yet been freed.
48  */
49 static size_t alloc_count;
50
51 /*!@{*/
52 /*!
53  * JSON library has its own reference counting, so we'll provide our own allocators to
54  * test that everything gets freed as expected.
55  */
56 static void *json_debug_malloc(size_t size)
57 {
58         void *p = ast_json_malloc(size);
59         if (p) {
60                 ++alloc_count;
61         }
62         return p;
63 }
64
65 static void json_debug_free(void *p)
66 {
67         if (p) {
68                 --alloc_count;
69         }
70         ast_json_free(p);
71 }
72
73 static int json_test_init(struct ast_test_info *info, struct ast_test *test)
74 {
75         ast_json_set_alloc_funcs(json_debug_malloc, json_debug_free);
76         alloc_count = 0;
77         return 0;
78 }
79
80 static int json_test_cleanup(struct ast_test_info *info, struct ast_test *test)
81 {
82         ast_json_reset_alloc_funcs();
83         if (0 != alloc_count) {
84                 ast_test_status_update(test,
85                         "JSON test leaked %zd allocations!\n", alloc_count);
86                 return -1;
87         }
88         return 0;
89 }
90
91 /*!@}*/
92
93 AST_TEST_DEFINE(json_test_false)
94 {
95         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
96
97         switch (cmd) {
98         case TEST_INIT:
99                 info->name = "false";
100                 info->category = CATEGORY;
101                 info->summary = "Testing fundamental JSON false value.";
102                 info->description = "Test JSON abstraction library.";
103                 return AST_TEST_NOT_RUN;
104         case TEST_EXECUTE:
105                 break;
106         }
107
108         uut = ast_json_false();
109         ast_test_validate(test, NULL != uut);
110         ast_test_validate(test, AST_JSON_FALSE == ast_json_typeof(uut));
111         ast_test_validate(test, !ast_json_is_null(uut));
112         ast_test_validate(test, !ast_json_is_true(uut));
113         ast_test_validate(test, ast_json_is_false(uut));
114
115         return AST_TEST_PASS;
116 }
117
118 AST_TEST_DEFINE(json_test_true)
119 {
120         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
121
122         switch (cmd) {
123         case TEST_INIT:
124                 info->name = "true";
125                 info->category = CATEGORY;
126                 info->summary = "Testing JSON true value.";
127                 info->description = "Test JSON abstraction library.";
128                 return AST_TEST_NOT_RUN;
129         case TEST_EXECUTE:
130                 break;
131         }
132
133         uut = ast_json_true();
134         ast_test_validate(test, NULL != uut);
135         ast_test_validate(test, AST_JSON_TRUE == ast_json_typeof(uut));
136         ast_test_validate(test, !ast_json_is_null(uut));
137         ast_test_validate(test, ast_json_is_true(uut));
138         ast_test_validate(test, !ast_json_is_false(uut));
139
140         return AST_TEST_PASS;
141 }
142
143 AST_TEST_DEFINE(json_test_bool0)
144 {
145         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
146
147         switch (cmd) {
148         case TEST_INIT:
149                 info->name = "bool0";
150                 info->category = CATEGORY;
151                 info->summary = "Testing JSON boolean function (false).";
152                 info->description = "Test JSON abstraction library.";
153                 return AST_TEST_NOT_RUN;
154         case TEST_EXECUTE:
155                 break;
156         }
157
158         uut = ast_json_boolean(0);
159         ast_test_validate(test, NULL != uut);
160         ast_test_validate(test, AST_JSON_FALSE == ast_json_typeof(uut));
161         ast_test_validate(test, !ast_json_is_null(uut));
162         ast_test_validate(test, !ast_json_is_true(uut));
163         ast_test_validate(test, ast_json_is_false(uut));
164         ast_test_validate(test, ast_json_equal(uut, ast_json_false()));
165         ast_test_validate(test, !ast_json_equal(uut, ast_json_true()));
166
167         return AST_TEST_PASS;
168 }
169
170 AST_TEST_DEFINE(json_test_bool1)
171 {
172         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
173
174         switch (cmd) {
175         case TEST_INIT:
176                 info->name = "bool1";
177                 info->category = CATEGORY;
178                 info->summary = "Testing JSON boolean function (true).";
179                 info->description = "Test JSON abstraction library.";
180                 return AST_TEST_NOT_RUN;
181         case TEST_EXECUTE:
182                 break;
183         }
184
185         uut = ast_json_boolean(1);
186         ast_test_validate(test, NULL != uut);
187         ast_test_validate(test, AST_JSON_TRUE == ast_json_typeof(uut));
188         ast_test_validate(test, !ast_json_is_null(uut));
189         ast_test_validate(test, ast_json_is_true(uut));
190         ast_test_validate(test, !ast_json_is_false(uut));
191         ast_test_validate(test, !ast_json_equal(uut, ast_json_false()));
192         ast_test_validate(test, ast_json_equal(uut, ast_json_true()));
193
194         return AST_TEST_PASS;
195 }
196
197 AST_TEST_DEFINE(json_test_null)
198 {
199         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
200
201         switch (cmd) {
202         case TEST_INIT:
203                 info->name = "null";
204                 info->category = CATEGORY;
205                 info->summary = "Testing JSON null value.";
206                 info->description = "Test JSON abstraction library.";
207                 return AST_TEST_NOT_RUN;
208         case TEST_EXECUTE:
209                 break;
210         }
211
212         uut = ast_json_null();
213         ast_test_validate(test, NULL != uut);
214         ast_test_validate(test, AST_JSON_NULL == ast_json_typeof(uut));
215         ast_test_validate(test, ast_json_is_null(uut));
216         ast_test_validate(test, !ast_json_is_true(uut));
217         ast_test_validate(test, !ast_json_is_false(uut));
218
219         return AST_TEST_PASS;
220 }
221
222 AST_TEST_DEFINE(json_test_null_val)
223 {
224         switch (cmd) {
225         case TEST_INIT:
226                 info->name = "null_val";
227                 info->category = CATEGORY;
228                 info->summary = "Testing JSON handling of NULL.";
229                 info->description = "Test JSON abstraction library.";
230                 return AST_TEST_NOT_RUN;
231         case TEST_EXECUTE:
232                 break;
233         }
234
235         /* NULL isn't null, true or false */
236         ast_test_validate(test, !ast_json_is_null(NULL));
237         ast_test_validate(test, !ast_json_is_false(NULL));
238         ast_test_validate(test, !ast_json_is_true(NULL));
239
240         /* ref and unref should be NULL safe */
241         ast_json_ref(NULL);
242         ast_json_unref(NULL);
243         /* no segfault; we're good. le sigh. */
244
245         return AST_TEST_PASS;
246 }
247
248 AST_TEST_DEFINE(json_test_string)
249 {
250         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
251         int uut_res;
252
253         switch (cmd) {
254         case TEST_INIT:
255                 info->name = "string";
256                 info->category = CATEGORY;
257                 info->summary = "Basic string tests.";
258                 info->description = "Test JSON abstraction library.";
259                 return AST_TEST_NOT_RUN;
260         case TEST_EXECUTE:
261                 break;
262         }
263
264         uut = ast_json_string_create("Hello, json");
265         ast_test_validate(test, NULL != uut);
266         ast_test_validate(test, AST_JSON_STRING == ast_json_typeof(uut));
267         ast_test_validate(test, 0 == strcmp("Hello, json", ast_json_string_get(uut)));
268
269         uut_res = ast_json_string_set(uut, NULL);
270         ast_test_validate(test, -1 == uut_res);
271         ast_test_validate(test, 0 == strcmp("Hello, json", ast_json_string_get(uut)));
272
273         uut_res = ast_json_string_set(uut, "Not UTF-8 - \xff");
274         ast_test_validate(test, -1 == uut_res);
275         ast_test_validate(test, 0 == strcmp("Hello, json", ast_json_string_get(uut)));
276
277         uut_res = ast_json_string_set(uut, "Is UTF-8 - \xE2\x98\xBA");
278         ast_test_validate(test, 0 == uut_res);
279         ast_test_validate(test, 0 == strcmp("Is UTF-8 - \xE2\x98\xBA", ast_json_string_get(uut)));
280
281         uut_res = ast_json_string_set(uut, "Goodbye, json");
282         ast_test_validate(test, 0 == uut_res);
283         ast_test_validate(test, 0 == strcmp("Goodbye, json", ast_json_string_get(uut)));
284
285         return AST_TEST_PASS;
286 }
287
288 AST_TEST_DEFINE(json_test_string_null)
289 {
290         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
291
292         switch (cmd) {
293         case TEST_INIT:
294                 info->name = "string_null";
295                 info->category = CATEGORY;
296                 info->summary = "JSON string NULL tests.";
297                 info->description = "Test JSON abstraction library.";
298                 return AST_TEST_NOT_RUN;
299         case TEST_EXECUTE:
300                 break;
301         }
302
303         /* NULL string */
304         uut = ast_json_string_create(NULL);
305         ast_test_validate(test, NULL == uut);
306
307         /* NULL JSON strings */
308         ast_test_validate(test, NULL == ast_json_string_create(NULL));
309         ast_test_validate(test, NULL == ast_json_string_get(NULL));
310         ast_test_validate(test, -1 == ast_json_string_set(NULL, "not null"));
311
312         /* string_value from non-string elements should return NULL */
313         ast_test_validate(test, NULL == ast_json_string_get(ast_json_null()));
314         ast_test_validate(test, NULL == ast_json_string_get(ast_json_false()));
315         ast_test_validate(test, NULL == ast_json_string_get(ast_json_true()));
316
317         return AST_TEST_PASS;
318 }
319
320 AST_TEST_DEFINE(json_test_stringf)
321 {
322         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
323         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
324
325         switch (cmd) {
326         case TEST_INIT:
327                 info->name = "stringf";
328                 info->category = CATEGORY;
329                 info->summary = "Basic string formatting tests.";
330                 info->description = "Test JSON abstraction library.";
331                 return AST_TEST_NOT_RUN;
332         case TEST_EXECUTE:
333                 break;
334         }
335
336         /* NULL format string */
337         uut = ast_json_stringf(NULL);
338         ast_test_validate(test, NULL == uut);
339
340         /* Non-UTF-8 strings are invalid */
341         uut = ast_json_stringf("Not UTF-8 - %s", "\xff");
342         ast_test_validate(test, NULL == uut);
343
344         /* formatted string */
345         uut = ast_json_stringf("Hello, %s", "json");
346         expected = ast_json_string_create("Hello, json");
347         ast_test_validate(test, NULL != uut);
348         ast_test_validate(test, ast_json_equal(expected, uut));
349
350         return AST_TEST_PASS;
351 }
352
353 AST_TEST_DEFINE(json_test_int)
354 {
355         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
356         int uut_res;
357
358         switch (cmd) {
359         case TEST_INIT:
360                 info->name = "int";
361                 info->category = CATEGORY;
362                 info->summary = "Basic JSON integer tests.";
363                 info->description = "Test JSON abstraction library.";
364                 return AST_TEST_NOT_RUN;
365         case TEST_EXECUTE:
366                 break;
367         }
368
369         /* Integer tests */
370         uut = ast_json_integer_create(0);
371         ast_test_validate(test, NULL != uut);
372         ast_test_validate(test, AST_JSON_INTEGER == ast_json_typeof(uut));
373         ast_test_validate(test, 0 == ast_json_integer_get(uut));
374
375         uut_res = ast_json_integer_set(uut, 1);
376         ast_test_validate(test, 0 == uut_res);
377         ast_test_validate(test, 1 == ast_json_integer_get(uut));
378
379         uut_res = ast_json_integer_set(uut, -1);
380         ast_test_validate(test, 0 == uut_res);
381         ast_test_validate(test, -1 == ast_json_integer_get(uut));
382
383         uut_res = ast_json_integer_set(uut, LLONG_MAX);
384         ast_test_validate(test, 0 == uut_res);
385         ast_test_validate(test, LLONG_MAX == ast_json_integer_get(uut));
386
387         uut_res = ast_json_integer_set(uut, LLONG_MIN);
388         ast_test_validate(test, 0 == uut_res);
389         ast_test_validate(test, LLONG_MIN == ast_json_integer_get(uut));
390
391         return AST_TEST_PASS;
392 }
393
394 AST_TEST_DEFINE(json_test_non_int)
395 {
396         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
397
398         switch (cmd) {
399         case TEST_INIT:
400                 info->name = "non_int";
401                 info->category = CATEGORY;
402                 info->summary = "Testing integer functions with non-integer types.";
403                 info->description = "Test JSON abstraction library.";
404                 return AST_TEST_NOT_RUN;
405         case TEST_EXECUTE:
406                 break;
407         }
408
409         /* Non-ints return 0 integer value */
410         ast_test_validate(test, 0 == ast_json_integer_get(ast_json_null()));
411         ast_test_validate(test, 0 == ast_json_integer_get(ast_json_true()));
412         ast_test_validate(test, 0 == ast_json_integer_get(ast_json_false()));
413
414         /* JSON NULL integers */
415         ast_test_validate(test, 0 == ast_json_integer_get(NULL));
416         ast_test_validate(test, -1 == ast_json_integer_set(NULL, 911));
417         ast_test_validate(test, 0 == ast_json_array_size(NULL));
418
419         /* No magical parsing of strings into ints */
420         uut = ast_json_string_create("314");
421         ast_test_validate(test, NULL != uut);
422         ast_test_validate(test, 0 == ast_json_integer_get(uut));
423
424         /* Or vice-versa */
425         ast_json_unref(uut);
426         uut = ast_json_integer_create(314);
427         ast_test_validate(test, NULL == ast_json_string_get(uut));
428
429         return AST_TEST_PASS;
430 }
431
432 AST_TEST_DEFINE(json_test_array_create)
433 {
434         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
435
436         switch (cmd) {
437         case TEST_INIT:
438                 info->name = "array_create";
439                 info->category = CATEGORY;
440                 info->summary = "Testing creating JSON arrays.";
441                 info->description = "Test JSON abstraction library.";
442                 return AST_TEST_NOT_RUN;
443         case TEST_EXECUTE:
444                 break;
445         }
446
447         /* array creation */
448         uut = ast_json_array_create();
449         ast_test_validate(test, NULL != uut);
450         ast_test_validate(test, AST_JSON_ARRAY == ast_json_typeof(uut));
451         ast_test_validate(test, 0 == ast_json_array_size(uut));
452
453         return AST_TEST_PASS;
454 }
455
456 AST_TEST_DEFINE(json_test_array_append)
457 {
458         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
459         int uut_res;
460
461         switch (cmd) {
462         case TEST_INIT:
463                 info->name = "array_append";
464                 info->category = CATEGORY;
465                 info->summary = "Testing appending to JSON arrays.";
466                 info->description = "Test JSON abstraction library.";
467                 return AST_TEST_NOT_RUN;
468         case TEST_EXECUTE:
469                 break;
470         }
471
472         /* array append */
473         uut = ast_json_array_create();
474         uut_res = ast_json_array_append(uut, ast_json_string_create("one"));
475         ast_test_validate(test, 0 == uut_res);
476         ast_test_validate(test, 1 == ast_json_array_size(uut));
477         ast_test_validate(test, 0 == strcmp("one", ast_json_string_get(ast_json_array_get(uut, 0))));
478         /* index out of range */
479         ast_test_validate(test, NULL == ast_json_array_get(uut, 1));
480         ast_test_validate(test, NULL == ast_json_array_get(uut, -1));
481
482         return AST_TEST_PASS;
483 }
484
485 AST_TEST_DEFINE(json_test_array_inset)
486 {
487         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
488         int uut_res;
489
490         switch (cmd) {
491         case TEST_INIT:
492                 info->name = "array_insert";
493                 info->category = CATEGORY;
494                 info->summary = "Testing inserting into JSON arrays.";
495                 info->description = "Test JSON abstraction library.";
496                 return AST_TEST_NOT_RUN;
497         case TEST_EXECUTE:
498                 break;
499         }
500
501         /* array insert */
502         uut = ast_json_pack("[s]", "one");
503         uut_res = ast_json_array_insert(uut, 0, ast_json_string_create("zero"));
504         ast_test_validate(test, 0 == uut_res);
505         ast_test_validate(test, 2 == ast_json_array_size(uut));
506         ast_test_validate(test, 0 == strcmp("zero", ast_json_string_get(ast_json_array_get(uut, 0))));
507         ast_test_validate(test, 0 == strcmp("one", ast_json_string_get(ast_json_array_get(uut, 1))));
508
509         return AST_TEST_PASS;
510 }
511
512 AST_TEST_DEFINE(json_test_array_set)
513 {
514         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
515         int uut_res;
516
517         switch (cmd) {
518         case TEST_INIT:
519                 info->name = "array_set";
520                 info->category = CATEGORY;
521                 info->summary = "Testing setting a value in JSON arrays.";
522                 info->description = "Test JSON abstraction library.";
523                 return AST_TEST_NOT_RUN;
524         case TEST_EXECUTE:
525                 break;
526         }
527
528         /* array set */
529         uut = ast_json_pack("[s, s]", "zero", "one");
530         uut_res = ast_json_array_set(uut, 1, ast_json_integer_create(1));
531         ast_test_validate(test, 0 == uut_res);
532         ast_test_validate(test, 2 == ast_json_array_size(uut));
533         ast_test_validate(test, 0 == strcmp("zero", ast_json_string_get(ast_json_array_get(uut, 0))));
534         ast_test_validate(test, 1 == ast_json_integer_get(ast_json_array_get(uut, 1)));
535
536         return AST_TEST_PASS;
537 }
538
539 AST_TEST_DEFINE(json_test_array_remove)
540 {
541         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
542         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
543         int uut_res;
544
545         switch (cmd) {
546         case TEST_INIT:
547                 info->name = "array_remove";
548                 info->category = CATEGORY;
549                 info->summary = "Testing removing a value from JSON arrays.";
550                 info->description = "Test JSON abstraction library.";
551                 return AST_TEST_NOT_RUN;
552         case TEST_EXECUTE:
553                 break;
554         }
555
556         /* array remove */
557         uut = ast_json_pack("[s, i]", "zero", 1);
558         expected = ast_json_pack("[i]", 1);
559         uut_res = ast_json_array_remove(uut, 0);
560         ast_test_validate(test, 0 == uut_res);
561         ast_test_validate(test, ast_json_equal(expected, uut));
562
563         return AST_TEST_PASS;
564 }
565
566 AST_TEST_DEFINE(json_test_array_clear)
567 {
568         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
569         int uut_res;
570
571         switch (cmd) {
572         case TEST_INIT:
573                 info->name = "array_clear";
574                 info->category = CATEGORY;
575                 info->summary = "Testing clearing JSON arrays.";
576                 info->description = "Test JSON abstraction library.";
577                 return AST_TEST_NOT_RUN;
578         case TEST_EXECUTE:
579                 break;
580         }
581
582         /* array clear */
583         uut = ast_json_pack("[s, s]", "zero", "one");
584         uut_res = ast_json_array_clear(uut);
585         ast_test_validate(test, 0 == uut_res);
586         ast_test_validate(test, 0 == ast_json_array_size(uut));
587
588         return AST_TEST_PASS;
589 }
590
591 AST_TEST_DEFINE(json_test_array_extend)
592 {
593         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
594         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
595         RAII_VAR(struct ast_json *, tail, NULL, ast_json_unref);
596         int uut_res;
597
598         switch (cmd) {
599         case TEST_INIT:
600                 info->name = "array_extend";
601                 info->category = CATEGORY;
602                 info->summary = "Testing extending JSON arrays.";
603                 info->description = "Test JSON abstraction library.";
604                 return AST_TEST_NOT_RUN;
605         case TEST_EXECUTE:
606                 break;
607         }
608
609         /* array extending */
610         expected = ast_json_array_create();
611         ast_json_array_append(expected, ast_json_string_create("a"));
612         ast_json_array_append(expected, ast_json_string_create("b"));
613         ast_json_array_append(expected, ast_json_string_create("c"));
614         ast_json_array_append(expected, ast_json_integer_create(1));
615         ast_json_array_append(expected, ast_json_integer_create(2));
616         ast_json_array_append(expected, ast_json_integer_create(3));
617
618         uut = ast_json_array_create();
619         ast_json_array_append(uut, ast_json_string_create("a"));
620         ast_json_array_append(uut, ast_json_string_create("b"));
621         ast_json_array_append(uut, ast_json_string_create("c"));
622
623         tail = ast_json_array_create();
624         ast_json_array_append(tail, ast_json_integer_create(1));
625         ast_json_array_append(tail, ast_json_integer_create(2));
626         ast_json_array_append(tail, ast_json_integer_create(3));
627
628         uut_res = ast_json_array_extend(uut, tail);
629         ast_test_validate(test, 0 == uut_res);
630         ast_test_validate(test, ast_json_equal(expected, uut));
631         /* tail is preserved */
632         ast_test_validate(test, 3 == ast_json_array_size(tail));
633
634         return AST_TEST_PASS;
635 }
636
637 AST_TEST_DEFINE(json_test_array_null)
638 {
639         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
640
641         switch (cmd) {
642         case TEST_INIT:
643                 info->name = "array_null";
644                 info->category = CATEGORY;
645                 info->summary = "Testing NULL conditions for JSON arrays.";
646                 info->description = "Test JSON abstraction library.";
647                 return AST_TEST_NOT_RUN;
648         case TEST_EXECUTE:
649                 break;
650         }
651
652         /* array NULL checks */
653         ast_test_validate(test, 0 == ast_json_array_size(NULL));
654         ast_test_validate(test, NULL == ast_json_array_get(NULL, 0));
655         ast_test_validate(test, -1 == ast_json_array_set(NULL, 0, ast_json_null()));
656         ast_test_validate(test, -1 == ast_json_array_append(NULL, ast_json_null()));
657         ast_test_validate(test, -1 == ast_json_array_insert(NULL, 0, ast_json_null()));
658         ast_test_validate(test, -1 == ast_json_array_remove(NULL, 0));
659         ast_test_validate(test, -1 == ast_json_array_clear(NULL));
660         uut = ast_json_array_create();
661         ast_test_validate(test, -1 == ast_json_array_extend(uut, NULL));
662         ast_test_validate(test, -1 == ast_json_array_extend(NULL, uut));
663         ast_test_validate(test, -1 == ast_json_array_extend(NULL, NULL));
664
665         return AST_TEST_PASS;
666 }
667
668 AST_TEST_DEFINE(json_test_object_alloc)
669 {
670         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
671
672         switch (cmd) {
673         case TEST_INIT:
674                 info->name = "object_alloc";
675                 info->category = CATEGORY;
676                 info->summary = "Testing creating JSON objects.";
677                 info->description = "Test JSON abstraction library.";
678                 return AST_TEST_NOT_RUN;
679         case TEST_EXECUTE:
680                 break;
681         }
682
683         /* object allocation */
684         uut = ast_json_object_create();
685         ast_test_validate(test, NULL != uut);
686         ast_test_validate(test, AST_JSON_OBJECT == ast_json_typeof(uut));
687         ast_test_validate(test, 0 == ast_json_object_size(uut));
688
689         return AST_TEST_PASS;
690 }
691
692 AST_TEST_DEFINE(json_test_object_set)
693 {
694         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
695         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
696         int uut_res;
697
698         switch (cmd) {
699         case TEST_INIT:
700                 info->name = "object_set";
701                 info->category = CATEGORY;
702                 info->summary = "Testing setting values in JSON objects.";
703                 info->description = "Test JSON abstraction library.";
704                 return AST_TEST_NOT_RUN;
705         case TEST_EXECUTE:
706                 break;
707         }
708
709         /* object set */
710         expected = ast_json_pack("{s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3);
711         uut = ast_json_object_create();
712         uut_res = ast_json_object_set(uut, "one", ast_json_integer_create(1));
713         ast_test_validate(test, 0 == uut_res);
714         uut_res = ast_json_object_set(uut, "two", ast_json_integer_create(2));
715         ast_test_validate(test, 0 == uut_res);
716         uut_res = ast_json_object_set(uut, "three", ast_json_integer_create(3));
717         ast_test_validate(test, 0 == uut_res);
718         ast_test_validate(test, ast_json_equal(expected, uut));
719         ast_test_validate(test, NULL == ast_json_object_get(uut, "dne"));
720
721         return AST_TEST_PASS;
722 }
723
724 AST_TEST_DEFINE(json_test_object_set_overwrite)
725 {
726         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
727         int uut_res;
728
729         switch (cmd) {
730         case TEST_INIT:
731                 info->name = "object_set_overwriting";
732                 info->category = CATEGORY;
733                 info->summary = "Testing changing values in JSON objects.";
734                 info->description = "Test JSON abstraction library.";
735                 return AST_TEST_NOT_RUN;
736         case TEST_EXECUTE:
737                 break;
738         }
739
740         /* object set existing */
741         uut = ast_json_pack("{s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3);
742         uut_res = ast_json_object_set(uut, "two", ast_json_integer_create(-2));
743         ast_test_validate(test, 0 == uut_res);
744         ast_test_validate(test, -2 == ast_json_integer_get(ast_json_object_get(uut, "two")));
745
746         return AST_TEST_PASS;
747 }
748
749 AST_TEST_DEFINE(json_test_object_get)
750 {
751         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
752
753         switch (cmd) {
754         case TEST_INIT:
755                 info->name = "object_get";
756                 info->category = CATEGORY;
757                 info->summary = "Testing getting values from JSON objects.";
758                 info->description = "Test JSON abstraction library.";
759                 return AST_TEST_NOT_RUN;
760         case TEST_EXECUTE:
761                 break;
762         }
763
764         /* object get */
765         uut = ast_json_pack("{s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3);
766         ast_test_validate(test, 2 == ast_json_integer_get(ast_json_object_get(uut, "two")));
767         ast_test_validate(test, NULL == ast_json_object_get(uut, "dne"));
768         ast_test_validate(test, NULL == ast_json_object_get(uut, NULL));
769
770         return AST_TEST_PASS;
771 }
772
773 AST_TEST_DEFINE(json_test_object_del)
774 {
775         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
776         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
777         int uut_res;
778
779         switch (cmd) {
780         case TEST_INIT:
781                 info->name = "object_del";
782                 info->category = CATEGORY;
783                 info->summary = "Testing deleting values from JSON objects.";
784                 info->description = "Test JSON abstraction library.";
785                 return AST_TEST_NOT_RUN;
786         case TEST_EXECUTE:
787                 break;
788         }
789
790         /* object del */
791         expected = ast_json_object_create();
792         uut = ast_json_pack("{s: i}", "one", 1);
793         uut_res = ast_json_object_del(uut, "one");
794         ast_test_validate(test, 0 == uut_res);
795         ast_test_validate(test, ast_json_equal(expected, uut));
796         uut_res = ast_json_object_del(uut, "dne");
797         ast_test_validate(test, -1 == uut_res);
798
799         return AST_TEST_PASS;
800 }
801
802 AST_TEST_DEFINE(json_test_object_clear)
803 {
804         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
805         int uut_res;
806
807         switch (cmd) {
808         case TEST_INIT:
809                 info->name = "object_clear";
810                 info->category = CATEGORY;
811                 info->summary = "Testing clearing values from JSON objects.";
812                 info->description = "Test JSON abstraction library.";
813                 return AST_TEST_NOT_RUN;
814         case TEST_EXECUTE:
815                 break;
816         }
817
818         /* object clear */
819         uut = ast_json_object_create();
820         ast_json_object_set(uut, "one", ast_json_integer_create(1));
821         ast_json_object_set(uut, "two", ast_json_integer_create(2));
822         ast_json_object_set(uut, "three", ast_json_integer_create(3));
823         uut_res = ast_json_object_clear(uut);
824         ast_test_validate(test, 0 == uut_res);
825         ast_test_validate(test, 0 == ast_json_object_size(uut));
826
827         return AST_TEST_PASS;
828 }
829
830 AST_TEST_DEFINE(json_test_object_merge_all)
831 {
832         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
833         RAII_VAR(struct ast_json *, merge, NULL, ast_json_unref);
834         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
835         int uut_res;
836
837         switch (cmd) {
838         case TEST_INIT:
839                 info->name = "object_alloc";
840                 info->category = CATEGORY;
841                 info->summary = "Testing merging JSON objects.";
842                 info->description = "Test JSON abstraction library.";
843                 return AST_TEST_NOT_RUN;
844         case TEST_EXECUTE:
845                 break;
846         }
847
848         /* object merging - all */
849         uut = ast_json_object_create();
850         ast_json_object_set(uut, "one", ast_json_integer_create(1));
851         ast_json_object_set(uut, "two", ast_json_integer_create(2));
852         ast_json_object_set(uut, "three", ast_json_integer_create(3));
853
854         merge = ast_json_object_create();
855         ast_json_object_set(merge, "three", ast_json_integer_create(-3));
856         ast_json_object_set(merge, "four", ast_json_integer_create(-4));
857         ast_json_object_set(merge, "five", ast_json_integer_create(-5));
858
859         expected = ast_json_object_create();
860         ast_json_object_set(expected, "one", ast_json_integer_create(1));
861         ast_json_object_set(expected, "two", ast_json_integer_create(2));
862         ast_json_object_set(expected, "three", ast_json_integer_create(-3));
863         ast_json_object_set(expected, "four", ast_json_integer_create(-4));
864         ast_json_object_set(expected, "five", ast_json_integer_create(-5));
865
866         uut_res = ast_json_object_update(uut, merge);
867         ast_test_validate(test, 0 == uut_res);
868         ast_test_validate(test, ast_json_equal(expected, uut));
869         /* merge object is untouched */
870         ast_test_validate(test, 3 == ast_json_object_size(merge));
871
872         return AST_TEST_PASS;
873 }
874
875 AST_TEST_DEFINE(json_test_object_merge_existing)
876 {
877         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
878         RAII_VAR(struct ast_json *, merge, NULL, ast_json_unref);
879         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
880         int uut_res;
881
882         switch (cmd) {
883         case TEST_INIT:
884                 info->name = "object_alloc";
885                 info->category = CATEGORY;
886                 info->summary = "Testing merging JSON objects, updating only existing fields.";
887                 info->description = "Test JSON abstraction library.";
888                 return AST_TEST_NOT_RUN;
889         case TEST_EXECUTE:
890                 break;
891         }
892
893         /* object merging - existing */
894         uut = ast_json_object_create();
895         ast_json_object_set(uut, "one", ast_json_integer_create(1));
896         ast_json_object_set(uut, "two", ast_json_integer_create(2));
897         ast_json_object_set(uut, "three", ast_json_integer_create(3));
898
899         merge = ast_json_object_create();
900         ast_json_object_set(merge, "three", ast_json_integer_create(-3));
901         ast_json_object_set(merge, "four", ast_json_integer_create(-4));
902         ast_json_object_set(merge, "five", ast_json_integer_create(-5));
903
904         expected = ast_json_object_create();
905         ast_json_object_set(expected, "one", ast_json_integer_create(1));
906         ast_json_object_set(expected, "two", ast_json_integer_create(2));
907         ast_json_object_set(expected, "three", ast_json_integer_create(-3));
908
909         uut_res = ast_json_object_update_existing(uut, merge);
910         ast_test_validate(test, 0 == uut_res);
911         ast_test_validate(test, ast_json_equal(expected, uut));
912         /* merge object is untouched */
913         ast_test_validate(test, 3 == ast_json_object_size(merge));
914
915         return AST_TEST_PASS;
916 }
917
918 AST_TEST_DEFINE(json_test_object_merge_missing)
919 {
920         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
921         RAII_VAR(struct ast_json *, merge, NULL, ast_json_unref);
922         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
923         int uut_res;
924
925         switch (cmd) {
926         case TEST_INIT:
927                 info->name = "object_merge_missing";
928                 info->category = CATEGORY;
929                 info->summary = "Testing merging JSON objects, adding only missing fields.";
930                 info->description = "Test JSON abstraction library.";
931                 return AST_TEST_NOT_RUN;
932         case TEST_EXECUTE:
933                 break;
934         }
935
936         /* object merging - missing */
937         uut = ast_json_object_create();
938         ast_json_object_set(uut, "one", ast_json_integer_create(1));
939         ast_json_object_set(uut, "two", ast_json_integer_create(2));
940         ast_json_object_set(uut, "three", ast_json_integer_create(3));
941
942         merge = ast_json_object_create();
943         ast_json_object_set(merge, "three", ast_json_integer_create(-3));
944         ast_json_object_set(merge, "four", ast_json_integer_create(-4));
945         ast_json_object_set(merge, "five", ast_json_integer_create(-5));
946
947         expected = ast_json_object_create();
948         ast_json_object_set(expected, "one", ast_json_integer_create(1));
949         ast_json_object_set(expected, "two", ast_json_integer_create(2));
950         ast_json_object_set(expected, "three", ast_json_integer_create(3));
951         ast_json_object_set(expected, "four", ast_json_integer_create(-4));
952         ast_json_object_set(expected, "five", ast_json_integer_create(-5));
953
954         uut_res = ast_json_object_update_missing(uut, merge);
955         ast_test_validate(test, 0 == uut_res);
956         ast_test_validate(test, ast_json_equal(expected, uut));
957         /* merge object is untouched */
958         ast_test_validate(test, 3 == ast_json_object_size(merge));
959
960         return AST_TEST_PASS;
961 }
962
963 AST_TEST_DEFINE(json_test_object_null)
964 {
965         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
966
967         switch (cmd) {
968         case TEST_INIT:
969                 info->name = "object_null";
970                 info->category = CATEGORY;
971                 info->summary = "Testing JSON object NULL behavior.";
972                 info->description = "Test JSON abstraction library.";
973                 return AST_TEST_NOT_RUN;
974         case TEST_EXECUTE:
975                 break;
976         }
977
978         /* Object NULL testing */
979         ast_test_validate(test, 0 == ast_json_object_size(NULL));
980         ast_test_validate(test, NULL == ast_json_object_get(NULL, "not null"));
981         ast_test_validate(test, -1 == ast_json_object_set(NULL, "not null", ast_json_null()));
982         ast_test_validate(test, -1 == ast_json_object_del(NULL, "not null"));
983         ast_test_validate(test, -1 == ast_json_object_clear(NULL));
984         uut = ast_json_object_create();
985         ast_test_validate(test, -1 == ast_json_object_update(NULL, uut));
986         ast_test_validate(test, -1 == ast_json_object_update(uut, NULL));
987         ast_test_validate(test, -1 == ast_json_object_update(NULL, NULL));
988         ast_test_validate(test, -1 == ast_json_object_update_existing(NULL, uut));
989         ast_test_validate(test, -1 == ast_json_object_update_existing(uut, NULL));
990         ast_test_validate(test, -1 == ast_json_object_update_existing(NULL, NULL));
991         ast_test_validate(test, -1 == ast_json_object_update_missing(NULL, uut));
992         ast_test_validate(test, -1 == ast_json_object_update_missing(uut, NULL));
993         ast_test_validate(test, -1 == ast_json_object_update_missing(NULL, NULL));
994
995         return AST_TEST_PASS;
996 }
997
998 AST_TEST_DEFINE(json_test_object_iter)
999 {
1000         struct ast_json_iter *iter;
1001         int count;
1002         int uut_res;
1003         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1004
1005         switch (cmd) {
1006         case TEST_INIT:
1007                 info->name = "object_iter";
1008                 info->category = CATEGORY;
1009                 info->summary = "Testing iterating through JSON objects.";
1010                 info->description = "Test JSON abstraction library.";
1011                 return AST_TEST_NOT_RUN;
1012         case TEST_EXECUTE:
1013                 break;
1014         }
1015
1016         /* Object iterator testing */
1017         uut = ast_json_pack("{s: i, s: i, s: i, s: i, s: i}", "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
1018
1019         /* Iterate through the object; be aware that order isn't specified */
1020         iter = ast_json_object_iter(uut);
1021         ast_test_validate(test, NULL != iter);
1022         count = 0;
1023         while (NULL != iter) {
1024                 if (0 == strcmp("one", ast_json_object_iter_key(iter))) {
1025                         ast_test_validate(test, 1 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1026                 } else if (0 == strcmp("two", ast_json_object_iter_key(iter))) {
1027                         ast_test_validate(test, 2 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1028                 } else if (0 == strcmp("three", ast_json_object_iter_key(iter))) {
1029                         ast_test_validate(test, 3 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1030                 } else if (0 == strcmp("four", ast_json_object_iter_key(iter))) {
1031                         ast_test_validate(test, 4 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1032                 } else if (0 == strcmp("five", ast_json_object_iter_key(iter))) {
1033                         ast_test_validate(test, 5 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1034                 } else {
1035                         /* Unexpected key */
1036                         ast_test_validate(test, 0);
1037                 }
1038                 iter = ast_json_object_iter_next(uut, iter);
1039                 ++count;
1040         }
1041         ast_test_validate(test, 5 == count);
1042
1043         /* iterator non-existing key */
1044         iter = ast_json_object_iter_at(uut, "dne");
1045         ast_test_validate(test, NULL == iter);
1046
1047         /* iterator specific key */
1048         iter = ast_json_object_iter_at(uut, "three");
1049         ast_test_validate(test, NULL != iter);
1050         ast_test_validate(test, 3 == ast_json_integer_get(ast_json_object_iter_value(iter)));
1051
1052         /* set via iter */
1053         iter = ast_json_object_iter_at(uut, "three");
1054         uut_res = ast_json_object_iter_set(uut, iter, ast_json_integer_create(-3));
1055         ast_test_validate(test, 0 == uut_res);
1056         ast_test_validate(test, -3 == ast_json_integer_get(ast_json_object_get(uut, "three")));
1057
1058         return AST_TEST_PASS;
1059 }
1060
1061 AST_TEST_DEFINE(json_test_object_iter_null)
1062 {
1063         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1064
1065         switch (cmd) {
1066         case TEST_INIT:
1067                 info->name = "object_iter_null";
1068                 info->category = CATEGORY;
1069                 info->summary = "Testing JSON object iterator NULL testings.";
1070                 info->description = "Test JSON abstraction library.";
1071                 return AST_TEST_NOT_RUN;
1072         case TEST_EXECUTE:
1073                 break;
1074         }
1075
1076         /* iterator NULL tests */
1077         uut = ast_json_object_create();
1078         ast_test_validate(test, NULL == ast_json_object_iter(NULL));
1079         ast_test_validate(test, NULL == ast_json_object_iter_at(NULL, "not null"));
1080         ast_test_validate(test, NULL == ast_json_object_iter_next(NULL, NULL));
1081         ast_test_validate(test, NULL == ast_json_object_iter_next(uut, NULL));
1082         ast_test_validate(test, NULL == ast_json_object_iter_key(NULL));
1083         ast_test_validate(test, NULL == ast_json_object_iter_value(NULL));
1084         ast_test_validate(test, -1 == ast_json_object_iter_set(NULL, NULL, ast_json_null()));
1085         ast_test_validate(test, -1 == ast_json_object_iter_set(uut, NULL, ast_json_null()));
1086
1087         return AST_TEST_PASS;
1088 }
1089
1090 AST_TEST_DEFINE(json_test_dump_load_string)
1091 {
1092         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1093         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1094         RAII_VAR(char *, str, NULL, json_debug_free);
1095
1096         switch (cmd) {
1097         case TEST_INIT:
1098                 info->name = "dump_load_string";
1099                 info->category = CATEGORY;
1100                 info->summary = "Testing dumping strings from JSON.";
1101                 info->description = "Test JSON abstraction library.";
1102                 return AST_TEST_NOT_RUN;
1103         case TEST_EXECUTE:
1104                 break;
1105         }
1106         expected = ast_json_pack("{ s: i }", "one", 1);
1107         str = ast_json_dump_string(expected);
1108         ast_test_validate(test, NULL != str);
1109         uut = ast_json_load_string(str, NULL);
1110         ast_test_validate(test, NULL != uut);
1111         ast_test_validate(test, ast_json_equal(expected, uut));
1112
1113         /* dump_string NULL */
1114         ast_test_validate(test, NULL == ast_json_dump_string(NULL));
1115
1116         return AST_TEST_PASS;
1117 }
1118
1119 AST_TEST_DEFINE(json_test_dump_load_str)
1120 {
1121         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1122         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1123         RAII_VAR(struct ast_str *, astr, NULL, ast_free);
1124         int uut_res;
1125
1126         switch (cmd) {
1127         case TEST_INIT:
1128                 info->name = "dump_load_str";
1129                 info->category = CATEGORY;
1130                 info->summary = "Testing dumping ast_str from JSON.";
1131                 info->description = "Test JSON abstraction library.";
1132                 return AST_TEST_NOT_RUN;
1133         case TEST_EXECUTE:
1134                 break;
1135         }
1136
1137         /* dump/load ast_str */
1138         expected = ast_json_pack("{ s: i }", "one", 1);
1139         astr = ast_str_create(1); /* should expand to hold output */
1140         uut_res = ast_json_dump_str(expected, &astr);
1141         ast_test_validate(test, 0 == uut_res);
1142         uut = ast_json_load_str(astr, NULL);
1143         ast_test_validate(test, NULL != uut);
1144         ast_test_validate(test, ast_json_equal(expected, uut));
1145
1146         return AST_TEST_PASS;
1147 }
1148
1149 AST_TEST_DEFINE(json_test_dump_str_fail)
1150 {
1151         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1152         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1153         struct ast_str *astr;
1154         int uut_res;
1155
1156         switch (cmd) {
1157         case TEST_INIT:
1158                 info->name = "dump_str_fail";
1159                 info->category = CATEGORY;
1160                 info->summary = "Testing dumping to ast_str when it can't grow.";
1161                 info->description = "Test JSON abstraction library.";
1162                 return AST_TEST_NOT_RUN;
1163         case TEST_EXECUTE:
1164                 break;
1165         }
1166
1167         /* dump ast_str growth failure */
1168         expected = ast_json_pack("{ s: i }", "one", 1);
1169         astr = ast_str_alloca(1); /* cannot grow */
1170         uut_res = ast_json_dump_str(expected, &astr);
1171         ast_test_validate(test, 0 != uut_res);
1172
1173         return AST_TEST_PASS;
1174 }
1175
1176 AST_TEST_DEFINE(json_test_load_buffer)
1177 {
1178         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1179         const char *str;
1180
1181         switch (cmd) {
1182         case TEST_INIT:
1183                 info->name = "load_buffer";
1184                 info->category = CATEGORY;
1185                 info->summary = "Testing loading JSON from buffer.";
1186                 info->description = "Test JSON abstraction library.";
1187                 return AST_TEST_NOT_RUN;
1188         case TEST_EXECUTE:
1189                 break;
1190         }
1191
1192         /* load buffer */
1193         str = "{ \"one\": 1 } trailing garbage";
1194         uut = ast_json_load_string(str, NULL);
1195         ast_test_validate(test, NULL == uut);
1196         uut = ast_json_load_buf(str, strlen("{ \"one\": 1 }"), NULL);
1197         ast_test_validate(test, NULL != uut);
1198
1199         return AST_TEST_PASS;
1200 }
1201
1202 /*! \brief \a fclose isn't NULL safe. */
1203 static int safe_fclose(FILE *f)
1204 {
1205         if (f) {
1206                 return fclose(f);
1207         }
1208         return 0;
1209 }
1210
1211 AST_TEST_DEFINE(json_test_dump_load_file)
1212 {
1213         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1214         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1215         RAII_VAR(char *, filename, NULL, free);
1216         RAII_VAR(FILE *, file, NULL, safe_fclose);
1217         int uut_res;
1218
1219         switch (cmd) {
1220         case TEST_INIT:
1221                 info->name = "dump_load_file";
1222                 info->category = CATEGORY;
1223                 info->summary = "Testing dumping/loading JSON to/from file by FILE *.";
1224                 info->description = "Test JSON abstraction library.";
1225                 return AST_TEST_NOT_RUN;
1226         case TEST_EXECUTE:
1227                 break;
1228         }
1229
1230         /* dump/load file */
1231         expected = ast_json_pack("{ s: i }", "one", 1);
1232         filename = tempnam(NULL, "ast-json");
1233         file = fopen(filename, "w");
1234         uut_res = ast_json_dump_file(expected, file);
1235         ast_test_validate(test, 0 == uut_res);
1236         fclose(file);
1237         file = fopen(filename, "r");
1238         uut = ast_json_load_file(file, NULL);
1239         ast_test_validate(test, ast_json_equal(expected, uut));
1240
1241         return AST_TEST_PASS;
1242 }
1243
1244 AST_TEST_DEFINE(json_test_dump_load_new_file)
1245 {
1246         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1247         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1248         RAII_VAR(char *, filename, NULL, free);
1249         int uut_res;
1250
1251         switch (cmd) {
1252         case TEST_INIT:
1253                 info->name = "dump_load_new_file";
1254                 info->category = CATEGORY;
1255                 info->summary = "Testing dumping/load JSON to/from file by filename.";
1256                 info->description = "Test JSON abstraction library.";
1257                 return AST_TEST_NOT_RUN;
1258         case TEST_EXECUTE:
1259                 break;
1260         }
1261
1262         /* dump/load filename */
1263         expected = ast_json_pack("{ s: i }", "one", 1);
1264         filename = tempnam(NULL, "ast-json");
1265         uut_res = ast_json_dump_new_file(expected, filename);
1266         ast_test_validate(test, 0 == uut_res);
1267         uut = ast_json_load_new_file(filename, NULL);
1268         ast_test_validate(test, ast_json_equal(expected, uut));
1269
1270         return AST_TEST_PASS;
1271 }
1272
1273 AST_TEST_DEFINE(json_test_dump_load_null)
1274 {
1275         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1276         RAII_VAR(char *, filename, NULL, free);
1277         RAII_VAR(FILE *, file, NULL, safe_fclose);
1278
1279         switch (cmd) {
1280         case TEST_INIT:
1281                 info->name = "dump_load_null";
1282                 info->category = CATEGORY;
1283                 info->summary = "Testing NULL handling of dump/load functions.";
1284                 info->description = "Test JSON abstraction library.";
1285                 return AST_TEST_NOT_RUN;
1286         case TEST_EXECUTE:
1287                 break;
1288         }
1289
1290         /* dump/load NULL tests */
1291         uut = ast_json_load_string("{ \"one\": 1 }", NULL);
1292         ast_test_validate(test, NULL != uut);
1293         filename = tempnam(NULL, "ast-json");
1294         file = fopen(filename, "w");
1295         ast_test_validate(test, NULL == ast_json_dump_string(NULL));
1296         ast_test_validate(test, -1 == ast_json_dump_file(NULL, file));
1297         ast_test_validate(test, -1 == ast_json_dump_file(uut, NULL));
1298         ast_test_validate(test, -1 == ast_json_dump_file(NULL, NULL));
1299         ast_test_validate(test, -1 == ast_json_dump_new_file(uut, NULL));
1300         ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, filename));
1301         ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, NULL));
1302         ast_test_validate(test, NULL == ast_json_load_string(NULL, NULL));
1303         ast_test_validate(test, NULL == ast_json_load_buf(NULL, 0, NULL));
1304         ast_test_validate(test, NULL == ast_json_load_file(NULL, NULL));
1305         ast_test_validate(test, NULL == ast_json_load_new_file(NULL, NULL));
1306
1307         return AST_TEST_PASS;
1308 }
1309
1310 AST_TEST_DEFINE(json_test_parse_errors)
1311 {
1312         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1313
1314         switch (cmd) {
1315         case TEST_INIT:
1316                 info->name = "parse_errors";
1317                 info->category = CATEGORY;
1318                 info->summary = "Testing various parse errors.";
1319                 info->description = "Test JSON abstraction library.";
1320                 return AST_TEST_NOT_RUN;
1321         case TEST_EXECUTE:
1322                 break;
1323         }
1324
1325         /* parse errors */
1326         ast_test_validate(test, NULL == ast_json_load_string("'singleton'", NULL));
1327         ast_test_validate(test, NULL == ast_json_load_string("{ no value }", NULL));
1328         ast_test_validate(test, NULL == ast_json_load_string("{ 'no': 'curly' ", NULL));
1329         ast_test_validate(test, NULL == ast_json_load_string("[ 'no', 'square'", NULL));
1330         ast_test_validate(test, NULL == ast_json_load_string("{ 1: 'int key' }", NULL));
1331         ast_test_validate(test, NULL == ast_json_load_string("", NULL));
1332         ast_test_validate(test, NULL == ast_json_load_string("{ 'missing' 'colon' }", NULL));
1333         ast_test_validate(test, NULL == ast_json_load_string("[ 'missing' 'comma' ]", NULL));
1334
1335         return AST_TEST_PASS;
1336 }
1337
1338 AST_TEST_DEFINE(json_test_pack)
1339 {
1340         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1341         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1342
1343         switch (cmd) {
1344         case TEST_INIT:
1345                 info->name = "pack";
1346                 info->category = CATEGORY;
1347                 info->summary = "Testing json_pack function.";
1348                 info->description = "Test JSON abstraction library.";
1349                 return AST_TEST_NOT_RUN;
1350         case TEST_EXECUTE:
1351                 break;
1352         }
1353
1354         /* pack test */
1355         expected = ast_json_array_create();
1356         ast_json_array_append(expected, ast_json_array_create());
1357         ast_json_array_append(expected, ast_json_object_create());
1358         ast_json_array_append(ast_json_array_get(expected, 0), ast_json_integer_create(1));
1359         ast_json_array_append(ast_json_array_get(expected, 0), ast_json_integer_create(2));
1360         ast_json_object_set(ast_json_array_get(expected, 1), "cool", ast_json_true());
1361         uut = ast_json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);
1362         ast_test_validate(test, NULL != uut);
1363         ast_test_validate(test, ast_json_equal(expected, uut));
1364
1365         return AST_TEST_PASS;
1366 }
1367
1368 AST_TEST_DEFINE(json_test_pack_ownership)
1369 {
1370         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1371
1372         switch (cmd) {
1373         case TEST_INIT:
1374                 info->name = "pack_ownership";
1375                 info->category = CATEGORY;
1376                 info->summary = "Testing json_pack failure conditions.";
1377                 info->description = "Test JSON abstraction library.";
1378                 return AST_TEST_NOT_RUN;
1379         case TEST_EXECUTE:
1380                 break;
1381         }
1382
1383         uut = ast_json_pack("[o]", ast_json_string_create("Am I freed?"));
1384
1385         return AST_TEST_PASS;
1386 }
1387
1388 AST_TEST_DEFINE(json_test_pack_errors)
1389 {
1390         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1391
1392         switch (cmd) {
1393         case TEST_INIT:
1394                 info->name = "object_alloc";
1395                 info->category = CATEGORY;
1396                 info->summary = "Testing json_pack failure conditions.";
1397                 info->description = "Test JSON abstraction library.";
1398                 return AST_TEST_NOT_RUN;
1399         case TEST_EXECUTE:
1400                 break;
1401         }
1402
1403         /* pack errors */
1404         ast_test_validate(test, NULL == ast_json_pack(NULL));
1405         ast_test_validate(test, NULL == ast_json_pack("{s:i", "no curly", 911));
1406         ast_test_validate(test, NULL == ast_json_pack("[s, s", "no", "square"));
1407
1408         return AST_TEST_PASS;
1409 }
1410
1411 AST_TEST_DEFINE(json_test_copy)
1412 {
1413         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1414         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1415
1416         switch (cmd) {
1417         case TEST_INIT:
1418                 info->name = "copy";
1419                 info->category = CATEGORY;
1420                 info->summary = "Testing copying JSON.";
1421                 info->description = "Test JSON abstraction library.";
1422                 return AST_TEST_NOT_RUN;
1423         case TEST_EXECUTE:
1424                 break;
1425         }
1426
1427         /* copy test */
1428         expected = ast_json_pack("{s: {s: i}}", "outer", "inner", 8675309);
1429         uut = ast_json_copy(expected);
1430         ast_test_validate(test, NULL != uut);
1431         ast_test_validate(test, ast_json_equal(expected, uut));
1432         ast_test_validate(test, ast_json_object_get(expected, "outer") == ast_json_object_get(uut, "outer"));
1433
1434         return AST_TEST_PASS;
1435 }
1436
1437 AST_TEST_DEFINE(json_test_deep_copy)
1438 {
1439         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1440         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1441
1442         switch (cmd) {
1443         case TEST_INIT:
1444                 info->name = "deep_copy";
1445                 info->category = CATEGORY;
1446                 info->summary = "Testing deep copying of JSON.";
1447                 info->description = "Test JSON abstraction library.";
1448                 return AST_TEST_NOT_RUN;
1449         case TEST_EXECUTE:
1450                 break;
1451         }
1452
1453         /* deep copy test */
1454         expected = ast_json_pack("{s: {s: i}}", "outer", "inner", 8675309);
1455         uut = ast_json_deep_copy(expected);
1456         ast_test_validate(test, NULL != uut);
1457         ast_test_validate(test, ast_json_equal(expected, uut));
1458         ast_test_validate(test, ast_json_object_get(expected, "outer") != ast_json_object_get(uut, "outer"));
1459         /* Changing the inner value of one should not change the other */
1460         ast_json_integer_set(ast_json_object_get(ast_json_object_get(uut, "outer"), "inner"), 411);
1461         ast_test_validate(test, !ast_json_equal(expected, uut));
1462
1463         return AST_TEST_PASS;
1464 }
1465
1466 AST_TEST_DEFINE(json_test_copy_null)
1467 {
1468         switch (cmd) {
1469         case TEST_INIT:
1470                 info->name = "copy_null";
1471                 info->category = CATEGORY;
1472                 info->summary = "Testing NULL handling of copy functions.";
1473                 info->description = "Test JSON abstraction library.";
1474                 return AST_TEST_NOT_RUN;
1475         case TEST_EXECUTE:
1476                 break;
1477         }
1478
1479         /* copy NULL */
1480         ast_test_validate(test, NULL == ast_json_copy(NULL));
1481         ast_test_validate(test, NULL == ast_json_deep_copy(NULL));
1482
1483         return AST_TEST_PASS;
1484 }
1485
1486 AST_TEST_DEFINE(json_test_circular_object)
1487 {
1488         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1489         int uut_res;
1490
1491         switch (cmd) {
1492         case TEST_INIT:
1493                 info->name = "circular_object";
1494                 info->category = CATEGORY;
1495                 info->summary = "Object cannot be added to itself.";
1496                 info->description = "Test JSON abstraction library.";
1497                 return AST_TEST_NOT_RUN;
1498         case TEST_EXECUTE:
1499                 break;
1500         }
1501
1502         /* circular reference testing */
1503         /* Cannot add self */
1504         uut = ast_json_object_create();
1505         uut_res = ast_json_object_set(uut, "myself", ast_json_ref(uut));
1506         ast_test_validate(test, -1 == uut_res);
1507         ast_test_validate(test, 0 == ast_json_object_size(uut));
1508
1509         return AST_TEST_PASS;
1510 }
1511
1512 AST_TEST_DEFINE(json_test_circular_array)
1513 {
1514         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1515         int uut_res;
1516
1517         switch (cmd) {
1518         case TEST_INIT:
1519                 info->name = "circular_array";
1520                 info->category = CATEGORY;
1521                 info->summary = "Array cannot be added to itself.";
1522                 info->description = "Test JSON abstraction library.";
1523                 return AST_TEST_NOT_RUN;
1524         case TEST_EXECUTE:
1525                 break;
1526         }
1527
1528         uut = ast_json_array_create();
1529         ast_test_validate(test, 0 == ast_json_array_size(uut));
1530         uut_res = ast_json_array_append(uut, ast_json_ref(uut));
1531         ast_test_validate(test, -1 == uut_res);
1532         ast_test_validate(test, 0 == ast_json_array_size(uut));
1533
1534         return AST_TEST_PASS;
1535 }
1536
1537 AST_TEST_DEFINE(json_test_clever_circle)
1538 {
1539         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1540         RAII_VAR(struct ast_json *, inner_child, NULL, ast_json_unref);
1541         RAII_VAR(char *, str, NULL, json_debug_free);
1542         int uut_res;
1543
1544         switch (cmd) {
1545         case TEST_INIT:
1546                 info->name = "clever_circle";
1547                 info->category = CATEGORY;
1548                 info->summary = "JSON with circular references cannot be encoded.";
1549                 info->description = "Test JSON abstraction library.";
1550                 return AST_TEST_NOT_RUN;
1551         case TEST_EXECUTE:
1552                 break;
1553         }
1554
1555         /* can add to self if you're clever enough, but it should not encode */
1556         uut = ast_json_object_create();
1557         inner_child = ast_json_object_create();
1558         uut_res = ast_json_object_set(uut, "inner_child", ast_json_ref(inner_child));   /* incref to keep a reference */
1559         ast_test_validate(test, 0 == uut_res);
1560         uut_res = ast_json_object_set(inner_child, "parent", ast_json_ref(uut));   /* incref to keep a reference */
1561         ast_test_validate(test, 0 == uut_res);
1562         str = ast_json_dump_string(uut);
1563         ast_test_validate(test, NULL == str);
1564         /* Circular refs screw up reference counting, so break the cycle */
1565         ast_json_object_clear(inner_child);
1566
1567         return AST_TEST_PASS;
1568 }
1569
1570 AST_TEST_DEFINE(json_test_name_number)
1571 {
1572         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1573         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1574
1575         switch (cmd) {
1576         case TEST_INIT:
1577                 info->name = "name_number";
1578                 info->category = CATEGORY;
1579                 info->summary = "JSON encoding of name/number pair.";
1580                 info->description = "Test JSON abstraction library.";
1581                 return AST_TEST_NOT_RUN;
1582         case TEST_EXECUTE:
1583                 break;
1584         }
1585
1586         ast_test_validate(test, NULL == ast_json_name_number("name", NULL));
1587         ast_test_validate(test, NULL == ast_json_name_number(NULL, "1234"));
1588         ast_test_validate(test, NULL == ast_json_name_number(NULL, NULL));
1589
1590         expected = ast_json_pack("{s: s, s: s}",
1591                                  "name", "Jenny",
1592                                  "number", "867-5309");
1593         uut = ast_json_name_number("Jenny", "867-5309");
1594         ast_test_validate(test, ast_json_equal(expected, uut));
1595
1596         return AST_TEST_PASS;
1597 }
1598
1599 AST_TEST_DEFINE(json_test_timeval)
1600 {
1601         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1602         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1603         struct timeval tv = {};
1604
1605         switch (cmd) {
1606         case TEST_INIT:
1607                 info->name = "timeval";
1608                 info->category = CATEGORY;
1609                 info->summary = "JSON encoding of timevals.";
1610                 info->description = "Test JSON abstraction library.";
1611                 return AST_TEST_NOT_RUN;
1612         case TEST_EXECUTE:
1613                 break;
1614         }
1615
1616         expected = ast_json_string_create("2013-02-07T09:32:34.314-0600");
1617
1618         tv.tv_sec = 1360251154;
1619         tv.tv_usec = 314159;
1620         uut = ast_json_timeval(tv, "America/Chicago");
1621
1622         ast_test_validate(test, ast_json_equal(expected, uut));
1623
1624         return AST_TEST_PASS;
1625 }
1626
1627 AST_TEST_DEFINE(json_test_cep)
1628 {
1629         RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
1630         RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
1631
1632         switch (cmd) {
1633         case TEST_INIT:
1634                 info->name = "cep";
1635                 info->category = CATEGORY;
1636                 info->summary = "JSON with circular references cannot be encoded.";
1637                 info->description = "Test JSON abstraction library.";
1638                 return AST_TEST_NOT_RUN;
1639         case TEST_EXECUTE:
1640                 break;
1641         }
1642
1643         expected = ast_json_pack("{s: o, s: o, s: o}",
1644                                  "context", ast_json_null(),
1645                                  "exten", ast_json_null(),
1646                                  "priority", ast_json_null());
1647         uut = ast_json_dialplan_cep(NULL, NULL, -1);
1648         ast_test_validate(test, ast_json_equal(expected, uut));
1649
1650         ast_json_unref(expected);
1651         ast_json_unref(uut);
1652         expected = ast_json_pack("{s: s, s: s, s: i}",
1653                                  "context", "main",
1654                                  "exten", "4321",
1655                                  "priority", 7);
1656         uut = ast_json_dialplan_cep("main", "4321", 7);
1657         ast_test_validate(test, ast_json_equal(expected, uut));
1658
1659         return AST_TEST_PASS;
1660 }
1661
1662 static int unload_module(void)
1663 {
1664         AST_TEST_UNREGISTER(json_test_false);
1665         AST_TEST_UNREGISTER(json_test_true);
1666         AST_TEST_UNREGISTER(json_test_bool0);
1667         AST_TEST_UNREGISTER(json_test_bool1);
1668         AST_TEST_UNREGISTER(json_test_null);
1669         AST_TEST_UNREGISTER(json_test_null_val);
1670         AST_TEST_UNREGISTER(json_test_string);
1671         AST_TEST_UNREGISTER(json_test_string_null);
1672         AST_TEST_UNREGISTER(json_test_stringf);
1673         AST_TEST_UNREGISTER(json_test_int);
1674         AST_TEST_UNREGISTER(json_test_non_int);
1675         AST_TEST_UNREGISTER(json_test_array_create);
1676         AST_TEST_UNREGISTER(json_test_array_append);
1677         AST_TEST_UNREGISTER(json_test_array_inset);
1678         AST_TEST_UNREGISTER(json_test_array_set);
1679         AST_TEST_UNREGISTER(json_test_array_remove);
1680         AST_TEST_UNREGISTER(json_test_array_clear);
1681         AST_TEST_UNREGISTER(json_test_array_extend);
1682         AST_TEST_UNREGISTER(json_test_array_null);
1683         AST_TEST_UNREGISTER(json_test_object_alloc);
1684         AST_TEST_UNREGISTER(json_test_object_set);
1685         AST_TEST_UNREGISTER(json_test_object_set_overwrite);
1686         AST_TEST_UNREGISTER(json_test_object_get);
1687         AST_TEST_UNREGISTER(json_test_object_del);
1688         AST_TEST_UNREGISTER(json_test_object_clear);
1689         AST_TEST_UNREGISTER(json_test_object_merge_all);
1690         AST_TEST_UNREGISTER(json_test_object_merge_existing);
1691         AST_TEST_UNREGISTER(json_test_object_merge_missing);
1692         AST_TEST_UNREGISTER(json_test_object_null);
1693         AST_TEST_UNREGISTER(json_test_object_iter);
1694         AST_TEST_UNREGISTER(json_test_object_iter_null);
1695         AST_TEST_UNREGISTER(json_test_dump_load_string);
1696         AST_TEST_UNREGISTER(json_test_dump_load_str);
1697         AST_TEST_UNREGISTER(json_test_dump_str_fail);
1698         AST_TEST_UNREGISTER(json_test_load_buffer);
1699         AST_TEST_UNREGISTER(json_test_dump_load_file);
1700         AST_TEST_UNREGISTER(json_test_dump_load_new_file);
1701         AST_TEST_UNREGISTER(json_test_dump_load_null);
1702         AST_TEST_UNREGISTER(json_test_parse_errors);
1703         AST_TEST_UNREGISTER(json_test_pack);
1704         AST_TEST_UNREGISTER(json_test_pack_ownership);
1705         AST_TEST_UNREGISTER(json_test_pack_errors);
1706         AST_TEST_UNREGISTER(json_test_copy);
1707         AST_TEST_UNREGISTER(json_test_deep_copy);
1708         AST_TEST_UNREGISTER(json_test_copy_null);
1709         AST_TEST_UNREGISTER(json_test_circular_object);
1710         AST_TEST_UNREGISTER(json_test_circular_array);
1711         AST_TEST_UNREGISTER(json_test_clever_circle);
1712         AST_TEST_UNREGISTER(json_test_name_number);
1713         AST_TEST_UNREGISTER(json_test_timeval);
1714         AST_TEST_UNREGISTER(json_test_cep);
1715         return 0;
1716 }
1717
1718 static int load_module(void)
1719 {
1720         AST_TEST_REGISTER(json_test_false);
1721         AST_TEST_REGISTER(json_test_true);
1722         AST_TEST_REGISTER(json_test_bool0);
1723         AST_TEST_REGISTER(json_test_bool1);
1724         AST_TEST_REGISTER(json_test_null);
1725         AST_TEST_REGISTER(json_test_null_val);
1726         AST_TEST_REGISTER(json_test_string);
1727         AST_TEST_REGISTER(json_test_string_null);
1728         AST_TEST_REGISTER(json_test_stringf);
1729         AST_TEST_REGISTER(json_test_int);
1730         AST_TEST_REGISTER(json_test_non_int);
1731         AST_TEST_REGISTER(json_test_array_create);
1732         AST_TEST_REGISTER(json_test_array_append);
1733         AST_TEST_REGISTER(json_test_array_inset);
1734         AST_TEST_REGISTER(json_test_array_set);
1735         AST_TEST_REGISTER(json_test_array_remove);
1736         AST_TEST_REGISTER(json_test_array_clear);
1737         AST_TEST_REGISTER(json_test_array_extend);
1738         AST_TEST_REGISTER(json_test_array_null);
1739         AST_TEST_REGISTER(json_test_object_alloc);
1740         AST_TEST_REGISTER(json_test_object_set);
1741         AST_TEST_REGISTER(json_test_object_set_overwrite);
1742         AST_TEST_REGISTER(json_test_object_get);
1743         AST_TEST_REGISTER(json_test_object_del);
1744         AST_TEST_REGISTER(json_test_object_clear);
1745         AST_TEST_REGISTER(json_test_object_merge_all);
1746         AST_TEST_REGISTER(json_test_object_merge_existing);
1747         AST_TEST_REGISTER(json_test_object_merge_missing);
1748         AST_TEST_REGISTER(json_test_object_null);
1749         AST_TEST_REGISTER(json_test_object_iter);
1750         AST_TEST_REGISTER(json_test_object_iter_null);
1751         AST_TEST_REGISTER(json_test_dump_load_string);
1752         AST_TEST_REGISTER(json_test_dump_load_str);
1753         AST_TEST_REGISTER(json_test_dump_str_fail);
1754         AST_TEST_REGISTER(json_test_load_buffer);
1755         AST_TEST_REGISTER(json_test_dump_load_file);
1756         AST_TEST_REGISTER(json_test_dump_load_new_file);
1757         AST_TEST_REGISTER(json_test_dump_load_null);
1758         AST_TEST_REGISTER(json_test_parse_errors);
1759         AST_TEST_REGISTER(json_test_pack);
1760         AST_TEST_REGISTER(json_test_pack_ownership);
1761         AST_TEST_REGISTER(json_test_pack_errors);
1762         AST_TEST_REGISTER(json_test_copy);
1763         AST_TEST_REGISTER(json_test_deep_copy);
1764         AST_TEST_REGISTER(json_test_copy_null);
1765         AST_TEST_REGISTER(json_test_circular_object);
1766         AST_TEST_REGISTER(json_test_circular_array);
1767         AST_TEST_REGISTER(json_test_clever_circle);
1768         AST_TEST_REGISTER(json_test_name_number);
1769         AST_TEST_REGISTER(json_test_timeval);
1770         AST_TEST_REGISTER(json_test_cep);
1771
1772         ast_test_register_init(CATEGORY, json_test_init);
1773         ast_test_register_cleanup(CATEGORY, json_test_cleanup);
1774
1775         return AST_MODULE_LOAD_SUCCESS;
1776 }
1777
1778 AST_MODULE_INFO(ASTERISK_GPL_KEY, 0, "JSON testing",
1779                 .load = load_module,
1780                 .unload = unload_module);