Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
test_message.c File Reference

Test module for out-of-call text message module. More...

#include "asterisk.h"
#include <regex.h>
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/message.h"
#include "asterisk/pbx.h"
#include "asterisk/manager.h"
#include "asterisk/vector.h"
Include dependency graph for test_message.c:

Go to the source code of this file.

Macros

#define DEFAULT_EXPECTED_EVENTS   4
 The number of user events we should get in a dialplan test. More...
 
#define FREE_VARIABLE_VECTOR(vector)
 
#define TEST_CATEGORY   "/main/message/"
 
#define TEST_CONTEXT   "__TEST_MESSAGE_CONTEXT__"
 
#define TEST_EXTENSION   "test_message_extension"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void ast_msg_safe_destroy (void *obj)
 
 AST_TEST_DEFINE (test_message_msg_tech_registration)
 
 AST_TEST_DEFINE (test_message_msg_handler_registration)
 
 AST_TEST_DEFINE (test_message_manipulation)
 
 AST_TEST_DEFINE (test_message_queue_dialplan_nominal)
 
 AST_TEST_DEFINE (test_message_queue_handler_nominal)
 
 AST_TEST_DEFINE (test_message_queue_both_nominal)
 
 AST_TEST_DEFINE (test_message_has_destination_dialplan)
 
 AST_TEST_DEFINE (test_message_has_destination_handler)
 
 AST_TEST_DEFINE (test_message_msg_send)
 
 AST_VECTOR (var_vector, struct ast_variable *)
 The expected user event fields. More...
 
static int create_test_dialplan (void)
 
static int handler_wait_for_message (struct ast_test *test)
 Wait for the test_msg_handler to receive the message. More...
 
static int load_module (void)
 
static int test_cleanup_cb (struct ast_test_info *info, struct ast_test *test)
 
static int test_init_cb (struct ast_test_info *info, struct ast_test *test)
 
static int test_msg_handle_msg_cb (struct ast_msg *msg)
 
static int test_msg_has_destination_cb (const struct ast_msg *msg)
 
static int test_msg_send (const struct ast_msg *msg, const char *to, const char *from)
 
static int unload_module (void)
 
static int user_event_hook_cb (int category, const char *event, char *body)
 
static int user_event_wait_for_events (struct ast_test *test, int expected_events)
 Wait for the expected number of user events to be received. More...
 
static int verify_bad_headers (struct ast_test *test)
 
static int verify_user_event_fields (int user_event, const char *header, const char *value)
 Verifies a user event header/value pair. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Out-of-call text message support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static int expected_user_events
 The number of user events we expect for this test. More...
 
static ast_cond_t handler_cond
 Condition wait variable for test_msg_handler receiving message. More...
 
static ast_mutex_t handler_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Mutex for handler_cond. More...
 
static int handler_received_message
 Predicate for the test_message_handler receiving a message. More...
 
static int message_received
 
static int received_user_events
 The current number of received user events. More...
 
static struct ast_msg_handler test_msg_handler
 Our test message handler. More...
 
static ast_cond_t user_event_cond
 Condition wait variable for all dialplan user events being received. More...
 
static struct manager_custom_hook user_event_hook
 AMI event hook that verifies whether or not we've gotten our user events. More...
 
static ast_mutex_t user_event_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Mutex for user_event_cond. More...
 

Detailed Description

Test module for out-of-call text message module.

Author
Matt Jordan <[email protected]> 

Definition in file test_message.c.

Macro Definition Documentation

◆ DEFAULT_EXPECTED_EVENTS

#define DEFAULT_EXPECTED_EVENTS   4

The number of user events we should get in a dialplan test.

Definition at line 50 of file test_message.c.

Referenced by AST_TEST_DEFINE(), and test_init_cb().

◆ FREE_VARIABLE_VECTOR

#define FREE_VARIABLE_VECTOR (   vector)

Definition at line 787 of file test_message.c.

Referenced by test_cleanup_cb().

◆ TEST_CATEGORY

#define TEST_CATEGORY   "/main/message/"

Definition at line 44 of file test_message.c.

Referenced by AST_TEST_DEFINE(), and load_module().

◆ TEST_CONTEXT

#define TEST_CONTEXT   "__TEST_MESSAGE_CONTEXT__"

Definition at line 46 of file test_message.c.

Referenced by AST_TEST_DEFINE(), and create_test_dialplan().

◆ TEST_EXTENSION

#define TEST_EXTENSION   "test_message_extension"

Definition at line 47 of file test_message.c.

Referenced by AST_TEST_DEFINE(), and create_test_dialplan().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 881 of file test_message.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 881 of file test_message.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 881 of file test_message.c.

◆ ast_msg_safe_destroy()

static void ast_msg_safe_destroy ( void *  obj)
static

Definition at line 365 of file test_message.c.

References ast_msg_destroy().

Referenced by AST_TEST_DEFINE().

366 {
367  struct ast_msg *msg = obj;
368 
369  if (msg) {
370  ast_msg_destroy(msg);
371  }
372 }
A message.
Definition: message.c:233
struct ast_msg * ast_msg_destroy(struct ast_msg *msg)
Destroy an ast_msg.
Definition: message.c:448

◆ AST_TEST_DEFINE() [1/9]

AST_TEST_DEFINE ( test_message_msg_tech_registration  )

Definition at line 299 of file test_message.c.

References ast_msg_tech_register(), ast_msg_tech_unregister(), AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

300 {
301  int reg_result;
302 
303  switch (cmd) {
304  case TEST_INIT:
305  info->name = __func__;
306  info->category = TEST_CATEGORY;
307  info->summary = "Test register/unregister of a message tech";
308  info->description =
309  "Test that:\n"
310  "\tA message technology can be registered once only\n"
311  "\tA registered message technology can be unregistered once only";
312  return AST_TEST_NOT_RUN;
313  case TEST_EXECUTE:
314  break;
315  }
316 
317  reg_result = ast_msg_tech_register(&test_msg_tech);
318  ast_test_validate(test, reg_result == 0);
319 
320  reg_result = ast_msg_tech_register(&test_msg_tech);
321  ast_test_validate(test, reg_result == -1);
322 
323  reg_result = ast_msg_tech_unregister(&test_msg_tech);
324  ast_test_validate(test, reg_result == 0);
325 
326  reg_result = ast_msg_tech_unregister(&test_msg_tech);
327  ast_test_validate(test, reg_result == -1);
328 
329  return AST_TEST_PASS;
330 }
int ast_msg_tech_register(const struct ast_msg_tech *tech)
Register a message technology.
Definition: message.c:1569
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
Unregister a message technology.
Definition: message.c:1610
def info(msg)

