[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