Doxygen comment tweaks.
[asterisk/asterisk.git] / tests / test_abstract_jb.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012, Matt Jordan
5  *
6  * Matt Jordan <mjordan@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 Abstract Jitterbuffer Tests
22  *
23  * \author \verbatim Matt Jordan <mjordan@digium.com> \endverbatim
24  *
25  * Tests the abstract jitter buffer API.  This tests both adaptive and fixed
26  * jitter buffers.  Functions defined in abstract_jb that are not part of the
27  * abstract jitter buffer API are not tested by this unit test.
28  *
29  * \ingroup tests
30  */
31
32 /*** MODULEINFO
33         <depend>TEST_FRAMEWORK</depend>
34         <support_level>core</support_level>
35  ***/
36
37 #include "asterisk.h"
38
39 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40
41 #include "asterisk/utils.h"
42 #include "asterisk/module.h"
43 #include "asterisk/test.h"
44 #include "asterisk/abstract_jb.h"
45 #include "asterisk/frame.h"
46
47 #define DEFAULT_FRAME_MS 160
48 #define DEFAULT_CONFIG_FLAGS 0
49 #define DEFAULT_CONFIG_SIZE (DEFAULT_FRAME_MS) * 10
50 #define DEFAULT_CONFIG_RESYNC_THRESHOLD (DEFAULT_FRAME_MS) * 2
51 #define DEFAULT_CONFIG_TARGET_EXTRA -1
52
53 /*!
54  * \internal
55  * \brief Destructor for a jitter buffer
56  *
57  * \param jb The jitter buffer to destroy
58  *
59  * \note This will destroy all frames still in the jitter buffer
60  */
61 static void dispose_jitterbuffer(struct ast_jb *jb)
62 {
63         if (!jb || !jb->impl || !jb->jbobj) {
64                 return;
65         }
66
67         jb->impl->empty_and_reset(jb->jbobj);
68
69         jb->impl->destroy(jb->jbobj);
70         jb->impl = NULL;
71         jb->jbobj = NULL;
72 }
73
74 /*!
75  * \internal
76  * \brief Create a test frame
77  *
78  * \param timestamp the time in ms of the frame
79  * \param seqno the frame's sequence number
80  *
81  * \returns a malloc'd frame
82  */
83 static struct ast_frame *create_test_frame(long timestamp,
84                 int seqno)
85 {
86         struct ast_frame f = {0};
87
88         f.subclass.format.id = AST_FORMAT_SLINEAR;
89         f.frametype = AST_FRAME_VOICE;
90         f.src = "TEST";
91         f.ts = timestamp;
92         f.len = DEFAULT_FRAME_MS;
93         f.seqno = seqno;
94
95         return ast_frisolate(&f);
96 }
97
98 /*! \internal
99  * \brief Test two numeric (long int) values.
100 */
101 #define LONG_INT_TEST(actual, expected) do { \
102         if ((actual) != (expected)) { \
103                 ast_test_status_update(test, #actual ": expected [%ld]; actual [%ld]\n", (long int)(expected), (long int)(actual)); \
104                 return AST_TEST_FAIL; \
105         } } while (0)
106
107 /*! \internal
108  * \brief Test two numeric (int) values.
109 */
110 #define INT_TEST(actual, expected) do { \
111         if ((actual) != (expected)) { \
112                 ast_test_status_update(test, #actual ": expected [%d]; actual [%d]\n", (expected), (actual)); \
113                 return AST_TEST_FAIL; \
114         } } while (0)
115
116 /*! \internal
117  * \brief Test two string values
118 */
119 #define STRING_TEST(actual, expected) do { \
120         if (strcmp((actual), (expected))) { \
121                 ast_test_status_update(test, #actual ": expected [%s]; actual [%s]\n", (expected), (actual)); \
122                 return AST_TEST_FAIL; \
123         } } while (0)
124
125 /*! \internal
126  * \brief Verify that two frames have the same properties
127  */
128 #define VERIFY_FRAME(actual, expected) do { \
129         INT_TEST((actual)->frametype, (expected)->frametype); \
130         INT_TEST((actual)->seqno, (expected)->seqno); \
131         LONG_INT_TEST((actual)->ts, (expected)->ts); \
132         LONG_INT_TEST((actual)->len, (expected)->len); \
133         STRING_TEST((actual)->src, (expected)->src); \
134 } while (0)
135
136 /*! \internal
137  * \brief Get the implementation for a jitter buffer
138  */
139 #define OBTAIN_JITTERBUFFER_IMPL(impl, ast_jb_type, literal_name) do { \
140         (impl) = ast_jb_get_impl((ast_jb_type)); \
141         if (!(impl)) { \
142                 ast_test_status_update(test, "Error: no %s jitterbuffer defined\n", (literal_name)); \
143                 return AST_TEST_FAIL; \
144         } \
145         if (strcmp((impl)->name, (literal_name))) { \
146                 ast_test_status_update(test, "Error: requested %s jitterbuffer and received %s\n", (literal_name), (impl)->name); \
147                 return AST_TEST_FAIL; \
148         } } while (0)
149
150 /*! \internal
151  * \brief Make a jitter buffer configuration object with default values
152  */
153 #define MAKE_DEFAULT_CONFIG(conf, impl) do { \
154         (conf)->flags = DEFAULT_CONFIG_FLAGS; \
155         strcpy((conf)->impl, (impl)->name); \
156         (conf)->max_size = DEFAULT_CONFIG_SIZE; \
157         (conf)->resync_threshold = DEFAULT_CONFIG_RESYNC_THRESHOLD; \
158         (conf)->target_extra = DEFAULT_CONFIG_TARGET_EXTRA; \
159         } while (0)
160
161 /*!
162  * \internal
163  * \brief A container object for the jitter buffers, used for all tests
164  */
165 static struct ast_jb default_jb = {
166         .impl = NULL,
167         .jbobj = NULL
168 };
169
170 /*!
171  * \internal
172  * \brief Construct a test name
173  */
174 #define TEST_NAME(type_name, specifier) type_name ## _  ## specifier
175
176 #define TEST_NAME2(test_name) #test_name
177 #define STRINGIFY_TESTNAME(test_name) TEST_NAME2(test_name)
178
179 /*!
180  * \internal
181  * \brief Test nominal construction of a jitter buffer
182  *
183  * \param type_name The enum type of the jitter buffer to create
184  * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
185  */
186 #define test_create_nominal(type_name, literal_type_name) AST_TEST_DEFINE(TEST_NAME(type_name, create)) {\
187         RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
188         const struct ast_jb_impl *impl; \
189         struct ast_jb_conf conf; \
190 \
191         switch (cmd) { \
192         case TEST_INIT: \
193                 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, create)); \
194                 info->category = "/main/abstract_jb/"; \
195                 info->summary = "Test nominal creation of a " literal_type_name " jitterbuffer"; \
196                 info->description = \
197                         "Tests nominal creation of a " literal_type_name " jitterbuffer using the " \
198                         " jitterbuffer API."; \
199                 return AST_TEST_NOT_RUN; \
200         case TEST_EXECUTE: \
201                 break; \
202         } \
203  \
204         ast_test_status_update(test, "Executing " STRINGIFY_TESTNAME(TEST_NAME(type_name,  create))"...\n"); \
205         OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
206         MAKE_DEFAULT_CONFIG(&conf, impl); \
207  \
208         jb->jbobj = impl->create(&conf); \
209         jb->impl = impl; \
210         if (!jb->jbobj) { \
211                 ast_test_status_update(test, "Error: Failed to adaptive jitterbuffer\n"); \
212                 return AST_TEST_FAIL; \
213         } \
214  \
215         return AST_TEST_PASS; \
216 }
217
218 /*!
219  * \internal
220  * \brief Test putting the initial frame into a jitter buffer
221  *
222  * \param type_name The enum type of the jitter buffer to create
223  * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
224  */
225 #define test_put_first(type_name, literal_type_name) AST_TEST_DEFINE(TEST_NAME(type_name,  put_first)) {\
226         RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
227         const struct ast_jb_impl *impl; \
228         struct ast_jb_conf conf; \
229         RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
230         RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
231         int res; \
232 \
233         switch (cmd) { \
234         case TEST_INIT: \
235                 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name,  put_first)); \
236                 info->category = "/main/abstract_jb/"; \
237                 info->summary = "Test putting a frame into a " literal_type_name " jitterbuffer"; \
238                 info->description = \
239                         "This tests putting a single frame into a " literal_type_name " jitterbuffer " \
240                         "when the jitterbuffer is empty and verifying that it is indeed " \
241                         "the first frame on the jitterbufffer"; \
242                 return AST_TEST_NOT_RUN; \
243         case TEST_EXECUTE: \
244                 break; \
245         } \
246 \
247         ast_test_status_update(test, "Executing " STRINGIFY_TESTNAME(TEST_NAME(type_name,  create))"...\n"); \
248         OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
249         MAKE_DEFAULT_CONFIG(&conf, impl); \
250         jb->jbobj = impl->create(&conf); \
251         jb->impl = impl; \
252         if (!jb->jbobj) { \
253                 ast_test_status_update(test, "Error: Failed to adaptive jitterbuffer\n"); \
254                 return AST_TEST_FAIL; \
255         } \
256 \
257         expected_frame = create_test_frame(1000, 0); \
258         res = jb->impl->put_first(jb->jbobj, \
259                 expected_frame, \
260                 1100); \
261         if (res != AST_JB_IMPL_OK) { \
262                 ast_test_status_update(test, "Error: Got %d back from put_first (expected %d)\n", \
263                         res, AST_JB_IMPL_OK); \
264                 return AST_TEST_FAIL; \
265         } \
266 \
267         res = jb->impl->remove(jb->jbobj, &actual_frame); \
268         if (!actual_frame || res != AST_JB_IMPL_OK) { \
269                 ast_test_status_update(test, "Error: failed to retrieve first frame\n"); \
270                 return AST_TEST_FAIL; \
271         } \
272         expected_frame = create_test_frame(1000, 0); \
273         VERIFY_FRAME(actual_frame, expected_frame); \
274         return AST_TEST_PASS; \
275 }
276
277 /*!
278  * \internal
279  * \brief Test putting a voice frames into a jitter buffer
280  *
281  * \param type_name The enum type of the jitter buffer to create
282  * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
283  */
284 #define test_put(type_name, literal_type_name) AST_TEST_DEFINE(TEST_NAME(type_name, put)) {\
285         RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
286         const struct ast_jb_impl *impl; \
287         struct ast_jb_conf conf; \
288         RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
289         RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
290         int res; \
291         long next; \
292         int i; \
293 \
294         switch (cmd) { \
295         case TEST_INIT: \
296                 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, put)); \
297                 info->category = "/main/abstract_jb/"; \
298                 info->summary = "Test putting frames onto a " literal_type_name " jitterbuffer"; \
299                 info->description = \
300                         "This tests putting multiple frames into a " literal_type_name " jitterbuffer"; \
301                 return AST_TEST_NOT_RUN; \
302         case TEST_EXECUTE: \
303                 break; \
304         } \
305 \
306         ast_test_status_update(test, "Executing "STRINGIFY_TESTNAME(TEST_NAME(type_name, put))"...\n"); \
307         OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
308         MAKE_DEFAULT_CONFIG(&conf, impl); \
309         jb->jbobj = impl->create(&conf); \
310         jb->impl = impl; \
311 \
312         expected_frame = create_test_frame(1000, 0); \
313         jb->impl->put_first(jb->jbobj, expected_frame, 1100); \
314         for (i = 1; i < 10; i++) { \
315                 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
316                 res = jb->impl->put(jb->jbobj, \
317                         expected_frame, \
318                         1100 + i * DEFAULT_FRAME_MS); \
319                 if (res != AST_JB_IMPL_OK) { \
320                         ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
321                                 i, res, AST_JB_IMPL_OK); \
322                         return AST_TEST_FAIL; \
323                 } \
324         } \
325 \
326         for (i = 0; i < 10; i++) { \
327                 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
328                 next = jb->impl->next(jb->jbobj); \
329                 res = jb->impl->get(jb->jbobj, &actual_frame, next, DEFAULT_FRAME_MS); \
330                 if (res != AST_JB_IMPL_OK) { \
331                         ast_test_status_update(test, "Error: failed to retrieve frame %i at time %ld\n", \
332                                 i, next); \
333                         return AST_TEST_FAIL; \
334                 } \
335                 VERIFY_FRAME(actual_frame, expected_frame); \
336                 ast_frfree(expected_frame); \
337                 expected_frame = NULL; \
338         } \
339         return AST_TEST_PASS; \
340 }
341
342 /*!
343  * \internal
344  * \brief Test overflowing the limits of a jitter buffer
345  *
346  * \param type_name The enum type of the jitter buffer to create
347  * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
348  * \param overflow_limit The number of frames at which we expect the buffer to overflow
349  */
350 #define test_put_overflow(type_name, literal_type_name, overflow_limit) AST_TEST_DEFINE(TEST_NAME(type_name, put_overflow)) {\
351         RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
352         const struct ast_jb_impl *impl; \
353         struct ast_jb_conf conf; \
354         RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
355         int res; \
356         int i; \
357 \
358         switch (cmd) { \
359         case TEST_INIT: \
360                 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name,  put_overflow)); \
361                 info->category = "/main/abstract_jb/"; \
362                 info->summary = "Test putting frames onto a " literal_type_name " jitterbuffer " \
363                         "that ends up overflowing the maximum allowed slots in the buffer"; \
364                 info->description = \
365                         "This tests putting multiple frames into a " literal_type_name " jitterbuffer " \
366                         "until the jitterbuffer overflows"; \
367                 return AST_TEST_NOT_RUN; \
368         case TEST_EXECUTE: \
369                 break; \
370         } \
371 \
372         ast_test_status_update(test, "Executing "STRINGIFY_TESTNAME(TEST_NAME(type_name, put_overflow))"...\n"); \
373         OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
374         MAKE_DEFAULT_CONFIG(&conf, impl); \
375         jb->jbobj = impl->create(&conf); \
376         jb->impl = impl; \
377 \
378         expected_frame = create_test_frame(1000, 0); \
379         jb->impl->put_first(jb->jbobj, expected_frame, 1100); \
380         for (i = 1; i <= (overflow_limit); i++) { \
381                 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
382                 res = jb->impl->put(jb->jbobj, \
383                         expected_frame, \
384                         1100 + i * DEFAULT_FRAME_MS); \
385                 if (res != AST_JB_IMPL_OK) { \
386                         ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
387                                 i, res, AST_JB_IMPL_OK); \
388                         return AST_TEST_FAIL; \
389                 } \
390         } \
391 \
392         for (i = (overflow_limit)+1; i < (overflow_limit) + 5; i++) { \
393                 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
394                 res = jb->impl->put(jb->jbobj, \
395                         expected_frame, \
396                         1100 + i * DEFAULT_FRAME_MS); \
397                 if (res != AST_JB_IMPL_DROP) { \
398                         expected_frame = NULL; \
399                         ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
400                                 i, res, AST_JB_IMPL_DROP); \
401                         return AST_TEST_FAIL; \
402                 } \
403                 ast_frfree(expected_frame); \
404                 expected_frame = NULL;\
405         } \
406 \
407         return AST_TEST_PASS; \
408 }
409
410 /*!
411  * \internal
412  * \brief Test putting voice frames into a jitter buffer out of order
413  *
414  * \param type_name The enum type of the jitter buffer to create
415  * \param literal_type_name The literal name of the type - "fixed" or "adaptive"
416  * \param synch_limit The synchronization limit for this particular type of jitter buffer
417  */
418 #define test_put_out_of_order(type_name, literal_type_name, synch_limit) AST_TEST_DEFINE(TEST_NAME(type_name, put_out_of_order)) {\
419         RAII_VAR(struct ast_jb *, jb, &default_jb, dispose_jitterbuffer); \
420         const struct ast_jb_impl *impl; \
421         struct ast_jb_conf conf; \
422         RAII_VAR(struct ast_frame *, actual_frame, NULL, ast_frame_dtor); \
423         RAII_VAR(struct ast_frame *, expected_frame, NULL, ast_frame_dtor); \
424         int res; \
425         long next; \
426         int i; \
427 \
428         switch (cmd) { \
429         case TEST_INIT: \
430                 info->name = STRINGIFY_TESTNAME(TEST_NAME(type_name, put_out_of_order)); \
431                 info->category = "/main/abstract_jb/"; \
432                 info->summary = "Test putting out of order frames onto a " literal_type_name " jitterbuffer"; \
433                 info->description = \
434                         "This tests putting multiple frames into a " literal_type_name " jitterbuffer " \
435                         "that arrive out of order.  Every 3rd frame is put in out of order."; \
436                 return AST_TEST_NOT_RUN; \
437         case TEST_EXECUTE: \
438                 break; \
439         } \
440 \
441         ast_test_status_update(test, "Executing " STRINGIFY_TESTNAME(TEST_NAME(type_name, put_out_of_order)) "...\n"); \
442         OBTAIN_JITTERBUFFER_IMPL(impl, (type_name), (literal_type_name)); \
443         MAKE_DEFAULT_CONFIG(&conf, impl); \
444         conf.resync_threshold = (synch_limit); \
445         jb->jbobj = impl->create(&conf); \
446         jb->impl = impl; \
447 \
448         expected_frame = create_test_frame(1000, 0); \
449         jb->impl->put_first(jb->jbobj, expected_frame, 1100); \
450         for (i = 1; i <= 10; i++) { \
451                 if (i % 3 == 1 && i != 10) { \
452                         expected_frame = create_test_frame(1000 + ((i + 1) * DEFAULT_FRAME_MS), 0); \
453                 } else if (i % 3 == 2) { \
454                         expected_frame = create_test_frame(1000 + ((i - 1) * DEFAULT_FRAME_MS), 0); \
455                 } else { \
456                         expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
457                 } \
458                 res = jb->impl->put(jb->jbobj, \
459                         expected_frame, \
460                         1100 + i * DEFAULT_FRAME_MS); \
461                 if (res != AST_JB_IMPL_OK) { \
462                         ast_test_status_update(test, "Error: On frame %d, got %d back from put (expected %d)\n", \
463                                 i, res, AST_JB_IMPL_OK); \
464                         return AST_TEST_FAIL; \
465                 } \
466         } \
467 \
468         for (i = 0; i <= 10; i++) { \
469                 expected_frame = create_test_frame(1000 + i * DEFAULT_FRAME_MS, 0); \
470                 next = jb->impl->next(jb->jbobj); \
471                 res = jb->impl->get(jb->jbobj, &actual_frame, next, DEFAULT_FRAME_MS); \
472                 if (res != AST_JB_IMPL_OK) { \
473                         ast_test_status_update(test, "Error: failed to retrieve frame at %ld\n", \
474                                 next); \
475                         return AST_TEST_FAIL; \
476                 } \
477                 VERIFY_FRAME(actual_frame, expected_frame); \
478                 ast_frfree(expected_frame); \
479                 expected_frame = NULL; \
480         } \
481 \
482         return AST_TEST_PASS; \
483 }
484
485
486 test_create_nominal(AST_JB_ADAPTIVE, "adaptive")
487
488 test_put_first(AST_JB_ADAPTIVE, "adaptive")
489
490 test_put(AST_JB_ADAPTIVE, "adaptive")
491
492 test_put_overflow(AST_JB_ADAPTIVE, "adaptive", 10)
493
494 test_put_out_of_order(AST_JB_ADAPTIVE, "adaptive", DEFAULT_FRAME_MS * 2)
495
496 test_create_nominal(AST_JB_FIXED, "fixed")
497
498 test_put_first(AST_JB_FIXED, "fixed")
499
500 test_put(AST_JB_FIXED, "fixed")
501
502 test_put_overflow(AST_JB_FIXED, "fixed", 12)
503
504 test_put_out_of_order(AST_JB_FIXED, "fixed", DEFAULT_CONFIG_RESYNC_THRESHOLD)
505
506 static int unload_module(void)
507 {
508         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_ADAPTIVE, create));
509         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_first));
510         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_ADAPTIVE, put));
511         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_overflow));
512         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_out_of_order));
513
514         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_FIXED, create));
515         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_FIXED, put_first));
516         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_FIXED, put));
517         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_FIXED, put_overflow));
518         AST_TEST_UNREGISTER(TEST_NAME(AST_JB_FIXED, put_out_of_order));
519
520         return 0;
521 }
522
523 static int load_module(void)
524 {
525         AST_TEST_REGISTER(TEST_NAME(AST_JB_ADAPTIVE, create));
526         AST_TEST_REGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_first));
527         AST_TEST_REGISTER(TEST_NAME(AST_JB_ADAPTIVE, put));
528         AST_TEST_REGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_overflow));
529         AST_TEST_REGISTER(TEST_NAME(AST_JB_ADAPTIVE, put_out_of_order));
530
531         AST_TEST_REGISTER(TEST_NAME(AST_JB_FIXED, create));
532         AST_TEST_REGISTER(TEST_NAME(AST_JB_FIXED, put_first));
533         AST_TEST_REGISTER(TEST_NAME(AST_JB_FIXED, put));
534         AST_TEST_REGISTER(TEST_NAME(AST_JB_FIXED, put_overflow));
535         AST_TEST_REGISTER(TEST_NAME(AST_JB_FIXED, put_out_of_order));
536
537         return AST_MODULE_LOAD_SUCCESS;
538 }
539
540 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Abstract JitterBuffer API Tests");