◆ AST_TEST_DEFINE() [2/9]

AST_TEST_DEFINE ( test_message_msg_handler_registration  )

Definition at line 332 of file test_message.c.

References ast_msg_handler_register(), ast_msg_handler_unregister(), AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

333 {
334  int reg_result;
335 
336  switch (cmd) {
337  case TEST_INIT:
338  info->name = __func__;
339  info->category = TEST_CATEGORY;
340  info->summary = "Test register/unregister of a message handler";
341  info->description =
342  "Test that:\n"
343  "\tA message handler can be registered once only\n"
344  "\tA registered message handler can be unregistered once only";
345  return AST_TEST_NOT_RUN;
346  case TEST_EXECUTE:
347  break;
348  }
349 
351  ast_test_validate(test, reg_result == 0);
352 
354  ast_test_validate(test, reg_result == -1);
355 
357  ast_test_validate(test, reg_result == 0);
358 
360  ast_test_validate(test, reg_result == -1);
361 
362  return AST_TEST_PASS;
363 }
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
Definition: message.c:1671
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
Definition: message.c:1629
#define TEST_CATEGORY
Definition: test_message.c:44
static struct ast_msg_handler test_msg_handler
Our test message handler.
Definition: test_message.c:90
def info(msg)

◆ AST_TEST_DEFINE() [3/9]

AST_TEST_DEFINE ( test_message_manipulation  )

Definition at line 374 of file test_message.c.

References ast_msg_alloc(), ast_msg_get_body(), ast_msg_get_endpoint(), ast_msg_get_from(), ast_msg_get_tech(), ast_msg_get_to(), ast_msg_get_var(), ast_msg_safe_destroy(), ast_msg_set_body(), ast_msg_set_endpoint(), ast_msg_set_from(), ast_msg_set_tech(), ast_msg_set_to(), ast_msg_set_var(), ast_msg_set_var_outbound(), ast_msg_var_iterator_destroy(), ast_msg_var_iterator_init(), ast_msg_var_iterator_next(), ast_msg_var_unref_current(), AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), NULL, RAII_VAR, result, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

