diff options
-rw-r--r-- | apps/app_voicemail.c | 1 | ||||
-rw-r--r-- | include/asterisk/test.h | 60 | ||||
-rw-r--r-- | main/manager.c | 50 | ||||
-rw-r--r-- | main/test.c | 111 |
4 files changed, 174 insertions, 48 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index c2de8da39..5b3dd73f1 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -10953,7 +10953,6 @@ static int vm_execmain(struct ast_channel *chan, const char *data) /* If ADSI is supported, setup login screen */ adsi_begin(chan, &useadsi); - ast_test_suite_assert(valid); if (!valid) { goto out; } diff --git a/include/asterisk/test.h b/include/asterisk/test.h index 8eec6cf16..d890b7a3e 100644 --- a/include/asterisk/test.h +++ b/include/asterisk/test.h @@ -134,6 +134,41 @@ /*! Macros used for the Asterisk Test Suite AMI events */ #ifdef TEST_FRAMEWORK +struct stasis_topic; +struct stasis_message_type; + +/*! + * \since 12 + * \brief Obtain the \ref stasis_topic for \ref ast_test_suite_event_notify + * messages + * + * \retval A stasis topic + */ +struct stasis_topic *ast_test_suite_topic(void); + +/*! + * \since 12 + * \brief Obtain the \ref stasis_message_type for \ref ast_test_suite_event_notify + * messages + * + * \retval A stasis message type + */ +struct stasis_message_type *ast_test_suite_message_type(void); + +/*! + * \since 12 + * \brief The message payload in a \ref ast_test_suite_message_type + */ +struct ast_test_suite_message_payload; + +/*! + * \since 12 + * \brief Get the JSON for a \ref ast_test_suite_message_payload + * + * \retval An \ref ast_json object + */ +struct ast_json *ast_test_suite_get_blob(struct ast_test_suite_message_payload *payload); + /*! * \brief Notifies the test suite of a change in application state * @@ -151,39 +186,14 @@ void __ast_test_suite_event_notify(const char *file, const char *func, int line, __attribute__((format(printf, 5, 6))); /*! - * \brief Notifies the test suite of a failed assert on an expression - * - * \details - * If the expression provided evaluates to true, no action is taken. If the expression - * evaluates to a false, a TestEvent manager event is raised with a subtype of Assert, notifying - * the test suite that the expression failed to evaluate to true. - * - * \param exp The expression to evaluate - * - * \return Nothing - */ -void __ast_test_suite_assert_notify(const char *file, const char *func, int line, const char *exp); - -/*! * \ref __ast_test_suite_event_notify() */ #define ast_test_suite_event_notify(s, f, ...) \ __ast_test_suite_event_notify(__FILE__, __PRETTY_FUNCTION__, __LINE__, (s), (f), ## __VA_ARGS__) -/*! - * \ref __ast_test_suite_assert_notify() - */ -#define ast_test_suite_assert(exp) \ - do { \ - if (__builtin_expect(!(exp), 1)) { \ - __ast_test_suite_assert_notify(__FILE__, __PRETTY_FUNCTION__, __LINE__, #exp); \ - } \ - } while (0) - #else #define ast_test_suite_event_notify(s, f, ...) -#define ast_test_suite_assert(exp) #endif diff --git a/main/manager.c b/main/manager.c index fdc85424b..eb4fd0649 100644 --- a/main/manager.c +++ b/main/manager.c @@ -92,6 +92,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/stringfields.h" #include "asterisk/presencestate.h" #include "asterisk/stasis.h" +#include "asterisk/test.h" +#include "asterisk/json.h" /*** DOCUMENTATION <manager name="Ping" language="en_US"> @@ -7343,6 +7345,50 @@ static void load_channelvars(struct ast_variable *var) ast_channel_set_manager_vars(args.argc, args.vars); } +#ifdef TEST_FRAMEWORK + +static void test_suite_event_cb(void *data, struct stasis_subscription *sub, + struct stasis_topic *topic, + struct stasis_message *message) +{ + struct ast_test_suite_message_payload *payload; + struct ast_json *blob; + const char *type; + + if (stasis_message_type(message) != ast_test_suite_message_type()) { + return; + } + + payload = stasis_message_data(message); + if (!payload) { + return; + } + blob = ast_test_suite_get_blob(payload); + if (!blob) { + return; + } + + type = ast_json_string_get(ast_json_object_get(blob, "type")); + if (ast_strlen_zero(type) || strcmp("testevent", type)) { + return; + } + + manager_event(EVENT_FLAG_TEST, "TestEvent", + "Type: StateChange\r\n" + "State: %s\r\n" + "AppFile: %s\r\n" + "AppFunction: %s\r\n" + "AppLine: %ld\r\n" + "%s\r\n", + ast_json_string_get(ast_json_object_get(blob, "state")), + ast_json_string_get(ast_json_object_get(blob, "appfile")), + ast_json_string_get(ast_json_object_get(blob, "appfunction")), + ast_json_integer_get(ast_json_object_get(blob, "line")), + ast_json_string_get(ast_json_object_get(blob, "data"))); +} + +#endif + /*! \internal \brief Free a user record. Should already be removed from the list */ static void manager_free_user(struct ast_manager_user *user) { @@ -7499,6 +7545,10 @@ static int __init_manager(int reload, int by_external_config) ast_manager_register_xml_core("AOCMessage", EVENT_FLAG_AOC, action_aocmessage); ast_manager_register_xml_core("Filter", EVENT_FLAG_SYSTEM, action_filter); +#ifdef TEST_FRAMEWORK + stasis_subscribe(ast_test_suite_topic(), test_suite_event_cb, NULL); +#endif + ast_cli_register_multiple(cli_manager, ARRAY_LEN(cli_manager)); __ast_custom_function_register(&managerclient_function, NULL); ast_extension_state_add(NULL, NULL, manager_state_cb, NULL); diff --git a/main/test.c b/main/test.c index 612697a15..12df75dd0 100644 --- a/main/test.c +++ b/main/test.c @@ -45,7 +45,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$"); #include "asterisk/ast_version.h" #include "asterisk/paths.h" #include "asterisk/time.h" -#include "asterisk/manager.h" +#include "asterisk/stasis.h" +#include "asterisk/json.h" +#include "asterisk/astobj2.h" + +/*! \since 12 + * \brief The topic for test suite messages + */ +struct stasis_topic *test_suite_topic; + +/*! \since 12 + * \brief The message type for test suite messages + */ +static struct stasis_message_type *test_suite_type; /*! This array corresponds to the values defined in the ast_test_state enum */ static const char * const test_result2str[] = { @@ -910,49 +922,104 @@ static struct ast_cli_entry test_cli[] = { AST_CLI_DEFINE(test_cli_generate_results, "generate test results to file"), }; +struct stasis_topic *ast_test_suite_topic(void) +{ + return test_suite_topic; +} + +struct stasis_message_type *ast_test_suite_message_type(void) +{ + return test_suite_type; +} + +/*! + * \since 12 + * \brief A wrapper object that can be ao2 ref counted around an \ref ast_json blob + */ +struct ast_test_suite_message_payload { + struct ast_json *blob; /*!< The actual blob that we want to deliver */ +}; + +/*! \internal + * \since 12 + * \brief Destructor for \ref ast_test_suite_message_payload + */ +static void test_suite_message_payload_dtor(void *obj) +{ + struct ast_test_suite_message_payload *payload = obj; + + if (payload->blob) { + ast_json_unref(payload->blob); + } +} + +struct ast_json *ast_test_suite_get_blob(struct ast_test_suite_message_payload *payload) +{ + return payload->blob; +} + void __ast_test_suite_event_notify(const char *file, const char *func, int line, const char *state, const char *fmt, ...) { - struct ast_str *buf = NULL; + RAII_VAR(struct ast_test_suite_message_payload *, payload, + ao2_alloc(sizeof(*payload), test_suite_message_payload_dtor), + ao2_cleanup); + RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + RAII_VAR(struct ast_str *, buf, ast_str_create(128), ast_free); va_list ap; - if (!(buf = ast_str_create(128))) { + if (!buf) { + return; + } + if (!payload) { return; } va_start(ap, fmt); ast_str_set_va(&buf, 0, fmt, ap); va_end(ap); + payload->blob = ast_json_pack("{s: s, s: s, s: s, s: s, s: i, s: s}", + "type", "testevent", + "state", state, + "appfile", file, + "appfunction", func, + "line", line, + "data", ast_str_buffer(buf)); + if (!payload->blob) { + return; + } + msg = stasis_message_create(ast_test_suite_message_type(), payload); + if (!msg) { + return; + } + stasis_publish(ast_test_suite_topic(), msg); +} - manager_event(EVENT_FLAG_TEST, "TestEvent", - "Type: StateChange\r\n" - "State: %s\r\n" - "AppFile: %s\r\n" - "AppFunction: %s\r\n" - "AppLine: %d\r\n" - "%s\r\n", - state, file, func, line, ast_str_buffer(buf)); +#endif /* TEST_FRAMEWORK */ - ast_free(buf); -} +#ifdef TEST_FRAMEWORK -void __ast_test_suite_assert_notify(const char *file, const char *func, int line, const char *exp) +static void test_cleanup(void) { - manager_event(EVENT_FLAG_TEST, "TestEvent", - "Type: Assert\r\n" - "AppFile: %s\r\n" - "AppFunction: %s\r\n" - "AppLine: %d\r\n" - "Expression: %s\r\n", - file, func, line, exp); + ao2_cleanup(test_suite_topic); + test_suite_topic = NULL; + ao2_cleanup(test_suite_type); + test_suite_type = NULL; } -#endif /* TEST_FRAMEWORK */ +#endif int ast_test_init(void) { #ifdef TEST_FRAMEWORK + /* Create stasis topic */ + test_suite_topic = stasis_topic_create("test_suite_topic"); + test_suite_type = stasis_message_type_create("test_suite_type"); + if (!test_suite_topic || !test_suite_type) { + return -1; + } /* Register cli commands */ ast_cli_register_multiple(test_cli, ARRAY_LEN(test_cli)); + ast_register_atexit(test_cleanup); #endif return 0; |