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