[asterisk-commits] mjordan: branch mjordan/trunk_jitter_tests r358728 - /team/mjordan/trunk_jitt...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Mar 9 16:28:50 CST 2012
Author: mjordan
Date: Fri Mar 9 16:28:46 2012
New Revision: 358728
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=358728
Log:
Add test_jitterbuffer.c
Add the actual unit test module that this branch exists for
Added:
team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c (with props)
Added: team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c?view=auto&rev=358728
==============================================================================
--- team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c (added)
+++ team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c Fri Mar 9 16:28:46 2012
@@ -1,0 +1,506 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) <Year>, <Your Name Here>
+ *
+ * <Your Name Here> <<Your Email Here>>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Skeleton Test
+ *
+ * \author\verbatim <Your Name Here> <<Your Email Here>> \endverbatim
+ *
+ * This is a skeleton for development of an Asterisk test module
+ * \ingroup tests
+ */
+
+/*** MODULEINFO
+ <depend>TEST_FRAMEWORK</depend>
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/utils.h"
+#include "asterisk/module.h"
+#include "asterisk/test.h"
+#include "jitterbuf.h"
+
+#define DEFAULT_MAX_JITTERBUFFER 1000
+#define DEFAULT_RESYNCH_THRESHOLD 1000
+#define DEFAULT_MAX_CONTIG_INTERP 10
+#define DEFAULT_TARGET_EXTRA -1
+#define DEFAULT_CODEC_INTERP_LEN 20
+
+static const char *jitter_buffer_return_codes[] = {
+ "JB_OK", /* 0 */
+ "JB_EMPTY", /* 1 */
+ "JB_NOFRAME", /* 2 */
+ "JB_INTERP", /* 3 */
+ "JB_DROP", /* 4 */
+ "JB_SCHED" /* 5 */
+};
+
+static void test_jb_populate_config(struct jb_conf *jbconf)
+{
+ if (!jbconf) {
+ return;
+ }
+
+ jbconf->max_jitterbuf = DEFAULT_MAX_JITTERBUFFER;
+ jbconf->resync_threshold = DEFAULT_RESYNCH_THRESHOLD;
+ jbconf->max_contig_interp = DEFAULT_MAX_CONTIG_INTERP;
+ jbconf->target_extra = 0;
+}
+
+AST_TEST_DEFINE(jitterbuffer_nominal_audio_frames)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_nominal_audio_frames";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Nominal operation of jitterbuffer with audio data";
+ info->description =
+ "Tests putting audio data into a jitterbuffer with no out"
+ "of order frames.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (jb_put(jb, NULL, JB_TYPE_VOICE, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ /* We should have a frame for each point in time */
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ if (frame.ms != 20) {
+ ast_test_status_update(test,
+ "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
+ goto cleanup;
+ }
+ if (frame.ts != i * 20 - jb->info.resync_offset) {
+ ast_test_status_update(test,
+ "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
+ goto cleanup;
+ }
+ }
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_nominal_control_frames)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_nominal_control_frames";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Nominal operation of jitterbuffer with control frames";
+ info->description =
+ "Tests putting control frames into a jitterbuffer with no out"
+ "of order frames.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ /* We should have a frame for each point in time */
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ if (frame.ms != 20) {
+ ast_test_status_update(test,
+ "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
+ goto cleanup;
+ }
+ if (frame.ts != i * 20 - jb->info.resync_offset) {
+ ast_test_status_update(test,
+ "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
+ goto cleanup;
+ }
+ }
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_out_of_order)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_info jbinfo;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_out_of_order";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests sending out of order frames to a jitterbuffer";
+ info->description =
+ "Every 5th frame sent to a jitter buffer is reversed with the previous"
+ "frame. The expected result is to have a jitter buffer with the frames"
+ "in order, while a total of 10 frames should be out of order.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (i % 4 == 0) {
+ /* Add 5th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, (i + 1) * 20, (i + 1) * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", (i+1));
+ goto cleanup;
+ }
+ /* Add 4th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ i++;
+ } else {
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ /* We should have a frame for each point in time */
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ if (frame.ms != 20) {
+ ast_test_status_update(test,
+ "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
+ goto cleanup;
+ }
+ if (frame.ts != i * 20 - jb->info.resync_offset) {
+ ast_test_status_update(test,
+ "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
+ goto cleanup;
+ }
+ }
+
+ if (jb_getinfo(jb, &jbinfo) != JB_OK) {
+ ast_test_status_update(test, "Failed to get jitterbuffer information\n");
+ goto cleanup;
+ }
+ if (jbinfo.frames_ooo != 10) {
+ ast_test_status_update(test, "Out of order frames: expected [%d]; actual [%ld]\n", 10, jbinfo.frames_ooo);
+ }
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_lost)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_info jbinfo;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_lost";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests missing frames in the jitterbuffer";
+ info->description =
+ "Every 5th frame that would be sent to a jitter buffer is instead"
+ "dropped. The jitterbuffer is expected to interpolate every 5th"
+ "frame. A total of 10 frames should be lost.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (i % 5 == 0) {
+ i++;
+ }
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ /* If we didn't get an OK, make sure that it was an expected lost frame */
+ if (!(ret == JB_NOFRAME && i % 5 == 0)) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ } else {
+ if (frame.ms != 20) {
+ ast_test_status_update(test,
+ "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
+ goto cleanup;
+ }
+ if (frame.ts != i * 20 - jb->info.resync_offset) {
+ ast_test_status_update(test,
+ "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
+ goto cleanup;
+ }
+ }
+ }
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+ return result;
+}
+
+AST_TEST_DEFINE(jitterbuffer_late)
+{
+ enum ast_test_result_state result = AST_TEST_FAIL;
+ struct jitterbuf *jb = NULL;
+ struct jb_frame frame;
+ struct jb_info jbinfo;
+ struct jb_conf jbconf;
+ int i;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "jitterbuffer_late";
+ info->category = "/main/jitterbuffer/";
+ info->summary = "Tests sending frames to a jitterbuffer that are late";
+ info->description =
+ "Every 5th frame sent to a jitter buffer is put into the jitterbuffer just"
+ "prior to the arrival of the 6th frame. The expected result is to have a";
+ /* TODO: */
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(jb = jb_new())) {
+ ast_test_status_update(test, "Failed to allocate memory for jitterbuffer\n");
+ goto cleanup;
+ }
+
+ test_jb_populate_config(&jbconf);
+ if (jb_setconf(jb, &jbconf) != JB_OK) {
+ ast_test_status_update(test, "Failed to set jitterbuffer configuration\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < 40; i++) {
+ if (i % 4 == 0) {
+ /* Add 5th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, (i + 1) * 20, (i + 1) * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", (i+1));
+ goto cleanup;
+ }
+ /* Add 4th frame */
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ i++;
+ } else {
+ if (jb_put(jb, NULL, JB_TYPE_CONTROL, 20, i * 20, i * 20 + 5) == JB_DROP) {
+ ast_test_status_update(test, "Jitter buffer dropped packet %d\n", i);
+ goto cleanup;
+ }
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ enum jb_return_code ret;
+ /* We should have a frame for each point in time */
+ if ((ret = jb_get(jb, &frame, i * 20 + 5, DEFAULT_CODEC_INTERP_LEN)) != JB_OK) {
+ ast_test_status_update(test,
+ "Unexpected jitter buffer return code [%s] when retrieving frame %d\n",
+ jitter_buffer_return_codes[ret], i);
+ goto cleanup;
+ }
+ if (frame.ms != 20) {
+ ast_test_status_update(test,
+ "Unexpected ms value [%ld] on frame %d - expected %d\n", frame.ms, i, 20);
+ goto cleanup;
+ }
+ if (frame.ts != i * 20 - jb->info.resync_offset) {
+ ast_test_status_update(test,
+ "Unexpected ts value [%ld] on frame %d - expected %ld\n", frame.ts, i, i * 20 - jb->info.resync_offset);
+ goto cleanup;
+ }
+ }
+
+ if (jb_getinfo(jb, &jbinfo) != JB_OK) {
+ ast_test_status_update(test, "Failed to get jitterbuffer information\n");
+ goto cleanup;
+ }
+ if (jbinfo.frames_ooo != 10) {
+ ast_test_status_update(test, "Out of order frames: expected [%d]; actual [%ld]\n", 10, jbinfo.frames_ooo);
+ }
+
+ result = AST_TEST_PASS;
+
+cleanup:
+ if (jb) {
+ /* No need to do anything - this will put all frames on the 'free' list,
+ * so jb_destroy will dispose of them */
+ while (jb_getall(jb, &frame) == JB_OK) { }
+ jb_destroy(jb);
+ }
+ return result;
+}
+
+static int unload_module(void)
+{
+ AST_TEST_UNREGISTER(jitterbuffer_nominal_audio_frames);
+ AST_TEST_UNREGISTER(jitterbuffer_nominal_control_frames);
+ AST_TEST_UNREGISTER(jitterbuffer_out_of_order);
+ AST_TEST_UNREGISTER(jitterbuffer_lost);
+ AST_TEST_REGISTER(jitterbuffer_late);
+ return 0;
+}
+
+static int load_module(void)
+{
+ AST_TEST_REGISTER(jitterbuffer_nominal_audio_frames);
+ AST_TEST_REGISTER(jitterbuffer_nominal_control_frames);
+ AST_TEST_REGISTER(jitterbuffer_out_of_order);
+ AST_TEST_REGISTER(jitterbuffer_lost);
+ AST_TEST_REGISTER(jitterbuffer_late);
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Jitterbuffer Test");
Propchange: team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/mjordan/trunk_jitter_tests/tests/test_jitterbuffer.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list