375 {
376  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
378  int result;
379  const char *actual;
380  const char *out_name;
381  const char *out_value;
382 
383  switch (cmd) {
384  case TEST_INIT:
385  info->name = __func__;
386  info->category = TEST_CATEGORY;
387  info->summary = "Test manipulating properties of a message";
388  info->description =
389  "This test covers the following:\n"
390  "\tSetting/getting the body\n"
391  "\tSetting/getting inbound/outbound variables\n"
392  "\tIterating over variables";
393  return AST_TEST_NOT_RUN;
394  case TEST_EXECUTE:
395  break;
396  }
397 
398  msg = ast_msg_alloc();
399  ast_test_validate(test, msg != NULL);
400 
401  /* Test setting/getting to */
402  result = ast_msg_set_to(msg, "testmsg:%s", "foo");
403  ast_test_validate(test, result == 0);
404  actual = ast_msg_get_to(msg);
405  ast_test_validate(test, !strcmp(actual, "testmsg:foo"));
406 
407  /* Test setting/getting from */
408  result = ast_msg_set_from(msg, "testmsg:%s", "bar");
409  ast_test_validate(test, result == 0);
410  actual = ast_msg_get_from(msg);
411  ast_test_validate(test, !strcmp(actual, "testmsg:bar"));
412 
413  /* Test setting/getting body */
414  result = ast_msg_set_body(msg, "BodyTest: %s", "foo");
415  ast_test_validate(test, result == 0);
416  actual = ast_msg_get_body(msg);
417  ast_test_validate(test, !strcmp(actual, "BodyTest: foo"));
418 
419  /* Test setting/getting technology */
420  result = ast_msg_set_tech(msg, "%s", "my_tech");
421  ast_test_validate(test, result == 0);
422  actual = ast_msg_get_tech(msg);
423  ast_test_validate(test, !strcmp(actual, "my_tech"));
424 
425  /* Test setting/getting endpoint */
426  result = ast_msg_set_endpoint(msg, "%s", "terminus");
427  ast_test_validate(test, result == 0);
428  actual = ast_msg_get_endpoint(msg);
429  ast_test_validate(test, !strcmp(actual, "terminus"));
430 
431  /* Test setting/getting non-outbound variable */
432  result = ast_msg_set_var(msg, "foo", "bar");
433  ast_test_validate(test, result == 0);
434  actual = ast_msg_get_var(msg, "foo");
435  ast_test_validate(test, !strcmp(actual, "bar"));
436 
437  /* Test updating existing variable */
438  result = ast_msg_set_var(msg, "foo", "new_bar");
439  ast_test_validate(test, result == 0);
440  actual = ast_msg_get_var(msg, "foo");
441  ast_test_validate(test, !strcmp(actual, "new_bar"));
442 
443  /* Verify a non-outbound variable is not iterable */
444  it_vars = ast_msg_var_iterator_init(msg);
445  ast_test_validate(test, it_vars != NULL);
446  ast_test_validate(test, ast_msg_var_iterator_next(msg, it_vars, &out_name, &out_value) == 0);
448 
449  /* Test updating an existing variable as an outbound variable */
450  result = ast_msg_set_var_outbound(msg, "foo", "outbound_bar");
451  ast_test_validate(test, result == 0);
452  it_vars = ast_msg_var_iterator_init(msg);
453  ast_test_validate(test, it_vars != NULL);
454  result = ast_msg_var_iterator_next(msg, it_vars, &out_name, &out_value);
455  ast_test_validate(test, result == 1);
456  ast_test_validate(test, !strcmp(out_name, "foo"));
457  ast_test_validate(test, !strcmp(out_value, "outbound_bar"));
458  ast_msg_var_unref_current(it_vars);
459  result = ast_msg_var_iterator_next(msg, it_vars, &out_name, &out_value);
460  ast_test_validate(test, result == 0);
461 
462  return AST_TEST_PASS;
463 }
int ast_msg_set_tech(struct ast_msg *msg, const char *fmt,...)
Set the technology associated with this message.
Definition: message.c:509
const char * ast_msg_get_var(struct ast_msg *msg, const char *name)
Get the specified variable on the message.
Definition: message.c:620
const char * ast_msg_get_tech(const struct ast_msg *msg)
Retrieve the technology associated with this message.
Definition: message.c:546
const char * ast_msg_get_endpoint(const struct ast_msg *msg)
Retrieve the endpoint associated with this message.
Definition: message.c:551
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value)
Get the next variable name and value that is set for sending outbound.
Definition: message.c:689
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
const char * ast_msg_get_body(const struct ast_msg *msg)
Get the body of a message.
Definition: message.c:531
void ast_msg_var_iterator_destroy(struct ast_msg_var_iterator *iter)
Destroy a message variable iterator.
Definition: message.c:706
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
const char * ast_msg_get_to(const struct ast_msg *msg)
Retrieve the destination of this message.
Definition: message.c:541
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter)
Unref a message var from inside an iterator loop.
Definition: message.c:700
int ast_msg_set_var(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message going to the dialplan.
Definition: message.c:615
const char * ast_msg_get_from(const struct ast_msg *msg)
Retrieve the source of this message.
Definition: message.c:536
def info(msg)
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
int ast_msg_set_endpoint(struct ast_msg *msg, const char *fmt,...)
Set the technology&#39;s endpoint associated with this message.
Definition: message.c:520
int ast_msg_set_var_outbound(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message being sent to a message tech directly.
Definition: message.c:610
static PGresult * result
Definition: cel_pgsql.c:88
A message.
Definition: message.c:233
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365
struct ast_msg_var_iterator * ast_msg_var_iterator_init(const struct ast_msg *msg)
Create a new message variable iterator.
Definition: message.c:644

◆ AST_TEST_DEFINE() [4/9]

AST_TEST_DEFINE ( test_message_queue_dialplan_nominal  )

Definition at line 465 of file test_message.c.

References ast_msg_alloc(), ast_msg_queue(), ast_msg_safe_destroy(), ast_msg_set_body(), ast_msg_set_context(), ast_msg_set_exten(), ast_msg_set_from(), ast_msg_set_to(), ast_msg_set_var_outbound(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_variable_list_append, ast_variable_new, AST_VECTOR_REPLACE, DEFAULT_EXPECTED_EVENTS, sip_to_pjsip::info(), NULL, RAII_VAR, TEST_CATEGORY, TEST_CONTEXT, TEST_EXECUTE, TEST_EXTENSION, TEST_INIT, user_event_wait_for_events(), and verify_bad_headers().

466 {
467  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
468  struct ast_variable *expected;
469  struct ast_variable *expected_response = NULL;
470 
471  switch (cmd) {
472  case TEST_INIT:
473  info->name = __func__;
474  info->category = TEST_CATEGORY;
475  info->summary = "Test enqueueing messages to the dialplan";
476  info->description =
477  "Test that a message enqueued for the dialplan is\n"
478  "passed to that particular extension";
479  return AST_TEST_NOT_RUN;
480  case TEST_EXECUTE:
481  break;
482  }
483 
484  msg = ast_msg_alloc();
485  ast_test_validate(test, msg != NULL);
486 
487  expected = ast_variable_new("Verify","^To$", __FILE__);
488  ast_variable_list_append(&expected_response, expected);
489  expected = ast_variable_new("Value","^foo$", __FILE__);
490  ast_variable_list_append(&expected_response, expected);
491  AST_VECTOR_REPLACE(&expected_user_event_fields, 0, expected_response);
492 
493  expected_response = NULL;
494  expected = ast_variable_new("Verify", "^From$", __FILE__);
495  ast_variable_list_append(&expected_response, expected);
496  expected = ast_variable_new("Value","^bar$", __FILE__);
497  ast_variable_list_append(&expected_response, expected);
498  AST_VECTOR_REPLACE(&expected_user_event_fields, 1, expected_response);
499 
500  expected_response = NULL;
501  expected = ast_variable_new("Verify", "^Body$", __FILE__);
502  ast_variable_list_append(&expected_response, expected);
503  expected = ast_variable_new("Value", "^a body$", __FILE__);
504  ast_variable_list_append(&expected_response, expected);
505  AST_VECTOR_REPLACE(&expected_user_event_fields, 2, expected_response);
506 
507  expected_response = NULL;
508  expected = ast_variable_new("Verify", "^Custom$", __FILE__);
509  ast_variable_list_append(&expected_response, expected);
510  expected = ast_variable_new("Value", "^field$", __FILE__);
511  ast_variable_list_append(&expected_response, expected);
512  AST_VECTOR_REPLACE(&expected_user_event_fields, 3, expected_response);
513 
514  ast_msg_set_to(msg, "foo");
515  ast_msg_set_from(msg, "bar");
516  ast_msg_set_body(msg, "a body");
517  ast_msg_set_var_outbound(msg, "custom_data", "field");
518 
521 
522  ast_msg_queue(msg);
523  msg = NULL;
524 
526  ast_test_status_update(test, "Failed to received %d expected user events\n", DEFAULT_EXPECTED_EVENTS);
527  return AST_TEST_FAIL;
528  }
529 
530  if (verify_bad_headers(test)) {
531  return AST_TEST_FAIL;
532  }
533 
534  return AST_TEST_PASS;
535 }
#define TEST_EXTENSION
Definition: test_message.c:47
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
static int verify_bad_headers(struct ast_test *test)
Definition: test_message.c:274
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
#define TEST_CONTEXT
Definition: test_message.c:46
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_variable_new(name, value, filename)
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
Definition: message.c:958
def info(msg)
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: message.c:498
#define DEFAULT_EXPECTED_EVENTS
The number of user events we should get in a dialplan test.
Definition: test_message.c:50
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
int ast_msg_set_var_outbound(struct ast_msg *msg, const char *name, const char *value)
Set a variable on the message being sent to a message tech directly.
Definition: message.c:610
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:284
A message.
Definition: message.c:233
static int user_event_wait_for_events(struct ast_test *test, int expected_events)
Wait for the expected number of user events to be received.
Definition: test_message.c:251
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365
#define ast_variable_list_append(head, new_var)

◆ AST_TEST_DEFINE() [5/9]

AST_TEST_DEFINE ( test_message_queue_handler_nominal  )

Definition at line 537 of file test_message.c.

References ast_msg_alloc(), ast_msg_handler_register(), ast_msg_handler_unregister(), ast_msg_queue(), ast_msg_safe_destroy(), ast_msg_set_body(), ast_msg_set_from(), ast_msg_set_to(), AST_TEST_NOT_RUN, AST_TEST_PASS, handler_wait_for_message(), sip_to_pjsip::info(), NULL, RAII_VAR, result, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

538 {
539  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
540  int result;
541 
542  switch (cmd) {
543  case TEST_INIT:
544  info->name = __func__;
545  info->category = TEST_CATEGORY;
546  info->summary = "Test enqueueing messages to a handler";
547  info->description =
548  "Test that a message enqueued can be handled by a\n"
549  "non-dialplan handler";
550  return AST_TEST_NOT_RUN;
551  case TEST_EXECUTE:
552  break;
553  }
554 
555  msg = ast_msg_alloc();
556  ast_test_validate(test, msg != NULL);
557 
559  ast_test_validate(test, result == 0);
560 
561  ast_msg_set_to(msg, "foo");
562  ast_msg_set_from(msg, "bar");
563  ast_msg_set_body(msg, "a body");
564 
565  ast_msg_queue(msg);
566  msg = NULL;
567 
568  /* This will automatically fail the test if we don't get the message */
570 
572  ast_test_validate(test, result == 0);
573 
574  return AST_TEST_PASS;
575 }
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
Definition: message.c:1671
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
Definition: message.c:1629
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
Definition: message.c:958
static struct ast_msg_handler test_msg_handler
Our test message handler.
Definition: test_message.c:90
def info(msg)
static int handler_wait_for_message(struct ast_test *test)
Wait for the test_msg_handler to receive the message.
Definition: test_message.c:230
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
static PGresult * result
Definition: cel_pgsql.c:88
A message.
Definition: message.c:233
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365

◆ AST_TEST_DEFINE() [6/9]

AST_TEST_DEFINE ( test_message_queue_both_nominal  )

Definition at line 577 of file test_message.c.

References ast_msg_alloc(), ast_msg_handler_register(), ast_msg_handler_unregister(), ast_msg_queue(), ast_msg_safe_destroy(), ast_msg_set_body(), ast_msg_set_context(), ast_msg_set_exten(), ast_msg_set_from(), ast_msg_set_to(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_set_result(), ast_test_status_update, ast_variable_list_append, ast_variable_new, AST_VECTOR_REPLACE, DEFAULT_EXPECTED_EVENTS, handler_wait_for_message(), sip_to_pjsip::info(), NULL, RAII_VAR, result, TEST_CATEGORY, TEST_CONTEXT, TEST_EXECUTE, TEST_EXTENSION, TEST_INIT, user_event_wait_for_events(), and verify_bad_headers().

578 {
579  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
580  struct ast_variable *expected;
581  struct ast_variable *expected_response = NULL;
582  int result;
583 
584  switch (cmd) {
585  case TEST_INIT:
586  info->name = __func__;
587  info->category = TEST_CATEGORY;
588  info->summary = "Test enqueueing messages to a dialplan and custom handler";
589  info->description =
590  "Test that a message enqueued is passed to all\n"
591  "handlers that can process it, dialplan as well as\n"
592  "a custom handler";
593  return AST_TEST_NOT_RUN;
594  case TEST_EXECUTE:
595  break;
596  }
597 
598  msg = ast_msg_alloc();
599  ast_test_validate(test, msg != NULL);
600 
602  ast_test_validate(test, result == 0);
603 
604  expected = ast_variable_new("Verify","^To$", __FILE__);
605  ast_variable_list_append(&expected_response, expected);
606  expected = ast_variable_new("Value","^foo$", __FILE__);
607  ast_variable_list_append(&expected_response, expected);
608  AST_VECTOR_REPLACE(&expected_user_event_fields, 0, expected_response);
609 
610  expected_response = NULL;
611  expected = ast_variable_new("Verify", "^From$", __FILE__);
612  ast_variable_list_append(&expected_response, expected);
613  expected = ast_variable_new("Value","^bar$", __FILE__);
614  ast_variable_list_append(&expected_response, expected);
615  AST_VECTOR_REPLACE(&expected_user_event_fields, 1, expected_response);
616 
617  expected_response = NULL;
618  expected = ast_variable_new("Verify", "^Body$", __FILE__);
619  ast_variable_list_append(&expected_response, expected);
620  expected = ast_variable_new("Value", "^a body$", __FILE__);
621  ast_variable_list_append(&expected_response, expected);
622  AST_VECTOR_REPLACE(&expected_user_event_fields, 2, expected_response);
623 
624  ast_msg_set_to(msg, "foo");
625  ast_msg_set_from(msg, "bar");
626  ast_msg_set_body(msg, "a body");
627 
630 
631  ast_msg_queue(msg);
632  msg = NULL;
633 
635  ast_test_status_update(test, "Failed to received %d expected user events\n", DEFAULT_EXPECTED_EVENTS);
637  }
638 
639  /* This will automatically fail the test if we don't get the message */
641 
643  ast_test_validate(test, result == 0);
644 
645  if (verify_bad_headers(test)) {
646  return AST_TEST_FAIL;
647  }
648 
649  return AST_TEST_PASS;
650 }
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
Definition: message.c:1671
#define TEST_EXTENSION
Definition: test_message.c:47
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
int ast_msg_set_body(struct ast_msg *msg, const char *fmt,...)
Set the &#39;body&#39; text of a message (in UTF-8)
Definition: message.c:476
static int verify_bad_headers(struct ast_test *test)
Definition: test_message.c:274
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
Definition: message.c:1629
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
#define TEST_CONTEXT
Definition: test_message.c:46
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_variable_new(name, value, filename)
int ast_msg_queue(struct ast_msg *msg)
Queue a message for routing through the dialplan.
Definition: message.c:958
static struct ast_msg_handler test_msg_handler
Our test message handler.
Definition: test_message.c:90
def info(msg)
void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state)
Definition: test.c:262
static int handler_wait_for_message(struct ast_test *test)
Wait for the test_msg_handler to receive the message.
Definition: test_message.c:230
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: message.c:498
#define DEFAULT_EXPECTED_EVENTS
The number of user events we should get in a dialplan test.
Definition: test_message.c:50
int ast_msg_set_from(struct ast_msg *msg, const char *fmt,...)
Set the &#39;from&#39; URI of a message.
Definition: message.c:465
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:284
A message.
Definition: message.c:233
static int user_event_wait_for_events(struct ast_test *test, int expected_events)
Wait for the expected number of user events to be received.
Definition: test_message.c:251
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365
#define ast_variable_list_append(head, new_var)

◆ AST_TEST_DEFINE() [7/9]

AST_TEST_DEFINE ( test_message_has_destination_dialplan  )

Definition at line 652 of file test_message.c.

References ast_msg_alloc(), ast_msg_has_destination(), ast_msg_safe_destroy(), ast_msg_set_context(), ast_msg_set_exten(), AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), NULL, RAII_VAR, TEST_CATEGORY, TEST_CONTEXT, TEST_EXECUTE, TEST_EXTENSION, and TEST_INIT.

