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

Gosub tests. More...

#include "asterisk.h"
#include "asterisk/utils.h"
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
Include dependency graph for test_gosub.c:

Go to the source code of this file.

Macros

#define CONTEXT_NAME   "tests_test_gosub_virtual_context"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_gosub)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Gosub Tests" , .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
 

Detailed Description

Gosub tests.

Author
Tilghman Lesher
<tlesher AT digium DOT com> 

Definition in file test_gosub.c.

Macro Definition Documentation

◆ CONTEXT_NAME

#define CONTEXT_NAME   "tests_test_gosub_virtual_context"

Referenced by AST_TEST_DEFINE().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 176 of file test_gosub.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 176 of file test_gosub.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 176 of file test_gosub.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( test_gosub  )

Definition at line 41 of file test_gosub.c.

References app, args, ARRAY_LEN, ast_add_extension(), ast_channel_unref, ast_context_destroy(), ast_context_find_or_create(), ast_context_remove_extension(), ast_dummy_channel_alloc, ast_free, ast_free_ptr(), ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), ast_strdup, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, CONTEXT_NAME, sip_to_pjsip::info(), NULL, pbx_exec(), pbx_findapp(), str, TEST_EXECUTE, and TEST_INIT.

42 {
43 #define CONTEXT_NAME "tests_test_gosub_virtual_context"
44  int res = AST_TEST_PASS, i;
45  struct ast_channel *chan;
46  struct ast_str *str;
47  struct testplan {
48  const char *app;
49  const char *args;
50  const char *expected_value;
51  } testplan[] = {
52  { NULL, "${STACK_PEEK(1,e,1)}", "" }, /* Stack is empty */
53  { "Gosub", "tests_test_gosub_virtual_context,s,1" },
54  { NULL, "${PRIORITY}", "1" },
55  { NULL, "${EXTEN}", "s" },
56  { NULL, "${STACK_PEEK(1,e,1)}", "" }, /* No extension originally */
57  { "Gosub", "test,dne,1", (const char *) -1 }, /* This is the only invocation that should fail. */
58  { NULL, "${PRIORITY}", "1" },
59  { NULL, "${EXTEN}", "s" },
60  { "Gosub", "tests_test_gosub_virtual_context,s,1(5,5,5,5,5)" },
61  { NULL, "${PRIORITY}", "1" },
62  { NULL, "$[0${ARG1} + 0${ARG5}]", "10" },
63  { NULL, "${STACK_PEEK(1,e)}", "s" },
64  { NULL, "${STACK_PEEK(1,c)}", "tests_test_gosub_virtual_context" },
65  { NULL, "${STACK_PEEK(1,p)}", "1" },
66  { NULL, "${STACK_PEEK(1,l)}", "tests_test_gosub_virtual_context,s,1" },
67  { "StackPop", "" },
68  { NULL, "${STACK_PEEK(1,e,1)}", "" }, /* Only 1 frame deep, my caller is top-level */
69  { "Gosub", "tests_test_gosub_virtual_context,s,1(5,5,5,5,5)" },
70  { "Gosub", "tests_test_gosub_virtual_context,s,1(4,4,4,4)" },
71  { NULL, "$[0${ARG1} + 0${ARG5}]", "4" },
72  { NULL, "$[0${ARG1} + 0${ARG4}]", "8" },
73  { "Gosub", "tests_test_gosub_virtual_context,s,1(3,3,3)" },
74  { NULL, "$[0${ARG1} + 0${ARG4}]", "3" },
75  { NULL, "$[0${ARG1} + 0${ARG3}]", "6" },
76  { "Gosub", "tests_test_gosub_virtual_context,s,1(2,2)" },
77  { NULL, "$[0${ARG1} + 0${ARG3}]", "2" },
78  { NULL, "$[0${ARG1} + 0${ARG2}]", "4" },
79  { "Gosub", "tests_test_gosub_virtual_context,s,1(1)" },
80  { NULL, "$[0${ARG1} + 0${ARG2}]", "1" },
81  { NULL, "$[0${ARG1} + 0${ARG1}]", "2" },
82  { "Gosub", "tests_test_gosub_virtual_context,s,1" },
83  { NULL, "$[0${ARG1} + 0${ARG1}]", "0" }, /* All arguments are correctly masked */
84  { "Set", "LOCAL(foo)=5" },
85  { NULL, "${foo}", "5" }, /* LOCAL() set a variable correctly */
86  { NULL, "${LOCAL_PEEK(0,ARG1)}", "" }, /* LOCAL_PEEK() arguments work correctly */
87  { NULL, "${LOCAL_PEEK(4,ARG1)}", "4" }, /* LOCAL_PEEK() arguments work correctly */
88  { NULL, "$[0${LOCAL_PEEK(3,ARG1)} + 0${LOCAL_PEEK(5,ARG1)}]", "8" },
89  { "StackPop", "" },
90  { NULL, "${foo}", "" }, /* StackPop removed the variable set with LOCAL() */
91  { "Return", "7" },
92  { NULL, "${GOSUB_RETVAL}", "7" }, /* Return sets a return value correctly */
93  { NULL, "$[0${GOSUB_RETVAL} + 0${ARG1}]", "9" }, /* Two frames less means ARG1 should have 2 */
94  };
95 
96  switch (cmd) {
97  case TEST_INIT:
98  info->name = "gosub application";
99  info->category = "/apps/app_gosub/";
100  info->summary = "Verify functionality of gosub application";
101  info->description =
102  "Verify functionality of gosub application";
103  return AST_TEST_NOT_RUN;
104  case TEST_EXECUTE:
105  break;
106  }
107 
108  if (!(chan = ast_dummy_channel_alloc())) {
109  ast_test_status_update(test, "Unable to allocate dummy channel\n");
110  return AST_TEST_FAIL;
111  }
112 
113  if (!(str = ast_str_create(16))) {
114  ast_test_status_update(test, "Unable to allocate dynamic string buffer\n");
115  ast_channel_unref(chan);
116  return AST_TEST_FAIL;
117  }
118 
119  /* Create our test dialplan */
120  if (!ast_context_find_or_create(NULL, NULL, CONTEXT_NAME, "test_gosub")) {
121  ast_test_status_update(test, "Unable to create test dialplan context");
122  ast_free(str);
123  ast_channel_unref(chan);
124  return AST_TEST_FAIL;
125  }
126 
127  ast_add_extension(CONTEXT_NAME, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "test_gosub");
128 
129  for (i = 0; i < ARRAY_LEN(testplan); i++) {
130  if (testplan[i].app == NULL) {
131  /* Evaluation */
132  ast_str_substitute_variables(&str, 0, chan, testplan[i].args);
133  if (strcmp(ast_str_buffer(str), testplan[i].expected_value)) {
134  ast_test_status_update(test, "Evaluation of '%s' returned '%s' instead of the expected value '%s'\n",
135  testplan[i].args, ast_str_buffer(str), testplan[i].expected_value);
136  res = AST_TEST_FAIL;
137  }
138  } else {
139  /* Run application */
140  intptr_t exec_res;
141  struct ast_app *app = pbx_findapp(testplan[i].app);
142  if (!app) {
143  ast_test_status_update(test, "Could not find '%s' in application listing!\n", testplan[i].app);
144  res = AST_TEST_FAIL;
145  break;
146  }
147 
148  if ((exec_res = pbx_exec(chan, app, testplan[i].args)) && ((const char *) exec_res != testplan[i].expected_value)) {
149  ast_test_status_update(test, "Application '%s' exited abnormally (with code %d)\n", testplan[i].app, (int) exec_res);
150  res = AST_TEST_FAIL;
151  break;
152  }
153  }
154  }
155 
156  ast_free(str);
157  ast_channel_unref(chan);
159  ast_context_destroy(NULL, "test_gosub");
160 
161  return res;
162 }
Main Channel structure associated with a channel.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define CONTEXT_NAME
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
const char * str
Definition: app_jack.c:147
const char * args
#define NULL
Definition: resample.c:96
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
Definition: pbx.c:4952
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
def info(msg)
#define ast_free(a)
Definition: astmm.h:182
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
ast_app: A registered application
Definition: pbx_app.c:45
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
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
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
static const char app[]
Definition: app_mysql.c:62
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ load_module()

static int load_module ( void  )
static

Definition at line 170 of file test_gosub.c.

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

171 {
172  AST_TEST_REGISTER(test_gosub);
174 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 164 of file test_gosub.c.

References AST_TEST_UNREGISTER.

165 {
166  AST_TEST_UNREGISTER(test_gosub);
167  return 0;
168 }
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Gosub Tests" , .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 176 of file test_gosub.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 176 of file test_gosub.c.