199 ast_log(
LOG_ERROR,
"Attempted to register test without all required information\n");
240 struct timeval begin;
275 "abstract",
"arguments",
"as",
"assert",
"await",
276 "boolean",
"break",
"byte",
"case",
"catch",
"char",
"class",
277 "const",
"continue",
"debugger",
"def",
"default",
"delete",
"do",
278 "double",
"else",
"enum",
"eval",
"export",
"extends",
"false",
279 "final",
"finally",
"float",
"for",
"function",
"goto",
"if",
280 "implements",
"import",
"in",
"instanceof",
"int",
"interface",
281 "let",
"long",
"native",
"new",
"null",
"package",
"private",
282 "protected",
"public",
"return",
"short",
"static",
"strictfp",
283 "string",
"super",
"switch",
"synchronized",
"this",
"throw",
"throws",
284 "trait",
"transient",
"true",
"try",
"typeof",
"var",
"void",
285 "volatile",
"while",
"with",
"yield" };
305 char *test_name = (
char *)test->
info.
name;
327 size_t name_length = strlen(test->
info.
name) + 2;
330 snprintf(test_name, name_length,
"_%s", test->
info.
name);
333 fprintf(f,
"\t\t<testcase time=\"%u.%u\" classname=\"%s\" name=\"%s\"%s>\n",
334 test->
time / 1000, test->
time % 1000,
341 fprintf(f,
"\t\t\t<failure><![CDATA[\n%s\n\t\t]]></failure>\n",
343 fprintf(f,
"\t\t</testcase>\n");
354 fprintf(f,
"\nName: %s\n", test->
info.
name);
360 fprintf(f,
"Time: %u\n", test->
time);
446 ast_cli(cli->
fd,
"END %s - %s Time: %s%ums Result: %s\n",
449 test->
time ?
"" :
"<",
514 if (!(f_xml = fopen(xml_path,
"w"))) {
521 if (!(f_txt = fopen(txt_path,
"w"))) {
522 ast_log(
LOG_WARNING,
"Could not open file %s for text output of test results\n", txt_path);
534 fprintf(f_xml,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
535 fprintf(f_xml,
"<testsuites>\n");
536 fprintf(f_xml,
"\t<testsuite errors=\"0\" time=\"%u.%u\" tests=\"%u\" " 537 "name=\"AsteriskUnitTests\">\n",
540 fprintf(f_xml,
"\t\t<properties>\n");
541 fprintf(f_xml,
"\t\t\t<property name=\"version\" value=\"%s\"/>\n",
ast_get_version());
542 fprintf(f_xml,
"\t\t</properties>\n");
580 fprintf(f_xml,
"\t</testsuite>\n");
581 fprintf(f_xml,
"</testsuites>\n");
647 if (!cat1 || !cat2) {
658 return strncmp(cat1, cat2, len2) ? 1 : 0;
707 ast_log(
LOG_WARNING,
"Test category '%s' for test '%s' is missing a leading or trailing slash.\n",
717 ast_log(
LOG_ERROR,
"Test %s%s has no summary, test registration refused.\n",
732 ast_log(
LOG_ERROR,
"Test %s%s has no description, test registration refused.\n",
747 ast_log(
LOG_ERROR,
"Failed to allocate status_str for %s%s, test registration failed.\n",
757 int wordlen = strlen(word);
775 int wordlen = strlen(word);
794 #define FORMAT "%-25.25s %-30.30s %-40.40s %-13.13s\n" 795 static const char *
const option1[] = {
"all",
"category",
NULL };
796 static const char *
const option2[] = {
"name",
NULL };
801 e->
command =
"test show registered";
804 "Usage: 'test show registered' can be used in three ways.\n" 805 " 1. 'test show registered all' shows all registered tests\n" 806 " 2. 'test show registered category [test category]' shows all tests in the given\n" 808 " 3. 'test show registered category [test category] name [test name]' shows all\n" 809 " tests in a given category matching a given name\n";
815 if (a->
pos == 4 && !strcasecmp(a->
argv[3],
"category")) {
827 ((a->
argc == 4) && strcasecmp(a->
argv[3],
"all")) ||
828 ((a->
argc == 7) && strcasecmp(a->
argv[5],
"name"))) {
835 if ((a->
argc == 4) ||
846 ast_cli(a->
fd,
"\n%d Registered Tests Matched\n", count);
856 static const char *
const option1[] = {
"all",
"category",
NULL };
857 static const char *
const option2[] = {
"name",
NULL };
863 "Usage: test execute can be used in three ways.\n" 864 " 1. 'test execute all' runs all registered tests\n" 865 " 2. 'test execute category [test category]' runs all tests in the given\n" 867 " 3. 'test execute category [test category] name [test name]' runs all\n" 868 " tests in a given category matching a given name\n";
874 if (a->
pos == 3 && !strcasecmp(a->
argv[2],
"category")) {
890 if ((a->
argc == 3) && !strcasecmp(a->
argv[2],
"all")) {
891 ast_cli(a->
fd,
"Running all available tests...\n\n");
893 }
else if (a->
argc == 4) {
894 ast_cli(a->
fd,
"Running all available tests matching category %s\n\n", a->
argv[3]);
896 }
else if (a->
argc == 6) {
897 ast_cli(a->
fd,
"Running all available tests matching category %s and name %s\n\n", a->
argv[3], a->
argv[5]);
905 ast_cli(a->
fd,
"--- No Tests Found! ---\n");
907 ast_cli(a->
fd,
"\n%u Test(s) Executed %u Passed %u Failed\n",
921 #define FORMAT_RES_ALL1 "%s%s %-30.30s %-25.25s %-10.10s\n" 922 #define FORMAT_RES_ALL2 "%s%s %-30.30s %-25.25s %s%ums\n" 923 static const char *
const option1[] = {
"all",
"failed",
"passed",
NULL };
932 e->
command =
"test show results";
934 "Usage: test show results can be used in three ways\n" 935 " 1. 'test show results all' Displays results for all executed tests.\n" 936 " 2. 'test show results passed' Displays results for all passed tests.\n" 937 " 3. 'test show results failed' Displays results for all failed tests.\n";
949 }
else if (!strcasecmp(a->
argv[3],
"passed")) {
951 }
else if (!strcasecmp(a->
argv[3],
"failed")) {
953 }
else if (!strcasecmp(a->
argv[3],
"all")) {
970 0,
sizeof(result_buf));
977 test->
time ?
" " :
"<",
983 ast_cli(a->
fd,
"%d Test(s) Executed %d Passed %d Failed\n", (failed + passed), passed, failed);
992 static const char *
const option[] = {
"xml",
"txt",
NULL };
994 const char *
type =
"";
1002 e->
command =
"test generate results";
1004 "Usage: 'test generate results'\n" 1005 " Generates test results in either xml or txt format. An optional \n" 1006 " file path may be provided to specify the location of the xml or\n" 1008 " \nExample usage:\n" 1009 " 'test generate results xml' this writes to a default file\n" 1010 " 'test generate results xml /path/to/file.xml' writes to specified file\n";
1022 }
else if (!strcasecmp(a->
argv[3],
"xml")) {
1025 }
else if (!strcasecmp(a->
argv[3],
"txt")) {
1049 ast_cli(a->
fd,
"Results Generated Successfully: %s\n",
S_OR(file,
""));
1051 ast_cli(a->
fd,
"Results Could Not Be Generated: %s\n",
S_OR(file,
""));
1090 if (payload->
blob) {
1097 return payload->
blob;
1154 if (!ast_test_suite_message_type()) {
1171 payload->blob =
ast_json_pack(
"{s: s, s: s, s: s, s: s, s: i, s: s}",
1172 "type",
"testevent",
1175 "appfunction", func,
1178 if (!payload->blob) {
1194 info->
summary =
"Validate Test Registration Data.";
1203 "%d test registration error%s occurred. See startup logs for details.\n",
1216 test_suite_topic =
NULL;
1223 #ifdef TEST_FRAMEWORK 1228 if (!test_suite_topic) {
static char * complete_test_name(const char *word, const char *category)
Contains all the initialization information required to store a new test definition.
Struct containing info for an AMI event to send out.
const char * summary
Short summary of test.
void ast_test_debug(struct ast_test *test, const char *fmt,...)
#define AST_CLI_DEFINE(fn, txt,...)
static char * reserved_words[]
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk main include file. File version handling, generic pbx functions.
static void test_execute(struct ast_test *test)
static SQLHSTMT execute(struct odbc_obj *obj, void *data, int silent)
Common execution function for SQL queries.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
void __ast_test_suite_event_notify(const char *file, const char *func, int line, const char *state, const char *fmt,...)
int ast_test_unregister(ast_test_cb_t *cb)
static char * test_cli_generate_results(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Asterisk version information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
int ast_test_register_init(const char *category, ast_test_init_cb_t *cb)
Time-related functions and macros.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
const char * ast_get_version(void)
Retrieve the Asterisk version string.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
static int registration_errors
static struct ast_test * test_remove(ast_test_cb_t *cb)
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static char * complete_test_category(const char *word)
static struct ast_manager_event_blob * test_suite_event_to_ami(struct stasis_message *msg)
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
#define AST_TEST_REGISTER(cb)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static struct ast_test * test_free(struct ast_test *test)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
#define ast_strdup(str)
A wrapper for strdup()
static int test_generate_results(const char *name, const char *category, const char *xml_path, const char *txt_path)
void ast_cli(int fd, const char *fmt,...)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
struct ast_str * status_str
Test defined status output from last execution.
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
static void test_xml_entry(struct ast_test *test, FILE *f)
static char * test_cli_show_results(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ast_strlen_zero(foo)
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
struct stasis_topic * test_suite_topic
The topic for test suite messages.
#define AST_LIST_INSERT_SORTALPHA(head, elm, field, sortfield)
Inserts a list entry into a alphabetically sorted list.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
int ast_test_register(ast_test_cb_t *cb)
ast_test_cleanup_cb_t * cleanup_cb
struct ast_json * ast_test_suite_get_blob(struct ast_test_suite_message_payload *payload)
Asterisk JSON abstraction layer.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Asterisk file paths, configured in asterisk.conf.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_test_status_update(a, b, c...)
struct ast_cli_args * cli
CLI arguments, if tests being run from the CLI.
unsigned int total_passed
static char * test_cli_execute_registered(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
int __ast_test_status_update(const char *file, const char *func, int line, struct ast_test *test, const char *fmt,...)
#define ast_strdupa(s)
duplicate a string in memory from the stack
unsigned int total_failed
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
A set of macros to manage forward-linked lists.
static void test_suite_message_payload_dtor(void *obj)
const char * description
More detailed description of test.
struct stasis_topic * stasis_topic_create(const char *name)
Create a new topic.
const char * name
name of test, unique to category
int ast_test_register_cleanup(const char *category, ast_test_cleanup_cb_t *cb)
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
AST_TEST_DEFINE(test_registrations)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
STASIS_MESSAGE_TYPE_DEFN(ast_test_suite_message_type,.to_ami=test_suite_event_to_ami)
The message type for test suite messages.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
#define AST_TEST_UNREGISTER(cb)
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
static int is_reserved_word(const char *word)
static int test_cat_cmp(const char *cat1, const char *cat2)
compares two test categories to determine if cat1 resides in cat2
static int test_execute_multiple(const char *name, const char *category, struct ast_cli_args *cli)
struct stasis_topic * ast_test_suite_topic(void)
#define ao2_alloc(data_size, destructor_fn)
const char * category
test category
const char * ast_config_AST_LOG_DIR
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
static void test_cleanup(void)
#define ast_calloc(num, len)
A wrapper for calloc()
static int test_insert(struct ast_test *test)
void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state)
static void to_ami(struct ast_sip_subscription *sub, struct ast_str **buf)
unsigned int explicit_only
Only run if explicitly named.
Prototypes for public functions only of internal interest,.
A wrapper object that can be ao2 ref counted around an ast_json blob.
Support for logging to various files, console and syslog Configuration in file logger.conf.
const char * ast_get_version_num(void)
Retrieve the numeric Asterisk version.
static struct ast_test_execute_results last_results
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define EVENT_FLAG_REPORTING
Standard Command Line Interface.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
static struct ast_threadstorage result_buf
struct ast_test_info info
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static void test_txt_entry(struct ast_test *test, FILE *f)
static struct ast_test * test_alloc(ast_test_cb_t *cb)
Abstract JSON element (object, array, string, int, ...).
Handy terminal functions for vt* terms.
static struct ast_cli_entry test_cli[]
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
struct ast_test::@430 entry
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
static char * test_cli_show_registered(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
ast_test_init_cb_t * init_cb
enum ast_test_result_state state
static struct ast_test * test
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
static char prefix[MAX_PREFIX]
static const char *const test_result2str[]