[asterisk-commits] branch group/testframework r16470 - in /team/group/testframework: ./ include/...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Mar 29 22:54:45 MST 2006


Author: russell
Date: Wed Mar 29 23:54:42 2006
New Revision: 16470

URL: http://svn.digium.com/view/asterisk?rev=16470&view=rev
Log: (empty)

Added:
    team/group/testframework/codetest.c   (with props)
    team/group/testframework/include/asterisk/codetest.h   (with props)
Modified:
    team/group/testframework/   (props changed)
    team/group/testframework/Makefile

Propchange: team/group/testframework/
            ('branch-1.2-blocked' removed)

Propchange: team/group/testframework/
            ('branch-1.2-merged' removed)

Modified: team/group/testframework/Makefile
URL: http://svn.digium.com/view/asterisk/team/group/testframework/Makefile?rev=16470&r1=16469&r2=16470&view=diff
==============================================================================
--- team/group/testframework/Makefile (original)
+++ team/group/testframework/Makefile Wed Mar 29 23:54:42 2006
@@ -169,6 +169,9 @@
 # Determine by a grep 'ScriptAlias' of your httpd.conf file
 HTTP_CGIDIR=/var/www/cgi-bin
 
+# Uncomment the following to enable code testing code to be enabled :)
+ASTCFLAGS+=-DENABLE_CODE_TEST
+
 # If the file .asterisk.makeopts is present in your home directory, you can
 # include all of your favorite Makefile options so that every time you download
 # a new version of Asterisk, you don't have to edit the makefile to set them. 
@@ -365,6 +368,10 @@
 	utils.o plc.o jitterbuf.o dnsmgr.o devicestate.o \
 	netsock.o slinfactory.o ast_expr2.o ast_expr2f.o \
 	cryptostub.o sha1.o http.o
+
+ifeq ($(findstring -DENABLE_CODE_TEST,$(ASTCFLAGS)),-DENABLE_CODE_TEST)
+  OBJS+= codetest.o
+endif
 
 # we need to link in the objects statically, not as a library, because
 # otherwise modules will not have them available if none of the static

