Convert TestEvent AMI events over to Stasis Core
[asterisk/asterisk.git] / include / asterisk / test.h
index bba40bd..d890b7a 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 2009, Digium, Inc.
+ * Copyright (C) 2009-2013, 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
@@ -23,6 +24,7 @@
  * 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_
@@ -33,7 +35,7 @@
 #include "asterisk/strings.h"
 #endif
 
-/*! 
+/*!
 
 \page AstUnitTestAPI Asterisk Unit Test API
 
@@ -46,7 +48,7 @@
    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_args *args
+       \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.
@@ -55,7 +57,7 @@
 
 \code
    AST_TEST_DEFINE(sample_test_cb) \\The name of the callback function
-   {                               \\The the function's body 
+   {                               \\The the function's body
       switch (cmd) {
       case TEST_INIT:
           info->name = "sample_test";
@@ -72,7 +74,7 @@
       .
       .
       if (fail) {                 \\ the following is just some example logic
-          ast_str_set(&args->ast_test_error_str, 0 , "an error occured because...");
+          ast_test_status_update(test, "an error occured because...");
           res = AST_RESULT_FAIL;
       } else {
           res = AST_RESULT_PASS
    }
 \endcode
 
-   Every callback function is passed an ast_test_args object which contains
-   an ast_str allowing the function to provide an optional short description of
-   what went wrong if the test failed. This is done by writing to
-   args->ast_test_error_str.
+      Details of the test execution, especially failure details, should be provided
+      by using the ast_test_status_update() function.
 
-\subsection RegisterTest Register a Test 
+\subsection RegisterTest Register a Test
 
    Register the test using the AST_TEST_REGISTER macro.
 
 /*! 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_args *args)
+#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_args *args)
+#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...)
+#define ast_test_debug(test, fmt, ...) ast_cli         /* Dummy function that should not be called. */
+
+#endif
+
+/*! 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
+ *
+ * \details
+ * Raises a TestEvent manager event with a subtype of StateChange.  Additional parameters
+ * The fmt parameter allows additional parameters to be added to the manager event using
+ * printf style statement formatting.
+ *
+ * \param state                The state the application has changed to
+ * \param fmt          The message with format parameters to add to the manager event
+ *
+ * \return Nothing
+ */
+void __ast_test_suite_event_notify(const char *file, const char *func, int line, const char *state, const char *fmt, ...)
+       __attribute__((format(printf, 5, 6)));
+
+/*!
+ * \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__)
+
+#else
+
+#define ast_test_suite_event_notify(s, f, ...)
 
 #endif
 
@@ -141,34 +209,28 @@ enum ast_test_command {
 };
 
 /*!
- *  This struct is passed to ast_test_status_update() providing a place to push
- *  the update to. In the future this structure may expand beyond simply being
- *  a wrapper for cli args to including other status update options as well.
- */
-struct ast_test_status_args {
-       /*! pointer to cli arg used for updating status */
-       struct ast_cli_args *cli;
-};
-
-/*!
- * tools made available to the callback function during test execution
+ * \brief An Asterisk unit test.
+ *
+ * This is an opaque type.
  */
-struct ast_test_args {
-       struct ast_str *ast_test_error_str;  /*! optional error str to describe error result */
-       struct ast_test_status_args status_update;
-};
+struct ast_test;
 
 /*!
- * Contains all the initilization information required to store a new test definition
+ * \brief Contains all the initialization information required to store a new test definition
  */
 struct ast_test_info {
-       /*! name of test, unique to category */
+       /*! \brief name of test, unique to category */
        const char *name;
-       /*! test category */
+       /*!
+        * \brief test category
+        *
+        * Tests are categorized in a directory tree style hierarchy.  It is expected that
+        * this string have both a leading and trailing forward slash ('/').
+        */
        const char *category;
-       /*! optional short summary of test */
+       /*! \brief optional short summary of test */
        const char *summary;
-       /*! optional brief detailed description of test */
+       /*! \brief optional brief detailed description of test */
        const char *description;
 };
 
@@ -181,7 +243,8 @@ struct ast_test_info {
  * \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_args *args);
+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
@@ -204,15 +267,57 @@ int ast_test_unregister(ast_test_cb_t *cb);
 int ast_test_register(ast_test_cb_t *cb);
 
 /*!
+ * \brief Unit test debug output.
+ * \since 12.0.0
+ *
+ * \param test Unit test control structure.
+ * \param fmt printf type format string.
+ *
+ * \return Nothing
+ */
+void ast_test_debug(struct ast_test *test, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
+/*!
  * \brief update test's status during testing.
  *
- * \param ast_test_status_args defines everywhere the update should go.
+ * \param test currently executing test
  *
  * \retval 0 success
  * \retval -1 failure
  */
-int ast_test_status_update(struct ast_test_status_args *args, const char *fmt, ...)
-__attribute__((format(printf, 2, 3)));
+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__)
+
+/*!
+ * \brief Check a test condition, failing the test if it's not true.
+ *
+ * \since 12.0.0
+ *
+ * This macro evaluates \a condition. If the condition evaluates to true (non-zero),
+ * nothing happens. If it evaluates to false (zero), then the failure is printed
+ * using \ref ast_test_status_update, and the current test is ended with AST_TEST_FAIL.
+ *
+ * Sadly, the name 'ast_test_assert' was already taken.
+ *
+ * Note that since this macro returns from the current test, there must not be any
+ * cleanup work to be done before returning. Use \ref RAII_VAR for test cleanup.
+ *
+ * \param test Currently executing test
+ * \param condition Boolean condition to check.
+ */
+#define ast_test_validate(test, condition)                             \
+       do {                                                            \
+               if (!(condition)) {                                     \
+                       __ast_test_status_update(__FILE__, __PRETTY_FUNCTION__, __LINE__, (test), "Condition failed: %s\n", #condition); \
+                       return AST_TEST_FAIL;                           \
+               }                                                       \
+       } while(0)
+
 
 #endif /* TEST_FRAMEWORK */
 #endif /* _AST_TEST_H */