[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