653 {
654  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
655 
656  switch (cmd) {
657  case TEST_INIT:
658  info->name = __func__;
659  info->category = TEST_CATEGORY;
660  info->summary = "Test checking for a dialplan destination";
661  info->description =
662  "Test that a message's destination is verified via the\n"
663  "dialplan";
664  return AST_TEST_NOT_RUN;
665  case TEST_EXECUTE:
666  break;
667  }
668 
669  msg = ast_msg_alloc();
670  ast_test_validate(test, msg != NULL);
671 
674  ast_test_validate(test, ast_msg_has_destination(msg) == 1);
675 
676  ast_msg_set_context(msg, "__I_SHOULD_NOT_EXIST_PLZ__");
677  ast_test_validate(test, ast_msg_has_destination(msg) == 0);
678 
680  ast_msg_set_exten(msg, "__I_SHOULD_NOT_EXIST_PLZ__");
681  ast_test_validate(test, ast_msg_has_destination(msg) == 0);
682 
683  ast_msg_set_exten(msg, NULL);
684  ast_test_validate(test, ast_msg_has_destination(msg) == 0);
685 
688  ast_test_validate(test, ast_msg_has_destination(msg) == 0);
689 
690  return AST_TEST_PASS;
691 }
#define TEST_EXTENSION
Definition: test_message.c:47
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
#define TEST_CONTEXT
Definition: test_message.c:46
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
def info(msg)
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: message.c:498
int ast_msg_has_destination(const struct ast_msg *msg)
Determine if a particular message has a destination via some handler.
Definition: message.c:937
A message.
Definition: message.c:233
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365

