test.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2009-2013, Digium, Inc.
  5. *
  6. * David Vossel <dvossel@digium.com>
  7. * Russell Bryant <russell@digium.com>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*!
  20. * \file
  21. * \brief Test Framework API
  22. *
  23. * For an overview on how to use the test API, see \ref AstUnitTestAPI
  24. *
  25. * \author David Vossel <dvossel@digium.com>
  26. * \author Russell Bryant <russell@digium.com>
  27. */
  28. #ifndef _AST_TEST_H_
  29. #define _AST_TEST_H_
  30. #ifdef TEST_FRAMEWORK
  31. #include "asterisk/cli.h"
  32. #include "asterisk/strings.h"
  33. #endif
  34. /*!
  35. \page AstUnitTestAPI Asterisk Unit Test API
  36. \section UnitTestAPIUsage How to Use the Unit Test API
  37. \subsection DefineTest Define a Test
  38. Create a callback function for the test using the AST_TEST_DEFINE macro.
  39. Each defined test has three arguments available to it's test code.
  40. \param struct ast_test_info *info
  41. \param enum ast_test_command cmd
  42. \param struct ast_test *test
  43. While these arguments are not visible they are passed to every test function
  44. defined using the AST_TEST_DEFINE macro.
  45. Below is an example of how to define and write a test function.
  46. \code
  47. AST_TEST_DEFINE(sample_test_cb) \\The name of the callback function
  48. { \\The the function's body
  49. switch (cmd) {
  50. case TEST_INIT:
  51. info->name = "sample_test";
  52. info->category = "main/test/";
  53. info->summary = "sample test for example purpose";
  54. info->description = "This demonstrates how to initialize a test function";
  55. return AST_TEST_NOT_RUN;
  56. case TEST_EXECUTE:
  57. break;
  58. }
  59. \test code
  60. .
  61. .
  62. .
  63. if (fail) { \\ the following is just some example logic
  64. ast_test_status_update(test, "an error occured because...");
  65. res = AST_RESULT_FAIL;
  66. } else {
  67. res = AST_RESULT_PASS
  68. }
  69. return res; \\ result must be of type enum ast_test_result_state
  70. }
  71. \endcode
  72. Details of the test execution, especially failure details, should be provided
  73. by using the ast_test_status_update() function.
  74. \subsection RegisterTest Register a Test
  75. Register the test using the AST_TEST_REGISTER macro.
  76. AST_TEST_REGISTER uses the callback function to retrieve all the information
  77. pertaining to a test, so the callback function is the only argument required
  78. for registering a test.
  79. AST_TEST_REGISTER(sample_test_cb); \\ Test callback function defined by AST_TEST_DEFINE
  80. Tests are unregestered by using the AST_TEST_UNREGISTER macro.
  81. AST_TEST_UNREGISTER(sample_test_cb); \\ Remove a registered test by callback function
  82. \subsection ExecuteTest Execute a Test
  83. Execute and generate test results via CLI commands
  84. CLI Examples:
  85. \code
  86. 'test show registered all' will show every registered test.
  87. 'test execute all' will execute every registered test.
  88. 'test show results all' will show detailed results for ever executed test
  89. 'test generate results xml' will generate a test report in xml format
  90. 'test generate results txt' will generate a test report in txt format
  91. \endcode
  92. */
  93. /*! Macros used for defining and registering a test */
  94. #ifdef TEST_FRAMEWORK
  95. #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)
  96. #define AST_TEST_REGISTER(cb) ast_test_register(cb)
  97. #define AST_TEST_UNREGISTER(cb) ast_test_unregister(cb)
  98. #else
  99. #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)
  100. #define AST_TEST_REGISTER(cb)
  101. #define AST_TEST_UNREGISTER(cb)
  102. #define ast_test_status_update(a,b,c...)
  103. #define ast_test_debug(test, fmt, ...) ast_cli /* Dummy function that should not be called. */
  104. #endif
  105. /*! Macros used for the Asterisk Test Suite AMI events */
  106. #ifdef TEST_FRAMEWORK
  107. struct stasis_topic;
  108. struct stasis_message_type;
  109. /*!
  110. * \since 12
  111. * \brief Obtain the \ref stasis_topic for \ref ast_test_suite_event_notify
  112. * messages
  113. *
  114. * \retval A stasis topic
  115. */
  116. struct stasis_topic *ast_test_suite_topic(void);
  117. /*!
  118. * \since 12
  119. * \brief Obtain the \ref stasis_message_type for \ref ast_test_suite_event_notify
  120. * messages
  121. *
  122. * \retval A stasis message type
  123. */
  124. struct stasis_message_type *ast_test_suite_message_type(void);
  125. /*!
  126. * \since 12
  127. * \brief The message payload in a \ref ast_test_suite_message_type
  128. */
  129. struct ast_test_suite_message_payload;
  130. /*!
  131. * \since 12
  132. * \brief Get the JSON for a \ref ast_test_suite_message_payload
  133. *
  134. * \retval An \ref ast_json object
  135. */
  136. struct ast_json *ast_test_suite_get_blob(struct ast_test_suite_message_payload *payload);
  137. /*!
  138. * \brief Notifies the test suite of a change in application state
  139. *
  140. * \details
  141. * Raises a TestEvent manager event with a subtype of StateChange. Additional parameters
  142. * The fmt parameter allows additional parameters to be added to the manager event using
  143. * printf style statement formatting.
  144. *
  145. * \param state The state the application has changed to
  146. * \param fmt The message with format parameters to add to the manager event
  147. *
  148. * \return Nothing
  149. */
  150. void __ast_test_suite_event_notify(const char *file, const char *func, int line, const char *state, const char *fmt, ...)
  151. __attribute__((format(printf, 5, 6)));
  152. /*!
  153. * \ref __ast_test_suite_event_notify()
  154. */
  155. #define ast_test_suite_event_notify(s, f, ...) \
  156. __ast_test_suite_event_notify(__FILE__, __PRETTY_FUNCTION__, __LINE__, (s), (f), ## __VA_ARGS__)
  157. #else
  158. #define ast_test_suite_event_notify(s, f, ...)
  159. #endif
  160. enum ast_test_result_state {
  161. AST_TEST_NOT_RUN,
  162. AST_TEST_PASS,
  163. AST_TEST_FAIL,
  164. };
  165. enum ast_test_command {
  166. TEST_INIT,
  167. TEST_EXECUTE,
  168. };
  169. /*!
  170. * \brief An Asterisk unit test.
  171. *
  172. * This is an opaque type.
  173. */
  174. struct ast_test;
  175. /*!
  176. * \brief Contains all the initialization information required to store a new test definition
  177. */
  178. struct ast_test_info {
  179. /*! \brief name of test, unique to category */
  180. const char *name;
  181. /*!
  182. * \brief test category
  183. *
  184. * \details
  185. * Tests are categorized in a directory tree style hierarchy. It is expected that
  186. * this string have both a leading and trailing forward slash ('/').
  187. */
  188. const char *category;
  189. /*!
  190. * \brief Short summary of test
  191. *
  192. * \note The summary must not end with a newline.
  193. */
  194. const char *summary;
  195. /*!
  196. * \brief More detailed description of test
  197. *
  198. * \note The description must not end with a newline.
  199. */
  200. const char *description;
  201. /*!
  202. * \brief Only run if explicitly named
  203. *
  204. * \details
  205. * Run this test only if it's explicitly named on the command line.
  206. * Do NOT run it as part of an execute category or execute all command.
  207. */
  208. unsigned int explicit_only;
  209. };
  210. #ifdef TEST_FRAMEWORK
  211. /*!
  212. * \brief Generic test callback function
  213. *
  214. * \param info The test info object
  215. * \param cmd What to perform in the test
  216. * \param test The actual test object being manipulated
  217. *
  218. * \retval AST_TEST_PASS for pass
  219. * \retval AST_TEST_FAIL for failure
  220. */
  221. typedef enum ast_test_result_state (ast_test_cb_t)(struct ast_test_info *info,
  222. enum ast_test_command cmd, struct ast_test *test);
  223. /*!
  224. * \since 12
  225. * \brief A test initialization callback function
  226. *
  227. * \param info The test info object
  228. * \param test The actual test object that will be manipulated
  229. *
  230. * \retval 0 success
  231. * \retval other failure. This will fail the test.
  232. */
  233. typedef int (ast_test_init_cb_t)(struct ast_test_info *info, struct ast_test *test);
  234. /*!
  235. * \since 12
  236. * \brief A test cleanup callback function
  237. *
  238. * \param info The test info object
  239. * \param test The actual test object that was executed
  240. *
  241. * \retval 0 success
  242. * \retval other failure. This will fail the test.
  243. */
  244. typedef int (ast_test_cleanup_cb_t)(struct ast_test_info *info, struct ast_test *test);
  245. /*!
  246. * \brief unregisters a test with the test framework
  247. *
  248. * \param test callback function (required)
  249. *
  250. * \retval 0 success
  251. * \retval -1 failure
  252. */
  253. int ast_test_unregister(ast_test_cb_t *cb);
  254. /*!
  255. * \brief registers a test with the test framework
  256. *
  257. * \param test callback function (required)
  258. *
  259. * \retval 0 success
  260. * \retval -1 failure
  261. */
  262. int ast_test_register(ast_test_cb_t *cb);
  263. /*!
  264. * \since 12
  265. * \brief Register an initialization function to be run before each test
  266. * executes
  267. *
  268. * This function lets a registered test have an initialization function that
  269. * will be run prior to test execution. Each category may have a single init
  270. * function.
  271. *
  272. * If the initialization function returns a non-zero value, the test will not
  273. * be executed and the result will be set to \ref AST_TEST_FAIL.
  274. *
  275. * \retval 0 success
  276. * \retval other failure
  277. */
  278. int ast_test_register_init(const char *category, ast_test_init_cb_t *cb);
  279. /*!
  280. * \since 12
  281. * \brief Register a cleanup function to be run after each test executes
  282. *
  283. * This function lets a registered test have a cleanup function that will be
  284. * run immediately after test execution. Each category may have a single
  285. * cleanup function.
  286. *
  287. * If the cleanup function returns a non-zero value, the test result will be
  288. * set to \ref AST_TEST_FAIL.
  289. *
  290. * \retval 0 success
  291. * \retval other failure
  292. */
  293. int ast_test_register_cleanup(const char *category, ast_test_cleanup_cb_t *cb);
  294. /*!
  295. * \brief Unit test debug output.
  296. * \since 12.0.0
  297. *
  298. * \param test Unit test control structure.
  299. * \param fmt printf type format string.
  300. *
  301. * \return Nothing
  302. */
  303. void ast_test_debug(struct ast_test *test, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
  304. /*!
  305. * \brief Set the result of a test.
  306. *
  307. * If the caller of this function sets the result to AST_TEST_FAIL, returning
  308. * AST_TEST_PASS from the test will not pass the test. This lets a test writer
  309. * end and fail a test and continue on with logic, catching multiple failure
  310. * conditions within a single test.
  311. */
  312. void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state);
  313. /*!
  314. * \brief update test's status during testing.
  315. *
  316. * \param test currently executing test
  317. *
  318. * \retval 0 success
  319. * \retval -1 failure
  320. */
  321. int __ast_test_status_update(const char *file, const char *func, int line, struct ast_test *test, const char *fmt, ...)
  322. __attribute__((format(printf, 5, 6)));
  323. /*!
  324. * \ref __ast_test_status_update()
  325. */
  326. #define ast_test_status_update(t, f, ...) __ast_test_status_update(__FILE__, __PRETTY_FUNCTION__, __LINE__, (t), (f), ## __VA_ARGS__)
  327. /*!
  328. * \brief Check a test condition, failing the test if it's not true.
  329. *
  330. * \since 12.0.0
  331. *
  332. * This macro evaluates \a condition. If the condition evaluates to true (non-zero),
  333. * nothing happens. If it evaluates to false (zero), then the failure is printed
  334. * using \ref ast_test_status_update, and the current test is ended with AST_TEST_FAIL.
  335. *
  336. * Sadly, the name 'ast_test_assert' was already taken.
  337. *
  338. * Note that since this macro returns from the current test, there must not be any
  339. * cleanup work to be done before returning. Use \ref RAII_VAR for test cleanup.
  340. *
  341. * \param test Currently executing test
  342. * \param condition Boolean condition to check.
  343. */
  344. #define ast_test_validate(test, condition, ...) \
  345. do { \
  346. if (!(condition)) { \
  347. __ast_test_status_update(__FILE__, __PRETTY_FUNCTION__, __LINE__, (test), "%s: %s\n", strlen(#__VA_ARGS__) ? #__VA_ARGS__ : "Condition failed", #condition); \
  348. return AST_TEST_FAIL; \
  349. } \
  350. } while(0)
  351. /*!
  352. * \brief Check a test condition, report error and goto cleanup label if failed.
  353. *
  354. * \since 13.4.0
  355. *
  356. * This macro evaluates \a condition. If the condition evaluates to true (non-zero),
  357. * nothing happens. If it evaluates to false (zero), then the failure is printed
  358. * using \ref ast_test_status_update, the variable \a rc_variable is set to AST_TEST_FAIL,
  359. * and a goto to \a cleanup_label is executed.
  360. *
  361. * \param test Currently executing test
  362. * \param condition Boolean condition to check.
  363. * \param rc_variable Variable to receive AST_TEST_FAIL.
  364. * \param cleanup_label The label to go to on failure.
  365. */
  366. #define ast_test_validate_cleanup(test, condition, rc_variable, cleanup_label) ({ \
  367. if (!(condition)) { \
  368. ast_test_status_update((test), "%s: %s\n", "Condition failed", #condition); \
  369. rc_variable = AST_TEST_FAIL; \
  370. goto cleanup_label; \
  371. } \
  372. })
  373. #endif /* TEST_FRAMEWORK */
  374. #endif /* _AST_TEST_H */