stasis_test.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * David M. Lee, II <dlee@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. #ifndef _ASTERISK_STASIS_TEST_H
  19. #define _ASTERISK_STASIS_TEST_H
  20. /*!
  21. * \file \brief Test infrastructure for dealing with Stasis.
  22. *
  23. * \author David M. Lee, II <dlee@digium.com>
  24. *
  25. * This file contains some helpful utilities for testing Stasis related topics
  26. * and messages. The \ref stasis_message_sink is something you can subscribe to
  27. * a topic which will receive all of the messages from the topic. This messages
  28. * are accumulated in its \c messages field.
  29. *
  30. * There are a set of wait functions (stasis_message_sink_wait_for_count(),
  31. * stasis_message_sink_wait_for(), etc.) which will block waiting for conditions
  32. * to be met in the \ref stasis_message_sink.
  33. */
  34. #include "asterisk/lock.h"
  35. #include "asterisk/stasis.h"
  36. #define STASIS_SINK_DEFAULT_WAIT 5000
  37. /*! \brief Structure that collects messages from a topic */
  38. struct stasis_message_sink {
  39. /*! Condition mutex. */
  40. ast_mutex_t lock;
  41. /*! Condition to signal state changes */
  42. ast_cond_t cond;
  43. /*! Maximum number of messages messages field can hold without
  44. * realloc */
  45. size_t max_messages;
  46. /*! Current number of messages in messages field. */
  47. size_t num_messages;
  48. /*! Boolean flag to be set when unsubscribe is received */
  49. int is_done:1;
  50. /*! Ordered array of messages received */
  51. struct stasis_message **messages;
  52. };
  53. /*!
  54. * \brief Create a message sink.
  55. *
  56. * This is an AO2 managed object, which you ao2_cleanup() when done. The
  57. * destructor waits for an unsubscribe message to be received, to ensure the
  58. * object isn't disposed of before the topic is finished.
  59. */
  60. struct stasis_message_sink *stasis_message_sink_create(void);
  61. /*!
  62. * \brief Topic callback to receive messages.
  63. *
  64. * We return a function pointer instead of simply exposing the function because
  65. * of the vagaries of dlopen(), \c RTLD_LAZY, and function pointers. See the
  66. * comment on the implementation for details why.
  67. *
  68. * \return Function pointer to \ref stasis_message_sink's message handling
  69. * function
  70. */
  71. stasis_subscription_cb stasis_message_sink_cb(void);
  72. /*!
  73. * \brief Wait for a sink's num_messages field to reach a certain level.
  74. *
  75. * The optional timeout prevents complete deadlock in a test.
  76. *
  77. * \param sink Sink to wait on.
  78. * \param num_messages sink->num_messages value to wait for.
  79. * \param timeout_millis Number of milliseconds to wait. -1 to wait forever.
  80. * \return Actual sink->num_messages value at return.
  81. * If this is < \a num_messages, then the timeout expired.
  82. */
  83. int stasis_message_sink_wait_for_count(struct stasis_message_sink *sink,
  84. int num_messages, int timeout_millis);
  85. typedef int (*stasis_wait_cb)(struct stasis_message *msg, const void *data);
  86. /*!
  87. * \brief Wait for a message that matches the given criteria.
  88. *
  89. * \param sink Sink to wait on.
  90. * \param start Index of message to start with.
  91. * \param cmp_cb comparison function. This returns true (non-zero) on match
  92. * and false (zero) on match.
  93. * \param timeout_millis Number of milliseconds to wait.
  94. * \return Index of the matching message.
  95. * \return Negative for no match.
  96. */
  97. int stasis_message_sink_wait_for(struct stasis_message_sink *sink, int start,
  98. stasis_wait_cb cmp_cb, const void *data, int timeout_millis);
  99. /*!
  100. * \brief Ensures that no new messages are received.
  101. *
  102. * The optional timeout prevents complete deadlock in a test.
  103. *
  104. * \param sink Sink to wait on.
  105. * \param num_messages expecte \a sink->num_messages.
  106. * \param timeout_millis Number of milliseconds to wait for.
  107. * \return Actual sink->num_messages value at return.
  108. * If this is < \a num_messages, then the timeout expired.
  109. */
  110. int stasis_message_sink_should_stay(struct stasis_message_sink *sink,
  111. int num_messages, int timeout_millis);
  112. /*! \addtogroup StasisTopicsAndMessages
  113. * @{
  114. */
  115. /*!
  116. * \brief Creates a test message.
  117. */
  118. struct stasis_message *stasis_test_message_create(void);
  119. /*!
  120. * \brief Gets the type of messages created by stasis_test_message_create().
  121. */
  122. struct stasis_message_type *stasis_test_message_type(void);
  123. /*!
  124. * @}
  125. */
  126. #endif /* _ASTERISK_STASIS_TEST_H */