◆ AST_TEST_DEFINE() [8/9]

AST_TEST_DEFINE ( test_message_has_destination_handler  )

Definition at line 693 of file test_message.c.

References ast_msg_alloc(), ast_msg_handler_register(), ast_msg_handler_unregister(), ast_msg_has_destination(), ast_msg_safe_destroy(), ast_msg_set_context(), ast_msg_set_exten(), ast_msg_set_to(), AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), NULL, RAII_VAR, result, TEST_CATEGORY, TEST_CONTEXT, TEST_EXECUTE, and TEST_INIT.

694 {
695  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
696  int result;
697 
698  switch (cmd) {
699  case TEST_INIT:
700  info->name = __func__;
701  info->category = TEST_CATEGORY;
702  info->summary = "Test checking for a handler destination";
703  info->description =
704  "Test that a message's destination is verified via a\n"
705  "handler";
706  return AST_TEST_NOT_RUN;
707  case TEST_EXECUTE:
708  break;
709  }
710 
712  ast_test_validate(test, result == 0);
713 
714  msg = ast_msg_alloc();
715  ast_test_validate(test, msg != NULL);
716 
717  ast_msg_set_to(msg, "foo");
719  ast_msg_set_exten(msg, NULL);
720  ast_test_validate(test, ast_msg_has_destination(msg) == 1);
721 
723  ast_test_validate(test, ast_msg_has_destination(msg) == 1);
724 
725  ast_msg_set_to(msg, "__I_SHOULD_NOT_EXIST_PLZ__");
726  ast_test_validate(test, ast_msg_has_destination(msg) == 0);
727 
729  ast_test_validate(test, result == 0);
730 
731  return AST_TEST_PASS;
732 }
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
Definition: message.c:1671
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
Definition: message.c:1629
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
#define TEST_CONTEXT
Definition: test_message.c:46
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct ast_msg_handler test_msg_handler
Our test message handler.
Definition: test_message.c:90
def info(msg)
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: message.c:498
int ast_msg_has_destination(const struct ast_msg *msg)
Determine if a particular message has a destination via some handler.
Definition: message.c:937
static PGresult * result
Definition: cel_pgsql.c:88
A message.
Definition: message.c:233
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365

◆ AST_TEST_DEFINE() [9/9]

AST_TEST_DEFINE ( test_message_msg_send  )

Definition at line 734 of file test_message.c.

References ast_msg_alloc(), ast_msg_handler_register(), ast_msg_handler_unregister(), ast_msg_has_destination(), ast_msg_safe_destroy(), ast_msg_send(), ast_msg_set_context(), ast_msg_set_exten(), ast_msg_set_to(), ast_msg_tech_register(), ast_msg_tech_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_set_result(), ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, TEST_CATEGORY, TEST_CONTEXT, TEST_EXECUTE, and TEST_INIT.

735 {
736  RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
737 
738  switch (cmd) {
739  case TEST_INIT:
740  info->name = __func__;
741  info->category = TEST_CATEGORY;
742  info->summary = "Test message routing";
743  info->description =
744  "Test that a message can be routed if it has\n"
745  "a valid handler";
746  return AST_TEST_NOT_RUN;
747  case TEST_EXECUTE:
748  break;
749  }
750 
751  ast_test_validate(test, ast_msg_tech_register(&test_msg_tech) == 0);
752  ast_test_validate(test, ast_msg_handler_register(&test_msg_handler) == 0);
753 
754  msg = ast_msg_alloc();
755  ast_test_validate(test, msg != NULL);
756 
757  ast_msg_set_to(msg, "foo");
759  ast_msg_set_exten(msg, NULL);
760  ast_test_validate(test, ast_msg_has_destination(msg) == 1);
761 
762  if (!ast_msg_send(msg, "testmsg:foo", "blah")) {
763  msg = NULL;
764  } else {
765  ast_test_status_update(test, "Failed to send message\n");
767  }
768 
769  ast_test_validate(test, ast_msg_handler_unregister(&test_msg_handler) == 0);
770  ast_test_validate(test, ast_msg_tech_unregister(&test_msg_tech) == 0);
771 
772  return AST_TEST_PASS;
773 }
int ast_msg_handler_unregister(const struct ast_msg_handler *handler)
Unregister a ast_msg_handler.
Definition: message.c:1671
int ast_msg_set_context(struct ast_msg *msg, const char *fmt,...)
Set the dialplan context for this message.
Definition: message.c:487
int ast_msg_handler_register(const struct ast_msg_handler *handler)
Register a ast_msg_handler.
Definition: message.c:1629
struct ast_msg * ast_msg_alloc(void)
Allocate a message.
Definition: message.c:418
int ast_msg_tech_register(const struct ast_msg_tech *tech)
Register a message technology.
Definition: message.c:1569
#define NULL
Definition: resample.c:96
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_msg_set_to(struct ast_msg *msg, const char *fmt,...)
Set the &#39;to&#39; URI of a message.
Definition: message.c:454
int ast_msg_send(struct ast_msg *msg, const char *to, const char *from)
Send a msg directly to an endpoint.
Definition: message.c:1369
#define TEST_CONTEXT
Definition: test_message.c:46
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_msg_tech_unregister(const struct ast_msg_tech *tech)
Unregister a message technology.
Definition: message.c:1610
static struct ast_msg_handler test_msg_handler
Our test message handler.
Definition: test_message.c:90
def info(msg)
void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state)
Definition: test.c:262
int ast_msg_set_exten(struct ast_msg *msg, const char *fmt,...)
Set the dialplan extension for this message.
Definition: message.c:498
int ast_msg_has_destination(const struct ast_msg *msg)
Determine if a particular message has a destination via some handler.
Definition: message.c:937
A message.
Definition: message.c:233
static void ast_msg_safe_destroy(void *obj)
Definition: test_message.c:365