Added: team/group/testframework/codetest.c
URL: http://svn.digium.com/view/asterisk/team/group/testframework/codetest.c?rev=16470&view=auto
==============================================================================
--- team/group/testframework/codetest.c (added)
+++ team/group/testframework/codetest.c Wed Mar 29 23:54:42 2006
@@ -1,0 +1,378 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2005, Russell Bryant
+ *
+ * Russell Bryant <russell at digium.com>
+ *
+ * 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 Code Testing Framework
+ *
+ * \author Russell Bryant <russell at digium.com> 
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/channel.h"
+#include "asterisk/logger.h"
+#include "asterisk/cli.h"
+#include "asterisk/codetest.h"
+
+/*!
+  \brief A file that has registered tests
+
+  We store all registered tests by keeping track of whick file has
+  registered each test.
+*/
+struct testfile {
+	/*! The name of the file that has a list of registered tests */
+	const char *filename;
+	/*! The list of tests registered by this file */
+	AST_LIST_HEAD_NOLOCK(, ast_codetest) codetests;
+	/*! Link testfile's together */
+	AST_LIST_ENTRY(testfile) list;
+};
+
+/*! The list of testfile structures */
+static AST_LIST_HEAD_STATIC(testfile_list, testfile);
+
+/* Prototypes for non-exported functions */
+struct testfile *find_testfile_by_name(const char *filename);
+static struct testfile *add_testfile(struct ast_codetest *test);
+static int count_tests(struct testfile *tf);
+static int handle_cli_show_files(int fd, int argc, char *argv[]);
+static int handle_cli_show_file(int fd, int argc, char *argv[]);
+static char *complete_testfiles(char *line, char *word, int pos, int state);
+static char *complete_cli_show_file(char *line, char *word, int pos, int state);
+static void check_test_result(int fd, struct ast_codetest *test, int res);
+static int handle_cli_run(int fd, int argc, char *argv[]);
+static char *complete_tests(char *line, char *word, int pos, int state);
+static char *complete_cli_run(char *line, char *word, int pos, int state);
+
+/*!
+  \brief Add a test to the list of tests for a file
+
+  \note This function is to be called with the testfile_list locked
+*/
+static struct testfile *add_testfile(struct ast_codetest *test)
+{
+	struct testfile *tf;
+
+	tf = calloc(1, sizeof(struct testfile));
+	if (!tf) {
+		ast_log(LOG_ERROR, "Memory Allocation Error!\n");
+		return NULL;
+	}
+	tf->filename = test->filename;
+	AST_LIST_INSERT_HEAD(&testfile_list, tf, list);
+
+	return tf;
+}
+
+/*! 
+  \brief search the list of files that have registered tests
+
+  \note This function is to be called with the testfile_list locked
+*/
+struct testfile *find_testfile_by_name(const char *filename)
+{
+	struct testfile *cur;
+
+	AST_LIST_TRAVERSE(&testfile_list, cur, list) {
+		if (!strcmp(cur->filename, filename))
+			break;
+	}
+
+	return cur;
+}
+
+int ast_register_codetest(struct ast_codetest *test)
+{
+	struct testfile *cur;
+
+	AST_LIST_LOCK(&testfile_list);
+	cur = find_testfile_by_name(test->filename);
+	if (!cur)
+		cur = add_testfile(test);
+	if (!cur) {
+		AST_LIST_UNLOCK(&testfile_list);
+		return -1;
+	}
+	AST_LIST_INSERT_HEAD(&cur->codetests, test, list);
+	AST_LIST_UNLOCK(&testfile_list);
+
+	return 0;
+}
+
+int ast_unregister_codetest(struct ast_codetest *test)
+{
+	struct testfile *cur;
+
+	AST_LIST_LOCK(&testfile_list);
+	if (!(cur = find_testfile_by_name(test->filename))) {
+		ast_log(LOG_WARNING, "File '%s' not found in list of files with registered tests!\n", test->filename);
+		AST_LIST_UNLOCK(&testfile_list);
+		return -1;
+	}
+	AST_LIST_REMOVE(&cur->codetests, test, list);
+	if (AST_LIST_EMPTY(&cur->codetests)) {
+		AST_LIST_REMOVE(&testfile_list, cur, list);
+		free(cur);
+	}
+	AST_LIST_UNLOCK(&testfile_list);
+
+	return 0;
+}
+
+/*!
+  \brief Count how many tests are registered by a file
+
+  \note This function is to be called with the testfile_list locked
+*/
+static int count_tests(struct testfile *tf)
+{
+	struct ast_codetest *cur;
+	int count = 0;
+
+	AST_LIST_TRAVERSE(&tf->codetests, cur, list)
+		count++;
+
+	return count;
+}
+
+static int handle_cli_show_files(int fd, int argc, char *argv[])
+{
+	struct testfile *cur;
+	int count;
+
+	ast_cli(fd, "Files with Registered Code Tests\n");
+	ast_cli(fd, "--------------------------------\n");
+
+	AST_LIST_LOCK(&testfile_list);
+	AST_LIST_TRAVERSE(&testfile_list, cur, list) {
+		count = count_tests(cur);
+		ast_cli(fd, "Filename: '%s'  (%d %s)\n", cur->filename, count, count > 1 ? "tests" : "test");
+	}
+	AST_LIST_UNLOCK(&testfile_list);
+
+	return RESULT_SUCCESS;
+}
+
+static struct ast_cli_entry cli_show_files = {
+	.cmda = { "codetest", "show", "files", NULL },
+	.handler = handle_cli_show_files,
+	.summary = "Show files with registered code tests",
+	.usage =
+	"Usage: codetest show files\n"
+	"       This command will list all files that have registered code tests.\n"
+};
+
+static int handle_cli_show_file(int fd, int argc, char *argv[])
+{
+	struct testfile *cur;
+	struct ast_codetest *test;
+	int count = 0;
+
+	if (argc != 4)
+		return RESULT_SHOWUSAGE;
+
+	AST_LIST_LOCK(&testfile_list);
+	if (!(cur = find_testfile_by_name(argv[3]))) {
+		ast_cli(fd, "File '%s' not found in list of files with registered code tests!\n", argv[3]);
+		AST_LIST_UNLOCK(&testfile_list);
+		return RESULT_SHOWUSAGE;
+	}
+	ast_cli(fd, "Registered Code Tests for File '%s'\n", cur->filename);
+	ast_cli(fd, "---------------------------------------------\n");
+	AST_LIST_TRAVERSE(&cur->codetests, test, list) {
+		count++;
+		ast_cli(fd, "Test Name: '%s'\n", test->testname);
+	}
+	ast_cli(fd, "\n(Total Tests Registered: %d)\n", count);
+	AST_LIST_UNLOCK(&testfile_list);
+
+	return RESULT_SUCCESS;
+}
+
+static char *complete_testfiles(char *line, char *word, int pos, int state)
+{
+	struct testfile *cur;
+	int match = 0;
+	int wordlen = strlen(word);
+	char *file = NULL;
+
+	AST_LIST_LOCK(&testfile_list);
+	AST_LIST_TRAVERSE(&testfile_list, cur, list) {	
+		if (!strncasecmp(word, cur->filename, wordlen) && ++match > state) {
+			file = strdup(cur->filename);
+			break;
+		}
+	}
+	AST_LIST_UNLOCK(&testfile_list);
+
+	return file;
+
+}
+
+static char *complete_cli_show_file(char *line, char *word, int pos, int state)
+{
+	if (pos != 3) 
+		return NULL;
+
+	return complete_testfiles(line, word, pos, state);	
+}
+
+static struct ast_cli_entry cli_show_file = {
+	.cmda = { "codetest", "show", "file", NULL },
+	.handler = handle_cli_show_file,
+	.generator = complete_cli_show_file,
+	.summary = "Show registered code tests for a given file.",
+	.usage =
+	"Usage: codetest show file <file>\n"
+	"       This command will list all registered code tests for a file.\n"
+};
+
+static void check_test_result(int fd, struct ast_codetest *test, int res)
+{
+	if (res)
+		ast_cli(fd, "Test '%s' *** FAILED *** for File '%s' !!!\n", test->testname, test->filename);
+	else
+		ast_cli(fd, "Test '%s' PASSED for File '%s' !!!\n", test->testname, test->filename);
+}
+
+static int handle_cli_run(int fd, int argc, char *argv[])
+{
+	struct testfile *tf;
+	struct ast_codetest *test;
+	char *testname = NULL;
+	int res = 0;
+	int test_executed = 0;
+	int test_argc = 0;
+	char **test_argv = NULL;
+
+	if (argc > 3) {
+		testname = argv[3];
+		if (argc > 4) {
+			test_argc = argc - 4;
+			test_argv = argv + 4;	
+		}	
+	} else
+		return RESULT_SHOWUSAGE;
+
+	AST_LIST_LOCK(&testfile_list);
+	if (!(tf = find_testfile_by_name(argv[2]))) {
+		ast_cli(fd, "File '%s' not found in list of files with code tests.\n", argv[2]);
+		AST_LIST_UNLOCK(&testfile_list);
+		return RESULT_SHOWUSAGE;
+	}
+	AST_LIST_TRAVERSE(&tf->codetests, test, list) {
+		if (!ast_strlen_zero(testname)) {
+			if (!strcmp(test->testname, testname)) {
+				ast_cli(fd, "Executing test '%s' for file '%s' ...\n", test->testname, test->filename);
+				res = test->codetest(fd, test_argc, test_argv);
+				check_test_result(fd, test, res);
+				test_executed = 1;
+				break;
+			}
+		} else {
+			ast_cli(fd, "Executing test '%s' for file '%s' ...\n", test->testname, test->filename);
+			res = test->codetest(fd, test_argc, test_argv);
+			check_test_result(fd, test, res);
+			test_executed = 1;
+		}
+	}
+	AST_LIST_UNLOCK(&testfile_list);
+
+	if (!test_executed && !ast_strlen_zero(testname)) {
+		ast_cli(fd, "Test '%s' not found for file '%s'!\n", testname, argv[2]);
+		return RESULT_FAILURE;
+	}
+
+	return RESULT_SUCCESS;
+}
+
+static char *complete_tests(char *line, char *word, int pos, int state)
+{
+	char *file;
+	char *ret = NULL;
+	struct ast_codetest *test;
+	struct testfile *tf;
+	int match = 0;
+	int wordlen = strlen(word);
+
+	if (!(file = ast_strdupa(line))) {
+		ast_log(LOG_ERROR, "Memory Allocation Error!\n");
+		return NULL;
+	}
+
+	strsep(&file, " ");
+	strsep(&file, " ");
+	file = strsep(&file, " ");
+
+	AST_LIST_LOCK(&testfile_list);
+	if (!(tf = find_testfile_by_name(file))) {
+		AST_LIST_UNLOCK(&testfile_list);
+		return NULL;
+	}
+	AST_LIST_TRAVERSE(&tf->codetests, test, list) {
+		if (!strncasecmp(word, test->filename, wordlen) && ++match > state) {
+			ret = strdup(test->filename);
+			break;
+		}
+	}	
+	AST_LIST_UNLOCK(&testfile_list);
+
+	return ret;
+}
+
+static char *complete_cli_run(char *line, char *word, int pos, int state)
+{
+	if (pos == 2)
+		return complete_testfiles(line, word, pos, state);
+	else if (pos == 3)
+		/* XXX Why isn't this being executed ?! XXX */
+		return complete_tests(line, word, pos, state);
+
+	return NULL;
+}
+
+static struct ast_cli_entry cli_run = {
+	.cmda = { "codetest", "run", NULL },
+	.handler = handle_cli_run,
+	.generator = complete_cli_run,
+	.summary = "Run code test(s) for a file.",
+	.usage =
+	"Usage: codetest run <file> [test]\n"
+	"       This command will run registered code tests for a file.\n"
+	"       If a test is specified, only that test will be executed.\n"
+	"       Otherwise, all available tests will be executed.\n"
+};
+
+int codetest_init(void)
+{
+	int res;	
+
+	res = ast_cli_register(&cli_show_files);
+	res |= ast_cli_register(&cli_show_file);
+	res |= ast_cli_register(&cli_run);
+
+	return res;
+}

