diff options
Diffstat (limited to 'include/asterisk/stasis_test.h')
-rw-r--r-- | include/asterisk/stasis_test.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/include/asterisk/stasis_test.h b/include/asterisk/stasis_test.h new file mode 100644 index 000000000..ad4020a08 --- /dev/null +++ b/include/asterisk/stasis_test.h @@ -0,0 +1,142 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * David M. Lee, II <dlee@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +#ifndef _ASTERISK_STASIS_TEST_H +#define _ASTERISK_STASIS_TEST_H + +/*! + * \file \brief Test infrastructure for dealing with Stasis. + * + * \author David M. Lee, II <dlee@digium.com> + * + * This file contains some helpful utilities for testing Stasis related topics + * and messages. The \ref stasis_message_sink is something you can subscribe to + * a topic which will receive all of the messages from the topic. This messages + * are accumulated in its \c messages field. + * + * There are a set of wait functions (stasis_message_sink_wait_for_count(), + * stasis_message_sink_wait_for(), etc.) which will block waiting for conditions + * to be met in the \ref stasis_message_sink. + */ + +#include "asterisk/lock.h" +#include "asterisk/stasis.h" + +#define STASIS_SINK_DEFAULT_WAIT 5000 + +/*! \brief Structure that collects messages from a topic */ +struct stasis_message_sink { + /*! Condition mutex. */ + ast_mutex_t lock; + /*! Condition to signal state changes */ + ast_cond_t cond; + /*! Maximum number of messages messages field can hold without + * realloc */ + size_t max_messages; + /*! Current number of messages in messages field. */ + size_t num_messages; + /*! Boolean flag to be set when unsubscribe is received */ + int is_done:1; + /*! Ordered array of messages received */ + struct stasis_message **messages; +}; + +/*! + * \brief Create a message sink. + * + * This is an AO2 managed object, which you ao2_cleanup() when done. The + * destructor waits for an unsubscribe message to be received, to ensure the + * object isn't disposed of before the topic is finished. + */ +struct stasis_message_sink *stasis_message_sink_create(void); + +/*! + * \brief Topic callback to receive messages. + * + * We return a function pointer instead of simply exposing the function because + * of the vagaries of dlopen(), \c RTLD_LAZY, and function pointers. See the + * comment on the implementation for details why. + * + * \return Function pointer to \ref stasis_message_sink's message handling + * function + */ +stasis_subscription_cb stasis_message_sink_cb(void); + +/*! + * \brief Wait for a sink's num_messages field to reach a certain level. + * + * The optional timeout prevents complete deadlock in a test. + * + * \param sink Sink to wait on. + * \param num_messages sink->num_messages value to wait for. + * \param timeout_millis Number of milliseconds to wait. -1 to wait forever. + * \return Actual sink->num_messages value at return. + * If this is < \a num_messages, then the timeout expired. + */ +int stasis_message_sink_wait_for_count(struct stasis_message_sink *sink, + int num_messages, int timeout_millis); + +typedef int (*stasis_wait_cb)(struct stasis_message *msg, const void *data); + +/*! + * \brief Wait for a message that matches the given criteria. + * + * \param sink Sink to wait on. + * \param start Index of message to start with. + * \param cmp_cb comparison function. This returns true (non-zero) on match + * and false (zero) on match. + * \param timeout_millis Number of milliseconds to wait. + * \return Index of the matching message. + * \return Negative for no match. + */ +int stasis_message_sink_wait_for(struct stasis_message_sink *sink, int start, + stasis_wait_cb cmp_cb, const void *data, int timeout_millis); + +/*! + * \brief Ensures that no new messages are received. + * + * The optional timeout prevents complete deadlock in a test. + * + * \param sink Sink to wait on. + * \param num_messages expecte \a sink->num_messages. + * \param timeout_millis Number of milliseconds to wait for. + * \return Actual sink->num_messages value at return. + * If this is < \a num_messages, then the timeout expired. + */ +int stasis_message_sink_should_stay(struct stasis_message_sink *sink, + int num_messages, int timeout_millis); + +/*! \addtogroup StasisTopicsAndMessages + * @{ + */ + +/*! + * \brief Creates a test message. + */ +struct stasis_message *stasis_test_message_create(void); + +/*! + * \brief Gets the type of messages created by stasis_test_message_create(). + */ +struct stasis_message_type *stasis_test_message_type(void); + +/*! + * @} + */ + +#endif /* _ASTERISK_STASIS_TEST_H */ |