◆ AST_VECTOR()

AST_VECTOR ( var_vector  ,
struct ast_variable  
)

The expected user event fields.

Definition at line 74 of file test_message.c.

81  {
82  .name = "testmsg",
83  .msg_send = test_msg_send,
84 };
static int test_msg_send(const struct ast_msg *msg, const char *to, const char *from)
Definition: test_message.c:170

◆ create_test_dialplan()

static int create_test_dialplan ( void  )
static

Definition at line 828 of file test_message.c.

References ast_add_extension(), ast_context_find_or_create(), ast_manager_register_hook(), AST_MODULE, NULL, TEST_CONTEXT, and TEST_EXTENSION.

Referenced by load_module().

829 {
830  int res = 0;
831 
833  return -1;
834  }
835 
837  "UserEvent", "TestMessageUnitTest,Verify:To,Value:${MESSAGE(to)}",
838  NULL, AST_MODULE);
840  "UserEvent", "TestMessageUnitTest,Verify:From,Value:${MESSAGE(from)}",
841  NULL, AST_MODULE);
843  "UserEvent", "TestMessageUnitTest,Verify:Body,Value:${MESSAGE(body)}",
844  NULL, AST_MODULE);
846  "UserEvent", "TestMessageUnitTest,Verify:Custom,Value:${MESSAGE_DATA(custom_data)}",
847  NULL, AST_MODULE);
849  "Set", "MESSAGE_DATA(custom_data)=${MESSAGE_DATA(custom_data)}",
850  NULL, AST_MODULE);
852  "MessageSend", "testmsg:${MESSAGE(from)},testmsg:${MESSAGE(to)}",
853  NULL, AST_MODULE);
854 
856 
857  return res;
858 }
#define TEST_EXTENSION
Definition: test_message.c:47
void ast_manager_register_hook(struct manager_custom_hook *hook)
Add a custom hook to be called when an event is fired.
Definition: manager.c:1934
#define NULL
Definition: resample.c:96
#define TEST_CONTEXT
Definition: test_message.c:46
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
Definition: pbx.c:6970
#define AST_MODULE
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:6198
static struct manager_custom_hook user_event_hook
AMI event hook that verifies whether or not we&#39;ve gotten our user events.
Definition: test_message.c:99

◆ handler_wait_for_message()

static int handler_wait_for_message ( struct ast_test test)
static

Wait for the test_msg_handler to receive the message.

Definition at line 230 of file test_message.c.

References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, AST_TEST_FAIL, ast_test_set_result(), ast_test_status_update, ast_tv(), ast_tvadd(), ast_tvnow(), error(), handler_cond, handler_lock, and handler_received_message.

Referenced by AST_TEST_DEFINE().

231 {
232  int error = 0;
233  struct timeval wait = ast_tvadd(ast_tvnow(), ast_tv(5 /* seconds */, 0));
234  struct timespec wait_time = { .tv_sec = wait.tv_sec, .tv_nsec = wait.tv_usec * 1000 };
235 
237  while (!handler_received_message) {
238  error = ast_cond_timedwait(&handler_cond, &handler_lock, &wait_time);
239  if (error == ETIMEDOUT) {
240  ast_test_status_update(test, "Test timed out while waiting for handler to get message\n");
242  break;
243  }
244  }
246 
247  return (error != ETIMEDOUT);
248 }
static int handler_received_message
Predicate for the test_message_handler receiving a message.
Definition: test_message.c:59
static ast_mutex_t handler_lock
Mutex for handler_cond.
Definition: test_message.c:71
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
static ast_cond_t handler_cond
Condition wait variable for test_msg_handler receiving message.
Definition: test_message.c:68
void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state)
Definition: test.c:262
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
int error(const char *format,...)
Definition: utils/frame.c:999
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ load_module()

static int load_module ( void  )
static

Definition at line 860 of file test_message.c.

References AST_MODULE_LOAD_SUCCESS, AST_TEST_REGISTER, ast_test_register_cleanup(), ast_test_register_init(), create_test_dialplan(), TEST_CATEGORY, test_cleanup_cb(), and test_init_cb().

861 {
862  AST_TEST_REGISTER(test_message_msg_tech_registration);
863  AST_TEST_REGISTER(test_message_msg_handler_registration);
864  AST_TEST_REGISTER(test_message_manipulation);
865  AST_TEST_REGISTER(test_message_queue_dialplan_nominal);
866  AST_TEST_REGISTER(test_message_queue_handler_nominal);
867  AST_TEST_REGISTER(test_message_queue_both_nominal);
868  AST_TEST_REGISTER(test_message_has_destination_dialplan);
869  AST_TEST_REGISTER(test_message_has_destination_handler);
870  AST_TEST_REGISTER(test_message_msg_send);
871 
873 
876 
878 }
static int test_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_message.c:801
int ast_test_register_init(const char *category, ast_test_init_cb_t *cb)
Definition: test.c:160
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define TEST_CATEGORY
Definition: test_message.c:44
int ast_test_register_cleanup(const char *category, ast_test_cleanup_cb_t *cb)
Definition: test.c:177
static int test_init_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_message.c:775
static int create_test_dialplan(void)
Definition: test_message.c:828

◆ test_cleanup_cb()

static int test_cleanup_cb ( struct ast_test_info info,
struct ast_test test 
)
static

Definition at line 801 of file test_message.c.

References FREE_VARIABLE_VECTOR.

Referenced by load_module().

802 {
803  FREE_VARIABLE_VECTOR(expected_user_event_fields);
804  FREE_VARIABLE_VECTOR(bad_headers);
805 
806  return 0;
807 }
#define FREE_VARIABLE_VECTOR(vector)
Definition: test_message.c:787

◆ test_init_cb()

static int test_init_cb ( struct ast_test_info info,
struct ast_test test 
)
static

Definition at line 775 of file test_message.c.

