48 static enum ast_test_result_state test_chan_integer(
struct ast_test *
test,
49 struct ast_channel *c,
int *ifield,
const char *expression)
51 int i, okay = 1, value1 = -1, value2 = -1;
55 for (i = 0; i < 256; i++) {
58 pbx_substitute_variables_helper(c, expression, workspace,
sizeof(workspace));
60 if (sscanf(workspace,
"%d", &value1) != 1 || value1 != i || sscanf(
ast_str_buffer(str),
"%d", &value2) != 1 || value2 != i) {
61 ast_test_status_update(test,
"%s != %s and/or %d != %d != %d\n",
ast_str_buffer(str), workspace, value1, value2, i);
65 ast_test_status_update(test,
"Tested '%s' . . . . . %s\n", expression, okay ?
"passed" :
"FAILED");
69 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
72 static enum ast_test_result_state test_chan_integer_accessor(
struct ast_test *test,
75 int i, okay = 1, value1 = -1, value2 = -1;
79 for (i = 0; i < 256; i++) {
82 pbx_substitute_variables_helper(c, expression, workspace,
sizeof(workspace));
84 if (sscanf(workspace,
"%d", &value1) != 1 || value1 != i || sscanf(
ast_str_buffer(str),
"%d", &value2) != 1 || value2 != i) {
85 ast_test_status_update(test,
"%s != %s and/or %d != %d != %d\n",
ast_str_buffer(str), workspace, value1, value2, i);
89 ast_test_status_update(test,
"Tested '%s' . . . . . %s\n", expression, okay ?
"passed" :
"FAILED");
93 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
96 static enum ast_test_result_state test_chan_string(
struct ast_test *test,
98 const char *(*getter)(
const struct ast_channel *),
const char *expression)
100 const char *
values[] = {
"one",
"three",
"reallylongdinosaursoundingthingwithwordsinit" };
102 char workspace[4096];
105 for (i = 0; i < ARRAY_LEN(values); i++) {
106 setter(c, values[i]);
108 pbx_substitute_variables_helper(c, expression, workspace,
sizeof(workspace));
110 if (strcmp(getter(c),
ast_str_buffer(str)) != 0 || strcmp(getter(c), workspace) != 0) {
111 ast_test_status_update(test,
"%s != %s != %s\n", getter(c),
ast_str_buffer(str), workspace);
115 ast_test_status_update(test,
"Tested '%s' . . . . . %s\n",
116 expression, okay ?
"passed" :
"FAILED");
120 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
123 static enum ast_test_result_state test_chan_variable(
struct ast_test *test,
126 const char *values[] = {
"one",
"three",
"reallylongdinosaursoundingthingwithwordsinit" };
128 char workspace[4096];
133 for (i = 0; i < ARRAY_LEN(values); i++) {
136 pbx_substitute_variables_helper(c,
ast_str_buffer(var), workspace,
sizeof(workspace));
138 if (strcmp(values[i],
ast_str_buffer(str)) != 0 || strcmp(values[i], workspace) != 0) {
139 ast_test_status_update(test,
"%s != %s != %s\n",
144 ast_test_status_update(test,
"Tested '%s' . . . . . %s\n",
150 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
153 static enum ast_test_result_state test_chan_function(
struct ast_test *test,
157 char workspace[4096];
161 pbx_substitute_variables_helper(c, expression, workspace,
sizeof(workspace));
164 ast_test_status_update(test,
"expr: '%s' ... %s != %s\n",
168 ast_test_status_update(test,
"Tested '%s' . . . . . %s\n",
169 expression, okay ?
"passed" :
"FAILED");
173 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
176 static enum ast_test_result_state test_2way_function(
struct ast_test *test,
177 struct ast_channel *c,
const char *encode1,
const char *encode2,
178 const char *decode1,
const char *decode2)
183 ast_str_set(&expression, 0,
"%s%s%s", encode1,
"foobarbaz", encode2);
190 ast_test_status_update(test,
"'%s' != 'foobarbaz'\n",
193 ast_test_status_update(test,
"Tested '%s%s' and '%s%s' . . . . . %s\n",
194 encode1, encode2, decode1, decode2,
195 okay ?
"passed" :
"FAILED");
199 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
202 static enum ast_test_result_state test_expected_result(
struct ast_test *test,
203 struct ast_channel *c,
const char *expression,
const char *result)
212 ast_test_status_update(test,
"'%s' != '%s'\n",
215 ast_test_status_update(test,
"Tested '%s' ('%s') == '%s' . . . . . %s\n",
217 okay ?
"passed" :
"FAILED");
221 return okay ? AST_TEST_PASS : AST_TEST_FAIL;
228 enum ast_test_result_state res = AST_TEST_PASS;
233 info->name =
"test_substitution";
234 info->category =
"/main/pbx/";
235 info->summary =
"Test variable and function substitution";
237 "This test executes a variety of variable and function substitutions "
238 "and ensures that the expected results are received.";
239 return AST_TEST_NOT_RUN;
244 ast_test_status_update(test,
"Testing variable substitution ...\n");
246 c =
ast_channel_alloc(0, 0,
"",
"",
"",
"",
"", NULL, NULL, 0,
"Test/substitution");
247 ast_channel_unlock(c);
249 #define TEST(t) if (t == AST_TEST_FAIL) { res = AST_TEST_FAIL; }
258 TEST(test_chan_integer(test, c, &ast_channel_caller(c)->ani2,
"${CALLINGANI2}"));
259 TEST(test_chan_integer(test, c, &ast_channel_caller(c)->
id.
number.plan,
"${CALLINGTON}"));
260 TEST(test_chan_integer(test, c, &ast_channel_dialed(c)->transit_network_select,
"${CALLINGTNS}"));
261 TEST(test_chan_integer_accessor(test, c, ast_channel_hangupcause_set,
"${HANGUPCAUSE}"));
262 TEST(test_chan_integer_accessor(test, c, ast_channel_priority_set,
"${PRIORITY}"));
263 TEST(test_chan_string(test, c, ast_channel_context_set, ast_channel_context,
"${CONTEXT}"));
264 TEST(test_chan_string(test, c, ast_channel_exten_set, ast_channel_exten,
"${EXTEN}"));
265 TEST(test_chan_variable(test, c,
"CHANNEL(language)"));
266 TEST(test_chan_variable(test, c,
"CHANNEL(musicclass)"));
267 TEST(test_chan_variable(test, c,
"CHANNEL(parkinglot)"));
268 TEST(test_chan_variable(test, c,
"CALLERID(name)"));
269 TEST(test_chan_variable(test, c,
"CURLOPT(proxyuserpwd)"));
270 TEST(test_chan_variable(test, c,
"CDR(foo)"));
271 TEST(test_chan_variable(test, c,
"ENV(foo)"));
272 TEST(test_chan_variable(test, c,
"GLOBAL(foo)"));
273 TEST(test_chan_variable(test, c,
"GROUP()"));
274 TEST(test_2way_function(test, c,
"${AES_ENCRYPT(abcdefghijklmnop,",
")}",
"${AES_DECRYPT(abcdefghijklmnop,",
")}"));
275 TEST(test_2way_function(test, c,
"${BASE64_ENCODE(",
")}",
"${BASE64_DECODE(",
")}"));
279 TEST(test_expected_result(test, c,
"${foo}${foo}",
"123123"));
280 TEST(test_expected_result(test, c,
"A${foo}A${foo}A",
"A123A123A"));
281 TEST(test_expected_result(test, c,
"A${${bar}}A",
"A123A"));
282 TEST(test_expected_result(test, c,
"A${${baz}o}A",
"A123A"));
283 TEST(test_expected_result(test, c,
"A${${baz}o:1}A",
"A23A"));
284 TEST(test_expected_result(test, c,
"A${${baz}o:1:1}A",
"A2A"));
285 TEST(test_expected_result(test, c,
"A${${baz}o:1:-1}A",
"A2A"));
286 TEST(test_expected_result(test, c,
"A${${baz}o:-1:1}A",
"A3A"));
287 TEST(test_expected_result(test, c,
"A${${baz}o:-2:1}A",
"A2A"));
288 TEST(test_expected_result(test, c,
"A${${baz}o:-2:-1}A",
"A2A"));
290 TEST(test_expected_result(test, c,
"${LISTFILTER(list1,&,ab)}",
"cd&ef"));
291 TEST(test_expected_result(test, c,
"${LISTFILTER(list1,&,cd)}",
"ab&ef"));
292 TEST(test_expected_result(test, c,
"${LISTFILTER(list1,&,ef)}",
"ab&cd"));
293 TEST(test_expected_result(test, c,
"${LISTFILTER(list1,&,gh)}",
"ab&cd&ef"));
294 TEST(test_expected_result(test, c,
"${LISTFILTER(list1,&,c)}",
"ab&cd&ef"));
295 TEST(test_expected_result(test, c,
"${LISTFILTER(list1,&,d)}",
"ab&cd&ef"));
297 TEST(test_expected_result(test, c,
"${LISTFILTER(list2,&,ab)}",
""));
299 TEST(test_expected_result(test, c,
"${LISTFILTER(list_empty,&,ab)}",
""));
300 TEST(test_expected_result(test, c,
"${SHELL(printf '%d' 123)},${SHELL(printf '%d' 456)}",
"123,456"));
301 TEST(test_expected_result(test, c,
"${foo},${CDR(answer)},${SHELL(printf '%d' 456)}",
"123,,456"));
302 TEST(test_expected_result(test, c,
"${foo},${CDR(answer,u)},${SHELL(printf '%d' 456)}",
"123,0.000000,456"));
303 TEST(test_expected_result(test, c,
"${foo},${this_does_not_exist},${THIS_DOES_NOT_EXIST(either)}",
"123,,"));
313 if (strcmp(cmd,
"CHANNEL") && strcmp(cmd,
"CALLERID") && strncmp(cmd,
"CURL", 4) &&
314 strncmp(cmd,
"AES", 3) && strncmp(cmd,
"BASE64", 6) &&
315 strcmp(cmd,
"CDR") && strcmp(cmd,
"ENV") && strcmp(cmd,
"GLOBAL") &&
316 strcmp(cmd,
"GROUP") && strcmp(cmd,
"CUT") && strcmp(cmd,
"LISTFILTER") &&
317 strcmp(cmd,
"PP_EACH_EXTENSION") && strcmp(cmd,
"SET")) {
321 snprintf(expression,
sizeof(expression),
"${%s(foo)}", cmd);
322 if (AST_TEST_FAIL == test_chan_function(test, c, expression)) {
338 static int unload_module(
void)
340 AST_TEST_UNREGISTER(test_substitution);
344 static int load_module(
void)
346 AST_TEST_REGISTER(test_substitution);
Main Channel structure associated with a channel.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
struct ast_party_caller caller
Channel Caller ID information.
String manipulation functions.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
Definitions to aid in the use of thread local storage.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ast_party_id id
Caller party ID.
struct ast_vector_string * ast_cli_completion_vector(const char *text, const char *word)
Generates a vector of strings for CLI completion.
General Asterisk PBX channel definitions.
Data structure associated with a custom dialplan function.
Core PBX routines and definitions.
Support for dynamic strings.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Vector container support.
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
#define AST_TEST_DEFINE(hdr)
String vector definitions.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Asterisk module definitions.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
struct ast_party_number number
Subscriber phone number.