diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-06-28 18:34:18 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-06-28 18:34:18 +0000 |
commit | 4b7b8dd790147d834373bef43b57034fcec3d1a0 (patch) | |
tree | 5f64d6331a0260404d5b6d96513d0c28bb76b770 /include | |
parent | 3894ede3a1a894660486867ee5af813d25d9aa6b (diff) |
Backport unit test API to 1.4.
Review: https://reviewboard.asterisk.org/r/750/
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@272878 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r-- | include/asterisk.h | 1 | ||||
-rw-r--r-- | include/asterisk/linkedlists.h | 30 | ||||
-rw-r--r-- | include/asterisk/test.h | 215 |
3 files changed, 246 insertions, 0 deletions
diff --git a/include/asterisk.h b/include/asterisk.h index 1f6c2c723..e54b9b6a8 100644 --- a/include/asterisk.h +++ b/include/asterisk.h @@ -108,6 +108,7 @@ void threadstorage_init(void); /*!< Provided by threadstorage.c */ int astobj2_init(void); /*! Provided by astobj2.c */ void ast_autoservice_init(void); /*!< Provided by autoservice.c */ int ast_fd_init(void); /*!< Provided by astfd.c */ +int ast_test_init(void); /*!< Provided by test.c */ /* Many headers need 'ast_channel' to be defined */ struct ast_channel; diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h index a41ba857b..6810deea8 100644 --- a/include/asterisk/linkedlists.h +++ b/include/asterisk/linkedlists.h @@ -449,6 +449,7 @@ struct { \ \li AST_LIST_INSERT_AFTER() \li AST_LIST_INSERT_HEAD() \li AST_LIST_INSERT_TAIL() + \li AST_LIST_INSERT_SORTALPHA() */ #define AST_LIST_TRAVERSE(head,var,field) \ for((var) = (head)->first; (var); (var) = (var)->field.next) @@ -681,6 +682,35 @@ struct { \ #define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL /*! + * \brief Inserts a list entry into a alphabetically sorted list + * \param head Pointer to the list head structure + * \param elm Pointer to the entry to be inserted + * \param field Name of the list entry field (declared using AST_LIST_ENTRY()) + * \param sortfield Name of the field on which the list is sorted + */ +#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield) do { \ + if (!(head)->first) { \ + (head)->first = (elm); \ + (head)->last = (elm); \ + } else { \ + typeof((head)->first) cur = (head)->first, prev = NULL; \ + while (cur && strcmp(cur->sortfield, elm->sortfield) < 0) { \ + prev = cur; \ + cur = cur->field.next; \ + } \ + if (!prev) { \ + AST_LIST_INSERT_HEAD(head, elm, field); \ + } else if (!cur) { \ + AST_LIST_INSERT_TAIL(head, elm, field); \ + } else { \ + AST_LIST_INSERT_AFTER(head, prev, elm, field); \ + } \ + } \ +} while (0) + +#define AST_RWLIST_INSERT_SORTALPHA AST_LIST_INSERT_SORTALPHA + +/*! \brief Appends a whole list to the tail of a list. \param head This is a pointer to the list head structure \param list This is a pointer to the list to be appended. diff --git a/include/asterisk/test.h b/include/asterisk/test.h new file mode 100644 index 000000000..f97df80d7 --- /dev/null +++ b/include/asterisk/test.h @@ -0,0 +1,215 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2009-2010, Digium, Inc. + * + * David Vossel <dvossel@digium.com> + * Russell Bryant <russell@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 Test Framework API + * + * For an overview on how to use the test API, see \ref AstUnitTestAPI + * + * \author David Vossel <dvossel@digium.com> + * \author Russell Bryant <russell@digium.com> + */ + +#ifndef _AST_TEST_H_ +#define _AST_TEST_H_ + +#ifdef TEST_FRAMEWORK +#include "asterisk/cli.h" +#include "asterisk/strings.h" +#endif + +/*! + +\page AstUnitTestAPI Asterisk Unit Test API + +\section UnitTestAPIUsage How to Use the Unit Test API + +\subsection DefineTest Define a Test + + Create a callback function for the test using the AST_TEST_DEFINE macro. + + Each defined test has three arguments avaliable to it's test code. + \param struct ast_test_info *info + \param enum ast_test_command cmd + \param struct ast_test *test + + While these arguments are not visible they are passed to every test function + defined using the AST_TEST_DEFINE macro. + + Below is an example of how to define and write a test function. + +\code + AST_TEST_DEFINE(sample_test_cb) \\The name of the callback function + { \\The the function's body + switch (cmd) { + case TEST_INIT: + info->name = "sample_test"; + info->category = "main/test/"; + info->summary = "sample test for example purpose"; + info->description = "This demonstrates how to initialize a test function"; + + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + \test code + . + . + . + if (fail) { \\ the following is just some example logic + ast_test_status_update(test, "an error occured because..."); + res = AST_RESULT_FAIL; + } else { + res = AST_RESULT_PASS + } + return res; \\ result must be of type enum ast_test_result_state + } +\endcode + + Details of the test execution, especially failure details, should be provided + by using the ast_test_status_update() function. + +\subsection RegisterTest Register a Test + + Register the test using the AST_TEST_REGISTER macro. + + AST_TEST_REGISTER uses the callback function to retrieve all the information + pertaining to a test, so the callback function is the only argument required + for registering a test. + + AST_TEST_REGISTER(sample_test_cb); \\ Test callback function defined by AST_TEST_DEFINE + + Tests are unregestered by using the AST_TEST_UNREGISTER macro. + + AST_TEST_UNREGISTER(sample_test_cb); \\ Remove a registered test by callback function + +\subsection ExecuteTest Execute a Test + + Execute and generate test results via CLI commands + + CLI Examples: +\code + 'test show registered all' will show every registered test. + 'test execute all' will execute every registered test. + 'test show results all' will show detailed results for ever executed test + 'test generate results xml' will generate a test report in xml format + 'test generate results txt' will generate a test report in txt format +\endcode +*/ + +/*! Macros used for defining and registering a test */ +#ifdef TEST_FRAMEWORK + +#define AST_TEST_DEFINE(hdr) static enum ast_test_result_state hdr(struct ast_test_info *info, enum ast_test_command cmd, struct ast_test *test) +#define AST_TEST_REGISTER(cb) ast_test_register(cb) +#define AST_TEST_UNREGISTER(cb) ast_test_unregister(cb) + +#else + +#define AST_TEST_DEFINE(hdr) static enum ast_test_result_state attribute_unused hdr(struct ast_test_info *info, enum ast_test_command cmd, struct ast_test *test) +#define AST_TEST_REGISTER(cb) +#define AST_TEST_UNREGISTER(cb) +#define ast_test_status_update(a,b,c...) + +#endif + +enum ast_test_result_state { + AST_TEST_NOT_RUN, + AST_TEST_PASS, + AST_TEST_FAIL, +}; + +enum ast_test_command { + TEST_INIT, + TEST_EXECUTE, +}; + +/*! + * \brief An Asterisk unit test. + * + * This is an opaque type. + */ +struct ast_test; + +/*! + * \brief Contains all the initialization information required to store a new test definition + */ +struct ast_test_info { + /*! \brief name of test, unique to category */ + const char *name; + /*! \brief test category */ + const char *category; + /*! \brief optional short summary of test */ + const char *summary; + /*! \brief optional brief detailed description of test */ + const char *description; +}; + +#ifdef TEST_FRAMEWORK +/*! + * \brief Generic test callback function + * + * \param error buffer string for failure results + * + * \retval AST_TEST_PASS for pass + * \retval AST_TEST_FAIL for failure + */ +typedef enum ast_test_result_state (ast_test_cb_t)(struct ast_test_info *info, + enum ast_test_command cmd, struct ast_test *test); + +/*! + * \brief unregisters a test with the test framework + * + * \param test callback function (required) + * + * \retval 0 success + * \retval -1 failure + */ +int ast_test_unregister(ast_test_cb_t *cb); + +/*! + * \brief registers a test with the test framework + * + * \param test callback function (required) + * + * \retval 0 success + * \retval -1 failure + */ +int ast_test_register(ast_test_cb_t *cb); + +/*! + * \brief update test's status during testing. + * + * \param test currently executing test + * + * \retval 0 success + * \retval -1 failure + */ +int __ast_test_status_update(const char *file, const char *func, int line, + struct ast_test *test, const char *fmt, ...) + __attribute__((format(printf, 5, 6))); + +/*! + * \ref __ast_test_status_update() + */ +#define ast_test_status_update(t, f, ...) __ast_test_status_update(__FILE__, __PRETTY_FUNCTION__, __LINE__, (t), (f), ## __VA_ARGS__) + +#endif /* TEST_FRAMEWORK */ +#endif /* _AST_TEST_H */ |