References AST_VECTOR_INIT, DEFAULT_EXPECTED_EVENTS, handler_received_message, message_received, and received_user_events.

Referenced by load_module().

776 {
779  message_received = 0;
780 
781  AST_VECTOR_INIT(&expected_user_event_fields, DEFAULT_EXPECTED_EVENTS);
783 
784  return 0;
785 }
static int handler_received_message
Predicate for the test_message_handler receiving a message.
Definition: test_message.c:59
static int message_received
Definition: test_message.c:168
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
static int received_user_events
The current number of received user events.
Definition: test_message.c:53
#define DEFAULT_EXPECTED_EVENTS
The number of user events we should get in a dialplan test.
Definition: test_message.c:50

◆ test_msg_handle_msg_cb()

static int test_msg_handle_msg_cb ( struct ast_msg msg)
static

Definition at line 177 of file test_message.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, handler_cond, handler_lock, and handler_received_message.

178 {
183 
184  return 0;
185 }
static int handler_received_message
Predicate for the test_message_handler receiving a message.
Definition: test_message.c:59
static ast_mutex_t handler_lock
Mutex for handler_cond.
Definition: test_message.c:71
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
static ast_cond_t handler_cond
Condition wait variable for test_msg_handler receiving message.
Definition: test_message.c:68
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ test_msg_has_destination_cb()

static int test_msg_has_destination_cb ( const struct ast_msg msg)
static

Definition at line 187 of file test_message.c.

References ast_msg_get_to(), and ast_strlen_zero.

188 {
189  /* We only care about one destination: foo! */
190  if (ast_strlen_zero(ast_msg_get_to(msg))) {
191  return 0;
192  }
193  return (!strcmp(ast_msg_get_to(msg), "foo") ? 1 : 0);
194 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * ast_msg_get_to(const struct ast_msg *msg)
Retrieve the destination of this message.
Definition: message.c:541

◆ test_msg_send()

static int test_msg_send ( const struct ast_msg msg,
const char *  to,
const char *  from 
)
static

Definition at line 170 of file test_message.c.

References message_received.

171 {
172  message_received = 1;
173 
174  return 0;
175 }
static int message_received
Definition: test_message.c:168

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 809 of file test_message.c.

References ast_context_destroy(), ast_manager_unregister_hook(), AST_MODULE, AST_TEST_UNREGISTER, and NULL.

810 {
811  AST_TEST_UNREGISTER(test_message_msg_tech_registration);
812  AST_TEST_UNREGISTER(test_message_msg_handler_registration);
813  AST_TEST_UNREGISTER(test_message_manipulation);
814  AST_TEST_UNREGISTER(test_message_queue_dialplan_nominal);
815  AST_TEST_UNREGISTER(test_message_queue_handler_nominal);
816  AST_TEST_UNREGISTER(test_message_queue_both_nominal);
817  AST_TEST_UNREGISTER(test_message_has_destination_dialplan);
818  AST_TEST_UNREGISTER(test_message_has_destination_handler);
819  AST_TEST_UNREGISTER(test_message_msg_send);
820 
822 
824 
825  return 0;
826 }
void ast_manager_unregister_hook(struct manager_custom_hook *hook)
Delete a custom hook to be called when an event is fired.
Definition: manager.c:1942
#define NULL
Definition: resample.c:96
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
#define AST_MODULE
void ast_context_destroy(struct ast_context *con, const char *registrar)
Destroy a context (matches the specified context or ANY context if NULL)
Definition: conf2ael.c:625
static struct manager_custom_hook user_event_hook
AMI event hook that verifies whether or not we&#39;ve gotten our user events.
Definition: test_message.c:99

◆ user_event_hook_cb()

static int user_event_hook_cb ( int  category,
const char *  event,
char *  body 
)
static

Definition at line 196 of file test_message.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_skip_blanks(), ast_strdupa, ast_strlen_zero, ast_trim_blanks(), expected_user_events, parse(), received_user_events, strsep(), user_event_cond, user_event_lock, value, and verify_user_event_fields().

197 {
198  char *parse;
199  char *kvp;
200 
201  if (strcmp(event, "UserEvent")) {
202  return -1;
203  }
204 
205  parse = ast_strdupa(body);
206  while ((kvp = strsep(&parse, "\r\n"))) {
207  char *key, *value;
208 
209  kvp = ast_trim_blanks(kvp);
210  if (ast_strlen_zero(kvp)) {
211  continue;
212  }
213  key = strsep(&kvp, ":");
214  value = ast_skip_blanks(kvp);
216  }
217 
219 
223  }
225 
226  return 0;
227 }
static ast_cond_t user_event_cond
Condition wait variable for all dialplan user events being received.
Definition: test_message.c:62
static int verify_user_event_fields(int user_event, const char *header, const char *value)
Verifies a user event header/value pair.
Definition: test_message.c:114
Definition: astman.c:222
#define ast_mutex_lock(a)
Definition: lock.h:187
int value
Definition: syslog.c:37
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int expected_user_events
The number of user events we expect for this test.
Definition: test_message.c:56
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int received_user_events
The current number of received user events.
Definition: test_message.c:53
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:182
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1872
static ast_mutex_t user_event_lock
Mutex for user_event_cond.
Definition: test_message.c:65
char * strsep(char **str, const char *delims)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ user_event_wait_for_events()

static int user_event_wait_for_events ( struct ast_test test,
int  expected_events 
)
static

Wait for the expected number of user events to be received.

Definition at line 251 of file test_message.c.

References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, AST_TEST_FAIL, ast_test_set_result(), ast_test_status_update, ast_tv(), ast_tvadd(), ast_tvnow(), error(), expected_user_events, received_user_events, user_event_cond, and user_event_lock.

Referenced by AST_TEST_DEFINE().

252 {
253  int error;
254  struct timeval wait = ast_tvadd(ast_tvnow(), ast_tv(5 /* seconds */, 0));
255  struct timespec wait_time = { .tv_sec = wait.tv_sec, .tv_nsec = wait.tv_usec * 1000 };
256 
257  expected_user_events = expected_events;
258 
261  error = ast_cond_timedwait(&user_event_cond, &user_event_lock, &wait_time);
262  if (error == ETIMEDOUT) {
263  ast_test_status_update(test, "Test timed out while waiting for %d expected user events\n", expected_events);
265  break;
266  }
267  }
269 
270  ast_test_status_update(test, "Received %d of %d user events\n", received_user_events, expected_events);
271  return !(received_user_events == expected_events);
272 }
static ast_cond_t user_event_cond
Condition wait variable for all dialplan user events being received.
Definition: test_message.c:62
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static int expected_user_events
The number of user events we expect for this test.
Definition: test_message.c:56
static int received_user_events
The current number of received user events.
Definition: test_message.c:53
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state)
Definition: test.c:262
static ast_mutex_t user_event_lock
Mutex for user_event_cond.
Definition: test_message.c:65
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
int error(const char *format,...)
Definition: utils/frame.c:999
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ verify_bad_headers()

