app_queue: Revert bad ringinuse=no patch.
[asterisk/asterisk.git] / tests / test_format_api.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * David Vossel <dvossel@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 Tests for the ast_event API
22  *
23  * \author David Vossel <dvossel@digium.com>
24  *
25  * \ingroup tests
26  *
27  */
28
29 /*** MODULEINFO
30         <depend>TEST_FRAMEWORK</depend>
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37
38 #include "asterisk/module.h"
39 #include "asterisk/test.h"
40 #include "asterisk/format.h"
41 #include "asterisk/format_cap.h"
42 #include "asterisk/strings.h"
43
44 /*! These are the keys for accessing attributes */
45 enum test_attr_keys {
46         TEST_ATTR_KEY_SAMP_RATE,
47         TEST_ATTR_KEY_STRING,
48 };
49
50 /*! These are the values for the TEST_ATTR_KEY_SAMP_RATE key */
51 enum test_attr_vals_samp {
52         TEST_ATTR_VAL_SAMP_8KHZ  = (1 << 0),
53         TEST_ATTR_VAL_SAMP_12KHZ = (1 << 1),
54         TEST_ATTR_VAL_SAMP_16KHZ = (1 << 2),
55         TEST_ATTR_VAL_SAMP_32KHZ = (1 << 3),
56         TEST_ATTR_VAL_SAMP_48KHZ = (1 << 4),
57 };
58
59 /*! This is the attribute structure used for our test interface. */
60 struct test_attr {
61         enum test_attr_vals_samp samp_flags;
62         char string[32];
63 };
64
65 static enum ast_format_cmp_res test_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
66 {
67         struct test_attr *attr1 = (struct test_attr *) fattr1;
68         struct test_attr *attr2 = (struct test_attr *) fattr2;
69
70         if ((attr1->samp_flags == attr2->samp_flags) &&
71                 !(strcmp(attr1->string, attr2->string))) {
72                 return AST_FORMAT_CMP_EQUAL;
73         }
74         if ((attr1->samp_flags != (attr1->samp_flags & attr2->samp_flags)) ||
75                 (!ast_strlen_zero(attr1->string) && strcmp(attr1->string, attr2->string))) {
76                 return AST_FORMAT_CMP_NOT_EQUAL;
77         }
78         return AST_FORMAT_CMP_SUBSET;
79 }
80
81 static int test_getjoint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
82 {
83         struct test_attr *attr1 = (struct test_attr *) fattr1;
84         struct test_attr *attr2 = (struct test_attr *) fattr2;
85         struct test_attr *attr_res = (struct test_attr *) result;
86         int joint = -1;
87
88         attr_res->samp_flags = (attr1->samp_flags & attr2->samp_flags);
89
90         if (attr_res->samp_flags) {
91                 joint = 0;
92         }
93
94         if (!strcmp(attr1->string, attr2->string)) {
95                 ast_copy_string(attr_res->string, attr1->string, sizeof(attr_res->string));
96                 joint = 0;
97         }
98
99         return joint;
100 }
101
102 static void test_set(struct ast_format_attr *fattr, va_list ap)
103 {
104         enum test_attr_keys key;
105         struct test_attr *attr = (struct test_attr *) fattr;
106         char *string;
107
108         for (key = va_arg(ap, int);
109                 key != AST_FORMAT_ATTR_END;
110                 key = va_arg(ap, int))
111         {
112                 switch (key) {
113                 case TEST_ATTR_KEY_SAMP_RATE:
114                         attr->samp_flags = (va_arg(ap, int) | attr->samp_flags);
115                         break;
116                 case TEST_ATTR_KEY_STRING:
117                         string = va_arg(ap, char *);
118                         if (!ast_strlen_zero(string)) {
119                                 ast_copy_string(attr->string, string, sizeof(attr->string));
120                         }
121                         break;
122                 default:
123                         ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
124                 }
125         }
126 }
127
128 /*! uLaw does not actually have any attributes associated with it.
129  * This is just for the purpose of testing. We are guaranteed there
130  * will never exist a interface for uLaw already. */
131 static struct ast_format_attr_interface test_interface = {
132         .id = AST_FORMAT_TESTLAW,
133         .format_attr_cmp = test_cmp,
134         .format_attr_get_joint = test_getjoint,
135         .format_attr_set = test_set
136 };
137
138 /*!
139  * \internal
140  */
141 AST_TEST_DEFINE(format_test1)
142 {
143         struct ast_format format1 = { 0, };
144         struct ast_format format2 = { 0, };
145         struct ast_format joint = { 0, };
146
147         switch (cmd) {
148         case TEST_INIT:
149                 info->name = "ast_format_test1";
150                 info->category = "/main/format/";
151                 info->summary = "Test ast_format with attributes.";
152                 info->description =
153                         "This test exercises the Ast Format API by creating and registering "
154                         "a custom ast_format_attr_interface and performing various function "
155                         "calls on ast_formats using the interface. ";
156                 return AST_TEST_NOT_RUN;
157         case TEST_EXECUTE:
158                 break;
159         }
160
161         if (ast_format_attr_reg_interface(&test_interface)) {
162                 ast_test_status_update(test, "test_interface failed to register.\n");
163                 return AST_TEST_FAIL;
164         }
165
166         /* set a format with a single attribute. */
167         ast_format_set(&format1, AST_FORMAT_TESTLAW, 1,
168                 TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
169                 AST_FORMAT_ATTR_END);
170         if (ast_format_isset(&format1, TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ, AST_FORMAT_ATTR_END)) {
171                 ast_test_status_update(test, "format1 did not set number attribute correctly.\n");
172                 return AST_TEST_FAIL;
173         }
174         if (!ast_format_isset(&format1, TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_12KHZ, AST_FORMAT_ATTR_END)) {
175                 ast_test_status_update(test, "format1 did not determine isset on number correctly. \n");
176                 return AST_TEST_FAIL;
177         }
178
179         /* append the string attribute to a format with previous attributes already set */
180         ast_format_append(&format1,
181                 TEST_ATTR_KEY_STRING,"String",
182                 AST_FORMAT_ATTR_END);
183         if (ast_format_isset(&format1, TEST_ATTR_KEY_STRING, "String", AST_FORMAT_ATTR_END)) {
184                 ast_test_status_update(test, "format1 did not set string attribute correctly.\n");
185                 return AST_TEST_FAIL;
186         }
187         if (!ast_format_isset(&format1, TEST_ATTR_KEY_STRING, "Not a string", AST_FORMAT_ATTR_END)) {
188                 ast_test_status_update(test, "format1 did not determine isset on string correctly. \n");
189                 return AST_TEST_FAIL;
190         }
191
192         /* set format2 with both STRING and NUMBER at the same time */
193         ast_format_set(&format2, AST_FORMAT_TESTLAW, 1,
194                 TEST_ATTR_KEY_STRING, "MOOOoo",
195                 TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
196                 TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
197                 AST_FORMAT_ATTR_END);
198         /* perform isset with multiple key value pairs. */
199
200         if (ast_format_isset(&format2,
201                         TEST_ATTR_KEY_STRING, "MOOOoo",
202                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
203                         AST_FORMAT_ATTR_END)) {
204
205                 ast_test_status_update(test, "format2 did not set attributes correctly.\n");
206                 return AST_TEST_FAIL;
207         }
208         if (!ast_format_isset(&format2,
209                         TEST_ATTR_KEY_STRING, "WRONG",
210                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
211                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
212                         AST_FORMAT_ATTR_END)) {
213
214                 ast_test_status_update(test, "format2 did not deterine isset correctly.\n");
215                 return AST_TEST_FAIL;
216         }
217
218         /* get joint attributes between format1 and format2. */
219         if (ast_format_joint(&format1, &format2, &joint)) {
220                 ast_test_status_update(test, "failed to get joint attributes.\n");
221                 return AST_TEST_FAIL;
222         }
223         if (ast_format_isset(&joint, TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ, AST_FORMAT_ATTR_END)) {
224                 ast_test_status_update(test, "joint attribute was not what we expected.\n");
225                 return AST_TEST_FAIL;
226         }
227
228         /* exercise compare functions */
229         if (ast_format_cmp(&format1, &format2) != AST_FORMAT_CMP_NOT_EQUAL) {
230                 ast_test_status_update(test, "cmp 1 failed.\n");
231                 return AST_TEST_FAIL;
232         }
233         if (ast_format_cmp(&format1, &format1) != AST_FORMAT_CMP_EQUAL) {
234                 ast_test_status_update(test, "cmp 2 failed.\n");
235                 return AST_TEST_FAIL;
236         }
237         if (ast_format_cmp(&joint, &format1) != AST_FORMAT_CMP_SUBSET) {
238                 ast_test_status_update(test, "cmp 3 failed.\n");
239                 return AST_TEST_FAIL;
240         }
241
242         /* unregister interface */
243         if (ast_format_attr_unreg_interface(&test_interface)) {
244                 ast_test_status_update(test, "test_interface failed to unregister.\n");
245                 return AST_TEST_FAIL;
246         }
247
248         return AST_TEST_PASS;
249 }
250
251 /*!
252  * \internal
253  */
254 AST_TEST_DEFINE(format_test2)
255 {
256         struct ast_format format = { 0, };
257
258         switch (cmd) {
259         case TEST_INIT:
260                 info->name = "ast_format_test2";
261                 info->category = "/main/format/";
262                 info->summary = "Test ast_format unique id and category system";
263                 info->description =
264                         "This test exercises the Ast Format unique id and category "
265                         "system by creating formats of various types and verifying "
266                         "their category matches what we expect.";
267                 return AST_TEST_NOT_RUN;
268         case TEST_EXECUTE:
269                 break;
270         }
271
272         ast_format_set(&format, AST_FORMAT_ULAW, 0);
273         if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_AUDIO) {
274                 ast_test_status_update(test, "audio type failed\n");
275                 return AST_TEST_FAIL;
276         }
277
278         ast_format_set(&format, AST_FORMAT_H264, 0);
279         if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) {
280                 ast_test_status_update(test, "video type failed\n");
281                 return AST_TEST_FAIL;
282         }
283
284         ast_format_set(&format, AST_FORMAT_JPEG, 0);
285         if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_IMAGE) {
286                 ast_test_status_update(test, "image type failed\n");
287                 return AST_TEST_FAIL;
288         }
289
290         ast_format_set(&format, AST_FORMAT_T140, 0);
291         if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_TEXT) {
292                 ast_test_status_update(test, "text type failed\n");
293                 return AST_TEST_FAIL;
294         }
295
296         return AST_TEST_PASS;
297 }
298
299 static int container_test1_helper(struct ast_format_cap *cap1, struct ast_format_cap *cap2, struct ast_test *test)
300 {
301
302         int res = AST_TEST_PASS;
303         struct ast_format_cap *cap_joint = NULL;
304         struct ast_format tmpformat;
305
306         if (ast_format_attr_reg_interface(&test_interface)) {
307                 ast_test_status_update(test, "test_interface failed to register.\n");
308                 ast_format_cap_destroy(cap1);
309                 ast_format_cap_destroy(cap2);
310                 return AST_TEST_FAIL;
311         }
312
313         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
314         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
315         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_G722, 0));
316         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_ALAW, 0));
317         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_H264, 0));
318         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_H263, 0));
319         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_T140, 0));
320         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_JPEG, 0));
321         ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
322                         TEST_ATTR_KEY_STRING, "testing caps hooray",
323                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
324                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
325                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_32KHZ,
326                         AST_FORMAT_ATTR_END));
327
328         /* Test is compatible */
329         if (!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_ALAW, 0)) ||
330                 !ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0)) ||
331                 !ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0)) ||
332                 !ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_H264, 0)) ||
333                 !ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_JPEG, 0)) ||
334                 !ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_T140, 0))) {
335                 ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 1.\n");
336                 res = AST_TEST_FAIL;
337                 goto test3_cleanup;
338         }
339
340         /* Test things that are not compatible */
341         if (ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_SPEEX, 0)) ||
342                 ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_SPEEX16, 0)) ||
343                 ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_H261, 0))) {
344                 ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 2.\n");
345                 res = AST_TEST_FAIL;
346                 goto test3_cleanup;
347         }
348
349         /* Test compatiblity with format with attributes. */
350         if (!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
351                         TEST_ATTR_KEY_STRING, "testing caps hooray",
352                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
353                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
354                         AST_FORMAT_ATTR_END))) {
355
356                 ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 3.\n");
357                 res = AST_TEST_FAIL;
358                 goto test3_cleanup;
359         }
360         if (!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
361                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
362                         AST_FORMAT_ATTR_END))) {
363
364                 ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 4.\n");
365                 res = AST_TEST_FAIL;
366                 goto test3_cleanup;
367         }
368         if (ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
369                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
370                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_48KHZ, /* 48khz was not compatible, so this should fail iscompatible check */
371                         AST_FORMAT_ATTR_END))) {
372
373                 ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 5.\n");
374                 res = AST_TEST_FAIL;
375                 goto test3_cleanup;
376         }
377
378         /* Lets start testing the functions that compare ast_format_cap objects.
379          * Genreate the cap2 object to contain some similar formats as cap1
380          * and some different formats as well. */
381         ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
382         ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
383         ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_SIREN7, 0));
384         ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_H261, 0));
385         ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_T140, 0));
386         ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
387                         TEST_ATTR_KEY_STRING, "testing caps hooray",
388                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
389                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_12KHZ,
390                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
391                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_32KHZ,
392                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_48KHZ,
393                         AST_FORMAT_ATTR_END));
394
395
396         /* find joint formats between cap1 and cap2 */
397         cap_joint = ast_format_cap_joint(cap1, cap2);
398
399         if (!cap_joint) {
400                 ast_test_status_update(test, "failed to create joint capabilities correctly.\n");
401                 res = AST_TEST_FAIL;
402                 goto test3_cleanup;
403         }
404         /* determine if cap_joint is what we think it should be */
405         if (!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0)) ||
406                 !ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0)) ||
407                 !ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_T140, 0)) ||
408                 !ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
409                         TEST_ATTR_KEY_STRING, "testing caps hooray",
410                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
411                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
412                         AST_FORMAT_ATTR_END))) {
413
414                 ast_test_status_update(test, "ast cap_joint failed to properly detect compatibility test 1.\n");
415                 res = AST_TEST_FAIL;
416                 goto test3_cleanup;
417         }
418         /* make sure joint cap does not have formats that should not be there */
419         if (ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_SIREN7, 0)) ||
420                 ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
421                         TEST_ATTR_KEY_STRING, "testing caps hooray",
422                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
423                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
424                         TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_48KHZ,
425                         AST_FORMAT_ATTR_END))) {
426
427                 ast_test_status_update(test, "ast cap_joint failed to properly detect compatibility test 1.\n");
428                 res = AST_TEST_FAIL;
429                 goto test3_cleanup;
430         }
431
432         /* Lets test removing a capability */
433         if (ast_format_cap_remove(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_T140, 0))) {
434                 ast_test_status_update(test, "ast_format_cap_remove failed. \n");
435                 res = AST_TEST_FAIL;
436                 goto test3_cleanup;
437         }
438         /* Lets make sure what we just removed does not still exist */
439         if (ast_format_cap_iscompatible(cap_joint, &tmpformat)) {
440                 ast_test_status_update(test, "ast_format_cap_remove failed 2. \n");
441                 res = AST_TEST_FAIL;
442                 goto test3_cleanup;
443         }
444         /* Lets test removing a capability by id.*/
445         if (ast_format_cap_remove_byid(cap_joint, AST_FORMAT_GSM)) {
446                 ast_test_status_update(test, "ast_format_cap_remove failed 3. \n");
447                 res = AST_TEST_FAIL;
448                 goto test3_cleanup;
449         }
450         /* Lets make sure what we just removed does not still exist */
451         if (ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0))) {
452                 ast_test_status_update(test, "ast_format_cap_remove failed 4. \n");
453                 res = AST_TEST_FAIL;
454                 goto test3_cleanup;
455         }
456
457         /* lets test getting joint formats by type */
458         ast_format_cap_destroy(cap_joint);
459         if (!(cap_joint = ast_format_cap_get_type(cap1, AST_FORMAT_TYPE_VIDEO))) {
460                 ast_test_status_update(test, "ast_format_cap_get_type failed.\n");
461                 res = AST_TEST_FAIL;
462                 goto test3_cleanup;
463         }
464         /* lets make sure our joint capability structure has what we expect */
465         if (!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_H264, 0)) ||
466                 !ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_H263, 0))) {
467                 ast_test_status_update(test, "get_type failed 2.\n");
468                 res = AST_TEST_FAIL;
469                 goto test3_cleanup;
470         }
471         /* now make sure joint does not have anything but video */
472         if (ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_ALAW, 0)) ||
473                 ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0)) ||
474                 ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0)) ||
475                 ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_JPEG, 0)) ||
476                 ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_T140, 0))) {
477                 ast_test_status_update(test, "get_type failed 3.\n");
478                 res = AST_TEST_FAIL;
479                 goto test3_cleanup;
480         }
481
482         /* now lets remove everythign from cap_joint */
483         ast_format_cap_remove_all(cap_joint);
484         if (!ast_format_cap_is_empty(cap_joint)) {
485                 ast_test_status_update(test, "failed to remove all\n");
486                 res = AST_TEST_FAIL;
487                 goto test3_cleanup;
488         }
489
490         /* now lets add all by type */
491         ast_format_cap_add_all_by_type(cap_joint, AST_FORMAT_TYPE_AUDIO);
492         if (ast_format_cap_is_empty(cap_joint)) {
493                         ast_test_status_update(test, "failed to add all by type AUDIO\n");
494                         res = AST_TEST_FAIL;
495         }
496         ast_format_cap_iter_start(cap_joint);
497         while (!(ast_format_cap_iter_next(cap_joint, &tmpformat))) {
498                 if (AST_FORMAT_GET_TYPE(tmpformat.id) != AST_FORMAT_TYPE_AUDIO) {
499                         ast_test_status_update(test, "failed to add all by type AUDIO\n");
500                         res = AST_TEST_FAIL;
501                         ast_format_cap_iter_end(cap_joint);
502                         goto test3_cleanup;
503                 }
504         }
505         ast_format_cap_iter_end(cap_joint);
506
507         /* test append */
508         ast_format_cap_append(cap_joint, cap1);
509         ast_format_cap_iter_start(cap1);
510         while (!(ast_format_cap_iter_next(cap1, &tmpformat))) {
511                 if (!ast_format_cap_iscompatible(cap_joint, &tmpformat)) {
512                         ast_test_status_update(test, "failed to append format capabilities.\n");
513                         res = AST_TEST_FAIL;
514                         ast_format_cap_iter_end(cap1);
515                         goto test3_cleanup;
516                 }
517         }
518         ast_format_cap_iter_end(cap1);
519
520         /* test copy */
521         cap1 = ast_format_cap_destroy(cap1);
522         cap1 = ast_format_cap_dup(cap_joint);
523         if (!ast_format_cap_identical(cap_joint, cap1)) {
524                         ast_test_status_update(test, "failed to copy capabilities\n");
525                         res = AST_TEST_FAIL;
526                         goto test3_cleanup;
527         }
528
529         /* test remove by type */
530         ast_format_cap_remove_bytype(cap_joint, AST_FORMAT_TYPE_AUDIO);
531         if (ast_format_cap_has_type(cap_joint, AST_FORMAT_TYPE_AUDIO)) {
532                 ast_test_status_update(test, "failed to remove all by type audio\n");
533                 res = AST_TEST_FAIL;
534                 goto test3_cleanup;
535         }
536         if (!ast_format_cap_has_type(cap_joint, AST_FORMAT_TYPE_TEXT)) { /* it should still have text */
537                 ast_test_status_update(test, "failed to remove all by type audio\n");
538                 res = AST_TEST_FAIL;
539                 goto test3_cleanup;
540         }
541         ast_format_cap_iter_start(cap_joint);
542         while (!(ast_format_cap_iter_next(cap_joint, &tmpformat))) {
543                 if (AST_FORMAT_GET_TYPE(tmpformat.id) == AST_FORMAT_TYPE_AUDIO) {
544                         ast_test_status_update(test, "failed to remove all by type audio\n");
545                         res = AST_TEST_FAIL;
546                         ast_format_cap_iter_end(cap_joint);
547                         goto test3_cleanup;
548                 }
549         }
550         ast_format_cap_iter_end(cap_joint);
551
552         /* test add all */
553         ast_format_cap_remove_all(cap_joint);
554         ast_format_cap_add_all(cap_joint);
555         {
556                 int video = 0, audio = 0, text = 0, image = 0;
557                 ast_format_cap_iter_start(cap_joint);
558                 while (!(ast_format_cap_iter_next(cap_joint, &tmpformat))) {
559                         switch (AST_FORMAT_GET_TYPE(tmpformat.id)) {
560                         case AST_FORMAT_TYPE_AUDIO:
561                                 audio++;
562                                 break;
563                         case AST_FORMAT_TYPE_VIDEO:
564                                 video++;
565                                 break;
566                         case AST_FORMAT_TYPE_TEXT:
567                                 text++;
568                                 break;
569                         case AST_FORMAT_TYPE_IMAGE:
570                                 image++;
571                                 break;
572                         }
573                 }
574                 ast_format_cap_iter_end(cap_joint);
575                 if (!video || !audio || !text || !image) {
576                         ast_test_status_update(test, "failed to add all\n");
577                         res = AST_TEST_FAIL;
578                         goto test3_cleanup;
579                 }
580         }
581
582         /* test copy2 */
583         ast_format_cap_copy(cap2, cap_joint);
584         if (!ast_format_cap_identical(cap2, cap_joint)) {
585                 ast_test_status_update(test, "ast_format_cap_copy failed\n");
586                 res = AST_TEST_FAIL;
587                 goto test3_cleanup;
588         }
589
590 test3_cleanup:
591         ast_format_cap_destroy(cap1);
592         ast_format_cap_destroy(cap2);
593         ast_format_cap_destroy(cap_joint);
594
595         /* unregister interface */
596         if (ast_format_attr_unreg_interface(&test_interface)) {
597                 ast_test_status_update(test, "test_interface failed to unregister.\n");
598                 res = AST_TEST_FAIL;
599         }
600
601         return res;
602 }
603
604 /*!
605  * \internal
606  */
607 AST_TEST_DEFINE(container_test1_nolock)
608 {
609         struct ast_format_cap *cap1;
610         struct ast_format_cap *cap2;
611
612         switch (cmd) {
613         case TEST_INIT:
614                 info->name = "container_test_1_no_locking";
615                 info->category = "/main/format/";
616                 info->summary = "Test ast_format and ast_format_cap structures, no locking";
617                 info->description =
618                         "This test exercises the Ast Format Capability API by creating "
619                         "capability structures and performing various API calls on them.";
620                 return AST_TEST_NOT_RUN;
621         case TEST_EXECUTE:
622                 break;
623         }
624
625         cap1 = ast_format_cap_alloc_nolock();
626         cap2 = ast_format_cap_alloc_nolock();
627
628         if (!cap1 || !cap2) {
629                 ast_test_status_update(test, "cap alloc failed.\n");
630                 return AST_TEST_FAIL;
631         }
632         return container_test1_helper(cap1, cap2, test);
633 }
634
635
636 /*!
637  * \internal
638  */
639 AST_TEST_DEFINE(container_test1_withlock)
640 {
641         struct ast_format_cap *cap1;
642         struct ast_format_cap *cap2;
643
644         switch (cmd) {
645         case TEST_INIT:
646                 info->name = "container_test1_with_locking";
647                 info->category = "/main/format/";
648                 info->summary = "Test ast_format and ast_format_cap structures, with locking";
649                 info->description =
650                         "This test exercises the Ast Format Capability API by creating "
651                         "capability structures and performing various API calls on them.";
652                 return AST_TEST_NOT_RUN;
653         case TEST_EXECUTE:
654                 break;
655         }
656
657         cap1 = ast_format_cap_alloc();
658         cap2 = ast_format_cap_alloc();
659
660         if (!cap1 || !cap2) {
661                 ast_test_status_update(test, "cap alloc failed.\n");
662                 return AST_TEST_FAIL;
663         }
664         return container_test1_helper(cap1, cap2, test);
665 }
666
667 static int container_test2_no_locking_helper(struct ast_format_cap *cap, struct ast_test *test)
668 {
669         int num = 0;
670         struct ast_format tmpformat = { 0, };
671
672         ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
673         ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
674         ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_G722, 0));
675
676         ast_format_cap_iter_start(cap);
677         while (!ast_format_cap_iter_next(cap, &tmpformat)) {
678                 num++;
679         }
680         ast_format_cap_iter_end(cap);
681
682         ast_format_cap_iter_start(cap);
683         while (!ast_format_cap_iter_next(cap, &tmpformat)) {
684                 num++;
685         }
686         ast_format_cap_iter_end(cap);
687
688         ast_format_cap_destroy(cap);
689         ast_test_status_update(test, "%d items iterated over\n", num);
690         return (num == 6) ? AST_TEST_PASS : AST_TEST_FAIL;
691
692 }
693
694 /*!
695  * \internal
696  */
697 AST_TEST_DEFINE(container_test2_no_locking)
698 {
699         struct ast_format_cap *cap;
700
701         switch (cmd) {
702         case TEST_INIT:
703                 info->name = "container_test2_no_locking";
704                 info->category = "/main/format/";
705                 info->summary = "Test ast_format_cap iterator, no locking";
706                 info->description =
707                         "This test exercises the Ast Capability API iterators.";
708                 return AST_TEST_NOT_RUN;
709         case TEST_EXECUTE:
710                 break;
711         }
712
713         cap = ast_format_cap_alloc_nolock();
714         if (!cap) {
715                 ast_test_status_update(test, "alloc failed\n");
716                 return AST_TEST_FAIL;
717         }
718         return container_test2_no_locking_helper(cap, test);
719 }
720
721 /*!
722  * \internal
723  */
724 AST_TEST_DEFINE(container_test2_with_locking)
725 {
726         struct ast_format_cap *cap;
727
728         switch (cmd) {
729         case TEST_INIT:
730                 info->name = "container_test2_with_locking";
731                 info->category = "/main/format/";
732                 info->summary = "Test ast_format_cap iterator, with locking";
733                 info->description =
734                         "This test exercises the Ast Capability API iterators.";
735                 return AST_TEST_NOT_RUN;
736         case TEST_EXECUTE:
737                 break;
738         }
739
740         cap = ast_format_cap_alloc();
741         if (!cap) {
742                 ast_test_status_update(test, "alloc failed\n");
743                 return AST_TEST_FAIL;
744         }
745         return container_test2_no_locking_helper(cap, test);
746 }
747
748
749 static int container_test3_helper(int nolocking, struct ast_test *test)
750 {
751         int x;
752         int res = AST_TEST_PASS;
753         struct ast_format_cap *cap1;
754         struct ast_format_cap *cap2;
755         struct ast_format_cap *joint;
756
757         for (x = 0; x < 2000; x++) {
758                 if (nolocking) {
759                         cap1 = ast_format_cap_alloc_nolock();
760                         cap2 = ast_format_cap_alloc_nolock();
761                         joint = ast_format_cap_alloc_nolock();
762                 } else {
763                         cap1 = ast_format_cap_alloc();
764                         cap2 = ast_format_cap_alloc();
765                         joint = ast_format_cap_alloc();
766                 }
767                 if (!cap1 || !cap2 || !joint) {
768                         ast_test_status_update(test, "cap alloc fail\n");
769                         return AST_TEST_FAIL;
770                 }
771                 ast_format_cap_add_all(cap1);
772                 ast_format_cap_add_all_by_type(cap2, AST_FORMAT_TYPE_AUDIO);
773                 ast_format_cap_joint_copy(cap1, cap2, joint);
774                 if (!(ast_format_cap_identical(cap2, joint))) {
775                         ast_test_status_update(test, "failed identical test\n");
776                         res = AST_TEST_FAIL;
777                         cap1 = ast_format_cap_destroy(cap1);
778                         cap2 = ast_format_cap_destroy(cap2);
779                         joint = ast_format_cap_destroy(joint);
780                         break;
781                 }
782                 cap1 = ast_format_cap_destroy(cap1);
783                 cap2 = ast_format_cap_destroy(cap2);
784                 joint = ast_format_cap_destroy(joint);
785         }
786         return res;
787 }
788
789 /*!
790  * \internal
791  */
792 AST_TEST_DEFINE(container_test3_nolock)
793 {
794         switch (cmd) {
795         case TEST_INIT:
796                 info->name = "container_test3_no_locking";
797                 info->category = "/main/format/";
798                 info->summary = "Load Test ast_format_cap no locking.";
799                 info->description =
800                         "This test exercises the Ast Capability API and its iterators for the purpose "
801                         "of measuring performance.";
802                 return AST_TEST_NOT_RUN;
803         case TEST_EXECUTE:
804                 break;
805         }
806
807         return container_test3_helper(1, test);
808 }
809
810 /*!
811  * \internal
812  */
813 AST_TEST_DEFINE(container_test3_withlock)
814 {
815         switch (cmd) {
816         case TEST_INIT:
817                 info->name = "container_test3_with_locking";
818                 info->category = "/main/format/";
819                 info->summary = "Load Test ast_format_cap with locking.";
820                 info->description =
821                         "This test exercises the Ast Capability API and its iterators for the purpose "
822                         "of measuring performance.";
823                 return AST_TEST_NOT_RUN;
824         case TEST_EXECUTE:
825                 break;
826         }
827
828         return container_test3_helper(0, test);
829 }
830
831 static int unload_module(void)
832 {
833         AST_TEST_UNREGISTER(format_test1);
834         AST_TEST_UNREGISTER(format_test2);
835         AST_TEST_UNREGISTER(container_test1_nolock);
836         AST_TEST_UNREGISTER(container_test1_withlock);
837         AST_TEST_UNREGISTER(container_test2_no_locking);
838         AST_TEST_UNREGISTER(container_test2_with_locking);
839         AST_TEST_UNREGISTER(container_test3_nolock);
840         AST_TEST_UNREGISTER(container_test3_withlock);
841
842         return 0;
843 }
844
845 static int load_module(void)
846 {
847         AST_TEST_REGISTER(format_test1);
848         AST_TEST_REGISTER(format_test2);
849         AST_TEST_REGISTER(container_test1_nolock);
850         AST_TEST_REGISTER(container_test1_withlock);
851         AST_TEST_REGISTER(container_test2_no_locking);
852         AST_TEST_REGISTER(container_test2_with_locking);
853         AST_TEST_REGISTER(container_test3_nolock);
854         AST_TEST_REGISTER(container_test3_withlock);
855
856         return AST_MODULE_LOAD_SUCCESS;
857 }
858
859 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ast_format API Tests");