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