static int verify_bad_headers ( struct ast_test test)
static

Definition at line 274 of file test_message.c.

References AST_TEST_FAIL, ast_test_set_result(), ast_test_status_update, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by AST_TEST_DEFINE().

275 {
276  int res = 0;
277  int i;
278 
279  for (i = 0; i < AST_VECTOR_SIZE(&bad_headers); i++) {
280  struct ast_variable *headers;
281  struct ast_variable *current;
282 
283  headers = AST_VECTOR_GET(&bad_headers, i);
284  if (!headers) {
285  continue;
286  }
287 
288  res = -1;
289  for (current = headers; current; current = current->next) {
290  ast_test_status_update(test, "Expected UserEvent %d: Failed to match %s: %s\n",
291  i, current->name, current->value);
293  }
294  }
295 
296  return res;
297 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
void ast_test_set_result(struct ast_test *test, enum ast_test_result_state state)
Definition: test.c:262
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ verify_user_event_fields()

static int verify_user_event_fields ( int  user_event,
const char *  header,
const char *  value 
)
static

Verifies a user event header/value pair.

Parameters
user_eventwhich user event to check
headerThe header to verify
valueThe value read from the event
Return values
-1on error or evaluation failure
0if match not needed or success

Definition at line 114 of file test_message.c.

References ast_log, ast_variable_list_append, ast_variable_new, AST_VECTOR_GET, AST_VECTOR_REPLACE, AST_VECTOR_SIZE, error(), LOG_ERROR, ast_variable::name, ast_variable::next, NULL, and ast_variable::value.

Referenced by user_event_hook_cb().

115 {
116  struct ast_variable *current;
117  struct ast_variable *expected;
118  regex_t regexbuf;
119  int error;
120 
121  if (user_event >= AST_VECTOR_SIZE(&expected_user_event_fields)) {
122  return -1;
123  }
124 
125  expected = AST_VECTOR_GET(&expected_user_event_fields, user_event);
126  if (!expected) {
127  return -1;
128  }
129 
130  for (current = expected; current; current = current->next) {
131  struct ast_variable *bad_header;
132 
133  if (strcmp(current->name, header)) {
134  continue;
135  }
136 
137  error = regcomp(&regexbuf, current->value, REG_EXTENDED | REG_NOSUB);
138  if (error) {
139  char error_buf[128];
140  regerror(error, &regexbuf, error_buf, sizeof(error_buf));
141  ast_log(LOG_ERROR, "Failed to compile regex '%s' for header check '%s': %s\n",
142  current->value, current->name, error_buf);
143  return -1;
144  }
145 
146  if (!regexec(&regexbuf, value, 0, NULL, 0)) {
147  regfree(&regexbuf);
148  return 0;
149  }
150 
151  bad_header = ast_variable_new(header, value, __FILE__);
152  if (bad_header) {
153  struct ast_variable *bad_headers_head = NULL;
154 
155  if (user_event < AST_VECTOR_SIZE(&bad_headers)) {
156  bad_headers_head = AST_VECTOR_GET(&bad_headers, user_event);
157  }
158  ast_variable_list_append(&bad_headers_head, bad_header);
159  AST_VECTOR_REPLACE(&bad_headers, user_event, bad_headers_head);
160  }
161  regfree(&regexbuf);
162  return -1;
163  }
164 
165  return 0;
166 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
#define ast_variable_new(name, value, filename)
#define LOG_ERROR
Definition: logger.h:285
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:284
int error(const char *format,...)
Definition: utils/frame.c:999
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define ast_variable_list_append(head, new_var)

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Out-of-call text message support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 881 of file test_message.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 881 of file test_message.c.

◆ expected_user_events

int expected_user_events
static

The number of user events we expect for this test.

Definition at line 56 of file test_message.c.

Referenced by user_event_hook_cb(), and user_event_wait_for_events().

◆ handler_cond

ast_cond_t handler_cond
static

Condition wait variable for test_msg_handler receiving message.

Definition at line 68 of file test_message.c.

Referenced by handler_wait_for_message(), and test_msg_handle_msg_cb().

◆ handler_lock

ast_mutex_t handler_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Mutex for handler_cond.

Definition at line 71 of file test_message.c.

Referenced by handler_wait_for_message(), and test_msg_handle_msg_cb().

◆ handler_received_message

int handler_received_message
static

Predicate for the test_message_handler receiving a message.

Definition at line 59 of file test_message.c.

Referenced by handler_wait_for_message(), test_init_cb(), and test_msg_handle_msg_cb().

◆ message_received

int message_received
static

Definition at line 168 of file test_message.c.

Referenced by test_init_cb(), and test_msg_send().

◆ received_user_events

int received_user_events
static

The current number of received user events.

Definition at line 53 of file test_message.c.

Referenced by test_init_cb(), user_event_hook_cb(), and user_event_wait_for_events().

◆ test_msg_handler

struct ast_msg_handler test_msg_handler
static
Initial value:
= {
.name = "testmsg",
.handle_msg = test_msg_handle_msg_cb,
.has_destination = test_msg_has_destination_cb,
}
static int test_msg_handle_msg_cb(struct ast_msg *msg)
Definition: test_message.c:177
static int test_msg_has_destination_cb(const struct ast_msg *msg)
Definition: test_message.c:187

Our test message handler.

Definition at line 90 of file test_message.c.

◆ user_event_cond

ast_cond_t user_event_cond
static

Condition wait variable for all dialplan user events being received.

Definition at line 62 of file test_message.c.

Referenced by user_event_hook_cb(), and user_event_wait_for_events().

◆ user_event_hook

struct manager_custom_hook user_event_hook
static
Initial value:
= {
.file = AST_MODULE,
.helper = user_event_hook_cb,
}
static int user_event_hook_cb(int category, const char *event, char *body)
Definition: test_message.c:196
#define AST_MODULE

AMI event hook that verifies whether or not we've gotten our user events.

Definition at line 99 of file test_message.c.

◆ user_event_lock

ast_mutex_t user_event_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Mutex for user_event_cond.

Definition at line 65 of file test_message.c.

Referenced by user_event_hook_cb(), and user_event_wait_for_events().