33 #define test_category "/mwi/"
35 #define MAILBOX_PREFIX "test~"
36 #define MAILBOX_COUNT 500
37 #define MAILBOX_SIZE 32
46 static size_t sum_total;
49 static size_t running_total;
52 static int expect_zero;
54 static int num_to_mailbox(
char *mailbox,
size_t size,
size_t num)
56 if (snprintf(mailbox, 10, MAILBOX_PREFIX
"%zu", num) == -1) {
57 ast_log(LOG_ERROR,
"Unable to convert mailbox to string\n");
64 static int mailbox_to_num(
const char *mailbox,
size_t *num)
67 const char *p = strchr(mailbox,
'~');
70 ast_log(LOG_ERROR,
"Prefix separator '~' not found in '%s'\n", mailbox);
75 ast_log(LOG_ERROR,
"Unable to convert mailbox '%s' to numeric\n", mailbox);
88 if (mailbox_to_num(mwi_state->
uniqueid, &num)) {
94 val = expect_zero ? 0 : num;
98 ast_log(LOG_ERROR,
"Unexpected MWI state data for '%s', %d != %zu\n",
111 validate_data(mwi_state);
114 ao2_cleanup(mwi_state);
119 .on_unsubscribe = handle_validate
129 running_total = expect_zero = 0;
136 if (running_total != sum_total) {
137 ast_log(LOG_ERROR,
"Failed to destroy all MWI subscriptions: running=%zu, sum=%zu\n",
138 running_total, sum_total);
154 sum_total = running_total = 0;
157 for (i = 0; i < MAILBOX_COUNT; ++i) {
159 char mailbox[MAILBOX_SIZE];
161 if (num_to_mailbox(mailbox, MAILBOX_SIZE, i)) {
167 ast_log(LOG_ERROR,
"Failed to create a MWI subscriber for mailbox '%s'\n", mailbox);
172 ast_log(LOG_ERROR,
"Failed to add to MWI sub to vector for mailbox '%s'\n", mailbox);
180 if (i != MAILBOX_COUNT || running_total != sum_total) {
181 ast_log(LOG_ERROR,
"Failed to create all MWI subscriptions: running=%zu, sum=%zu\n",
182 running_total, sum_total);
183 subscriptions_destroy(subs);
190 static int publishers_destroy(
struct publishers *pubs)
201 for (i = 0; i < MAILBOX_COUNT; ++i) {
202 char mailbox[MAILBOX_SIZE];
205 if (num_to_mailbox(mailbox, MAILBOX_SIZE, i)) {
215 static int publishers_create(
struct publishers *pubs)
223 for (i = 0; i < MAILBOX_COUNT; ++i) {
225 char mailbox[MAILBOX_SIZE];
227 if (num_to_mailbox(mailbox, MAILBOX_SIZE, i)) {
234 ast_log(LOG_ERROR,
"Failed to create an MWI publisher for mailbox '%s'\n", mailbox);
239 ast_log(LOG_ERROR,
"Failed to add to an MWI publisher to vector for mailbox '%s'\n", mailbox);
245 if (i != MAILBOX_COUNT) {
246 ast_log(LOG_ERROR,
"Failed to create all MWI publishers: count=%zu\n", i);
247 publishers_destroy(pubs);
254 static int implicit_publish_cb(
struct ast_mwi_state *mwi_state,
void *data)
263 num = validate_data(mwi_state);
273 static int explicit_publish_cb(
struct ast_mwi_state *mwi_state,
void *data)
284 num = validate_data(mwi_state);
289 if (mailbox_to_num(mwi_state->
uniqueid, &num)) {
297 ast_log(LOG_ERROR,
"Unable to locate MWI publisher for mailbox '%s'\n", mwi_state->
uniqueid);
314 if (running_total != sum_total) {
315 ast_log(LOG_ERROR,
"Failed MWI state callback (1): running=%zu, sum=%zu\n",
316 running_total, sum_total);
321 running_total = expect_zero = 0;
324 if (running_total != sum_total) {
325 ast_log(LOG_ERROR,
"Failed MWI state callback (2): running=%zu, sum=%zu\n",
326 running_total, sum_total);
336 int rc = AST_TEST_PASS;
340 info->name = __func__;
341 info->category = test_category;
342 info->summary =
"Test implicit publishing of MWI state";
343 info->description = info->summary;
344 return AST_TEST_NOT_RUN;
349 ast_test_validate(
test, !subscriptions_create(&subs));
351 ast_test_validate_cleanup(
test, !publish(implicit_publish_cb, NULL),
355 if (subscriptions_destroy(&subs) || publishers_destroy(NULL)) {
356 return AST_TEST_FAIL;
366 int rc = AST_TEST_PASS;
370 info->name = __func__;
371 info->category = test_category;
372 info->summary =
"Test explicit publishing of MWI state";
373 info->description = info->summary;
374 return AST_TEST_NOT_RUN;
379 ast_test_validate(
test, !subscriptions_create(&subs));
380 ast_test_validate_cleanup(
test, !publishers_create(&pubs), rc,
cleanup);
382 ast_test_validate_cleanup(
test, !publish(explicit_publish_cb, &pubs),
386 if (subscriptions_destroy(&subs) || publishers_destroy(&pubs)) {
387 return AST_TEST_FAIL;
393 static int unload_module(
void)
395 AST_TEST_UNREGISTER(implicit_publish);
396 AST_TEST_UNREGISTER(explicit_publish);
401 static int load_module(
void)
403 AST_TEST_REGISTER(implicit_publish);
404 AST_TEST_REGISTER(explicit_publish);
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Asterisk main include file. File version handling, generic pbx functions.
int ast_str_to_umax(const char *str, uintmax_t *res)
Convert the given string to an unsigned max size integer.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
struct ast_mwi_state * ast_mwi_subscriber_data(struct ast_mwi_subscriber *sub)
Retrieves the state data object associated with the MWI subscriber.
int ast_mwi_add_observer(struct ast_mwi_observer *observer)
Add an observer to receive MWI state related events.
void(* on_subscribe)(const char *mailbox, struct ast_mwi_subscriber *sub)
Raised when MWI is being subscribed.
static void cleanup(void)
Clean up any old apps that we don't need any more.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Conversion utility functions.
int(* on_mwi_state)(struct ast_mwi_state *mwi_state, void *data)
The delegate called for each managed mailbox state.
#define AST_VECTOR(name, type)
Define a vector structure.
int ast_mwi_publish(struct ast_mwi_publisher *publisher, int urgent_msgs, int new_msgs, int old_msgs, const char *channel_id, struct ast_eid *eid)
Publish MWI for the given mailbox.
void ast_mwi_remove_observer(struct ast_mwi_observer *observer)
Remove an MWI state observer.
#define ast_delete_mwi_state(mailbox, context)
Delete MWI state cached by stasis.
void ast_mwi_state_callback_all(on_mwi_state handler, void *data)
For each managed mailbox call the given handler.
void * ast_mwi_unsubscribe_and_join(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic, block until the final message is received, and then unsubscribe fr...
const ast_string_field uniqueid
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
struct ast_mwi_publisher * ast_mwi_add_publisher(const char *mailbox)
Add an MWI state publisher to the mailbox.
MWI state event interface.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
#define AST_TEST_DEFINE(hdr)
int ast_mwi_publish_by_mailbox(const char *mailbox, const char *context, int urgent_msgs, int new_msgs, int old_msgs, const char *channel_id, struct ast_eid *eid)
Publish MWI for the given mailbox.
The structure that contains MWI state.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.