Propchange: team/group/testframework/codetest.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/testframework/codetest.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/group/testframework/codetest.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/group/testframework/include/asterisk/codetest.h
URL: http://svn.digium.com/view/asterisk/team/group/testframework/include/asterisk/codetest.h?rev=16470&view=auto
==============================================================================
--- team/group/testframework/include/asterisk/codetest.h (added)
+++ team/group/testframework/include/asterisk/codetest.h Wed Mar 29 23:54:42 2006
@@ -1,0 +1,91 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Russell Bryant <russell at digium.com>
+ *
+ * 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 Code Testing Definitions
+ *
+ * \author Russell Bryant <russell at digium.com>
+ */
+
+#ifndef __ASTERISK_CODETEST_H
+#define __ASTERISK_CODETEST_H
+
+#ifdef ENABLE_CODE_TEST
+
+#include "asterisk/linkedlists.h"
+
+/*!
+  \brief A Code Test
+
+  This is declared in a file using AST_DEFINE_CODE_TEST
+*/
+struct ast_codetest {
+	/*! The file that registered this test */
+	const char *filename;
+	/*! The name of the test */
+	const char *testname;
+	/*! The codetest callback function */
+	int (*codetest)(int fd, int argc, char *argv[]);
+	/*! For linking, used only in codetest.c */
+	AST_LIST_ENTRY(ast_codetest) list;
+};
+
+/*!
+  \brief Define a Code Test
+  \param name  This is the name that will be used to refer to the test when
+               calling the register/unregister functions
+  \param tname This is the text name of the test.  It will be the name that
+               is used to refer to the test at the CLI.
+  \param func  This is the callback for the test, which will be stored in the
+               member 'codetest' in the ast_codetest structure.
+*/
+#define AST_DEFINE_CODE_TEST(name, tname, func) \
+	static struct ast_codetest name = { __FILE__, tname, func }
+
+/*!
+  \brief Reigster a Code Test
+  \param test The test to register.
+
+  If the code test was defined using the following macro:
+	AST_DEFINE_CODE_TEST(my_test, "my-test", my_test_handler);
+  Then, this function would be called like:
+	ast_register_codetest(&my_test);
+*/
+int ast_register_codetest(struct ast_codetest *test);
+
+/*!
+  \brief Unreigster a Code Test
+  \param test The test to unregister.
+
+  If the code test was defined using the following macro:
+	AST_DEFINE_CODE_TEST(my_test, "my-test", my_test_handler);
+  Then, this function would be called like:
+	ast_unregister_codetest(&my_test);
+*/
+int ast_unregister_codetest(struct ast_codetest *test);
+
+#else
+
+#define ast_register_codetest(f)
+#define ast_unregister_codetest(f)
+#define AST_DEFINE_CODE_TEST(name, testname, func)
+
+#endif
+
+#endif /* __ASTERISK_CODETEST_H */

Propchange: team/group/testframework/include/asterisk/codetest.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/testframework/include/asterisk/codetest.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/group/testframework/include/asterisk/codetest.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain



More information about the asterisk-commits mailing list