Asterisk - The Open Source Telephony Project GIT-master-b023714
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
test_pbx.c File Reference

PBX Tests. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/test.h"
#include <signal.h>
Include dependency graph for test_pbx.c:

Go to the source code of this file.

Data Structures

struct  exten_info
 an extension to add to our context More...
 
struct  pbx_test_pattern
 

Macros

#define MAX_PRIORITIES   10
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (call_assert)
 
 AST_TEST_DEFINE (call_backtrace)
 
 AST_TEST_DEFINE (just_fail)
 
 AST_TEST_DEFINE (just_pass)
 
 AST_TEST_DEFINE (pattern_match_test)
 
 AST_TEST_DEFINE (segv)
 
static int load_module (void)
 
static int test_exten (const struct pbx_test_pattern *test_pattern, struct ast_test *test, int new_engine)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PBX test module" , .key = ASTERISK_GPL_KEY , .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

PBX Tests.

Author
Mark Michelson mmich.nosp@m.elso.nosp@m.n@dig.nosp@m.ium..nosp@m.com

This module will run some PBX tests.

Definition in file test_pbx.c.

Macro Definition Documentation

◆ MAX_PRIORITIES

#define MAX_PRIORITIES   10

If we determine that we really need to be able to register more than 10 priorities for a single extension, then fine, we can do that later.

Definition at line 48 of file test_pbx.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 446 of file test_pbx.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 446 of file test_pbx.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 446 of file test_pbx.c.

◆ AST_TEST_DEFINE() [1/6]

AST_TEST_DEFINE ( call_assert  )

Definition at line 346 of file test_pbx.c.

347{
348 switch (cmd) {
349 case TEST_INIT:
350 info->name = "CALL_ASSERT";
351 info->category = "/DO_NOT_RUN/";
352 info->summary = "Calls ast_asert()!!! (will only be run if explicitly called)";
353 info->description = "Calls ast_asert()!!! (will only be run if explicitly called). "
354 "This test is mainly used for testing CI and tool failure scenarios.";
355 info->explicit_only = 1;
356 return AST_TEST_NOT_RUN;
357 case TEST_EXECUTE:
358 break;
359 }
360
361 ast_assert(0);
362
363 return AST_TEST_PASS;
364}
@ TEST_INIT
Definition test.h:200
@ TEST_EXECUTE
Definition test.h:201
@ AST_TEST_PASS
Definition test.h:195
@ AST_TEST_NOT_RUN
Definition test.h:194
#define ast_assert(a)
Definition utils.h:776

References ast_assert, AST_TEST_NOT_RUN, AST_TEST_PASS, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [2/6]

AST_TEST_DEFINE ( call_backtrace  )

Definition at line 366 of file test_pbx.c.

367{
368 switch (cmd) {
369 case TEST_INIT:
370 info->name = "CALL_BACKTRACE";
371 info->category = "/DO_NOT_RUN/";
372 info->summary = "Calls ast_log_backtrace()!!! (will only be run if explicitly called)";
373 info->description = "Calls ast_log_backtrace()!!! (will only be run if explicitly called). "
374 "This test is mainly used for testing CI and tool failure scenarios.";
375 info->explicit_only = 1;
376 return AST_TEST_NOT_RUN;
377 case TEST_EXECUTE:
378 break;
379 }
380
382
383 return AST_TEST_PASS;
384}
void ast_log_backtrace(void)
Log a backtrace of the current thread's execution stack to the Asterisk log.
Definition logger.c:2480

References ast_log_backtrace(), AST_TEST_NOT_RUN, AST_TEST_PASS, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [3/6]

AST_TEST_DEFINE ( just_fail  )

Definition at line 386 of file test_pbx.c.

387{
388 switch (cmd) {
389 case TEST_INIT:
390 info->name = "JUST_FAIL";
391 info->category = "/TEST_PASS_FAIL/";
392 info->summary = "Just fails";
393 info->description = "Just fails. "
394 "This test is mainly used for testing CI and tool failure scenarios.";
395 info->explicit_only = 1;
396 return AST_TEST_NOT_RUN;
397 case TEST_EXECUTE:
398 break;
399 }
400 ast_test_status_update(test, "This test just forces a fail\n");
401
402 return AST_TEST_FAIL;
403}
#define ast_test_status_update(a, b, c...)
Definition test.h:129
@ AST_TEST_FAIL
Definition test.h:196

References AST_TEST_FAIL, AST_TEST_NOT_RUN, ast_test_status_update, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [4/6]

AST_TEST_DEFINE ( just_pass  )

Definition at line 405 of file test_pbx.c.

406{
407 switch (cmd) {
408 case TEST_INIT:
409 info->name = "JUST_PASS";
410 info->category = "/TEST_PASS_FAIL/";
411 info->summary = "Just passes";
412 info->description = "Just passes. "
413 "This test is mainly used for testing CI and tool failure scenarios.";
414 info->explicit_only = 1;
415 return AST_TEST_NOT_RUN;
416 case TEST_EXECUTE:
417 break;
418 }
419 ast_test_status_update(test, "This test just forces a pass\n");
420
421 return AST_TEST_PASS;
422}

References AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [5/6]

AST_TEST_DEFINE ( pattern_match_test  )

Definition at line 188 of file test_pbx.c.

189{
190 static const char registrar[] = "test_pbx";
192 static const char TEST_PATTERN[] = "test_pattern";
193 static const char TEST_PATTERN_INCLUDE[] = "test_pattern_include";
194 int i, j;
195
196 /* The array of contexts to register for our test.
197 * To add more contexts, just add more rows to this array.
198 */
199 struct {
200 const char * context_string;
201 } contexts[] = {
202 { TEST_PATTERN, },
203 { TEST_PATTERN_INCLUDE, },
204 };
205
206 /*
207 * Map to indicate which contexts should be included inside
208 * other contexts. The first context listed will include
209 * the second context listed.
210 *
211 * To add more inclusions, add new rows to this array.
212 */
213 const struct {
214 const char *outer_context;
215 const char *inner_context;
216 } context_includes[] = {
217 { TEST_PATTERN, TEST_PATTERN_INCLUDE },
218 };
219
220 /* The array of extensions to add to our test context.
221 * For more information about the individual fields, see
222 * the doxygen for struct exten_info.
223 *
224 * To add new extensions to the test, simply add new rows
225 * to this array. All extensions will automatically be
226 * added when the test is run.
227 */
228 const struct exten_info extens[] = {
229 [0] = { TEST_PATTERN, "_2.", NULL, 1, { 1 } },
230 [1] = { TEST_PATTERN, "2000", NULL, 1, { 1 } },
231 [2] = { TEST_PATTERN_INCLUDE, "2000", NULL, 1, { 2 } },
232 };
233
234 /* This array contains our test material. See the doxygen
235 * for struct pbx_test_pattern for more information on each
236 * component.
237 *
238 * To add more test cases, add more lines to this array. Each
239 * case will be tested automatically when the test is run.
240 */
241 const struct pbx_test_pattern tests[] = {
242 { TEST_PATTERN, "200", NULL, 1, &extens[0] },
243 { TEST_PATTERN, "2000", NULL, 1, &extens[1] },
244 { TEST_PATTERN, "2000", NULL, 2, &extens[2] },
245 { TEST_PATTERN_INCLUDE, "2000", NULL, 2, &extens[2] },
246 };
247
248 switch (cmd) {
249 case TEST_INIT:
250 info->name = "pattern_match_test";
251 info->category = "/main/pbx/";
252 info->summary = "Test pattern matching";
253 info->description = "Create a context with a bunch of extensions within. Then attempt\n"
254 "to match some strings to the extensions.";
255 return AST_TEST_NOT_RUN;
256 case TEST_EXECUTE:
257 break;
258 }
259
260 /* Step one is to build the dialplan.
261 *
262 * We iterate first through the contexts array to build
263 * all the contexts we'll need. Then, we iterate over the
264 * extens array to add all the extensions to the appropriate
265 * contexts.
266 */
267
268 for (i = 0; i < ARRAY_LEN(contexts); ++i) {
269 if (!ast_context_find_or_create(NULL, NULL, contexts[i].context_string, registrar)) {
270 ast_test_status_update(test, "Failed to create context %s\n", contexts[i].context_string);
271 res = AST_TEST_FAIL;
272 goto cleanup;
273 }
274 }
275
276 for (i = 0; i < ARRAY_LEN(context_includes); ++i) {
277 if (ast_context_add_include(context_includes[i].outer_context,
278 context_includes[i].inner_context, registrar)) {
279 ast_test_status_update(test, "Failed to include context %s inside context %s\n",
280 context_includes[i].inner_context, context_includes[i].outer_context);
281 res = AST_TEST_FAIL;
282 goto cleanup;
283 }
284 }
285
286 for (i = 0; i < ARRAY_LEN(extens); ++i) {
287 int priority;
288 if (extens[i].num_priorities > MAX_PRIORITIES) {
289 ast_test_status_update(test, "Invalid number of priorities specified for extension %s."
290 "Max is %d, but we requested %d. Test failed\n",
291 extens[i].exten, MAX_PRIORITIES, extens[i].num_priorities);
292 res = AST_TEST_FAIL;
293 goto cleanup;
294 }
295 for (priority = 0; priority < extens[i].num_priorities; ++priority) {
296 if (ast_add_extension(extens[i].context, 0, extens[i].exten, extens[i].priorities[priority],
297 NULL, extens[i].cid, "Noop", (void *) extens[i].exten, NULL, registrar)) {
298 ast_test_status_update(test, "Failed to add extension %s, priority %d, to context %s."
299 "Test failed\n", extens[i].exten, extens[i].priorities[priority], extens[i].context);
300 res = AST_TEST_FAIL;
301 goto cleanup;
302 }
303 }
304 }
305
306 /* At this stage, the dialplan is built. Now we iterate over
307 * the tests array to attempt to find each of the specified
308 * extensions with the old and new pattern matching engines.
309 */
310 for (j = 0; j < 2; j++) {
312 for (i = 0; i < ARRAY_LEN(tests); ++i) {
313 if (test_exten(&tests[i], test, j)) {
314 res = AST_TEST_FAIL;
315 break;
316 }
317 }
318 }
319
320cleanup:
322
323 return res;
324}
void ast_context_destroy(void)
Definition ael_main.c:414
int extens
Definition ael_main.c:93
static int priority
static struct ast_context * contexts
Definition pbx.c:796
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:6949
int ast_context_add_include(const char *context, const char *include, const char *registrar)
Add a context include.
Definition pbx.c:6685
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:6170
int pbx_set_extenpatternmatchnew(int newval)
Definition pbx.c:4798
static char * registrar
Definition pbx_ael.c:81
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition res_stasis.c:327
#define NULL
Definition resample.c:96
an extension to add to our context
Definition test_pbx.c:53
const struct exten_info * exten
Expected extension match.
Definition test_pbx.c:153
const char * context
Test context.
Definition test_pbx.c:118
ast_test_result_state
Definition test.h:193
static int test_exten(const struct pbx_test_pattern *test_pattern, struct ast_test *test, int new_engine)
Definition test_pbx.c:156
#define MAX_PRIORITIES
Definition test_pbx.c:48
#define ARRAY_LEN(a)
Definition utils.h:703

References ARRAY_LEN, ast_add_extension(), ast_context_add_include(), ast_context_destroy(), ast_context_find_or_create(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, cleanup(), pbx_test_pattern::context, contexts, pbx_test_pattern::exten, extens, MAX_PRIORITIES, NULL, pbx_set_extenpatternmatchnew(), priority, registrar, TEST_EXECUTE, test_exten(), and TEST_INIT.

◆ AST_TEST_DEFINE() [6/6]

AST_TEST_DEFINE ( segv  )

Definition at line 326 of file test_pbx.c.

327{
328 switch (cmd) {
329 case TEST_INIT:
330 info->name = "RAISE_SEGV";
331 info->category = "/DO_NOT_RUN/";
332 info->summary = "RAISES SEGV!!! (will only be run if explicitly called)";
333 info->description = "RAISES SEGV!!! (will only be run if explicitly called). "
334 "This test is mainly used for testing CI and tool failure scenarios.";
335 info->explicit_only = 1;
336 return AST_TEST_NOT_RUN;
337 case TEST_EXECUTE:
338 break;
339 }
340
341 raise(SIGSEGV);
342
343 return AST_TEST_FAIL;
344}

References AST_TEST_FAIL, AST_TEST_NOT_RUN, TEST_EXECUTE, and TEST_INIT.

◆ load_module()

static int load_module ( void  )
static

Definition at line 435 of file test_pbx.c.

436{
437 AST_TEST_REGISTER(pattern_match_test);
438 AST_TEST_REGISTER(segv);
439 AST_TEST_REGISTER(call_assert);
440 AST_TEST_REGISTER(call_backtrace);
441 AST_TEST_REGISTER(just_fail);
442 AST_TEST_REGISTER(just_pass);
444}
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
#define AST_TEST_REGISTER(cb)
Definition test.h:127

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

◆ test_exten()

static int test_exten ( const struct pbx_test_pattern test_pattern,
struct ast_test *  test,
int  new_engine 
)
static

Definition at line 156 of file test_pbx.c.

157{
158 struct pbx_find_info pfi = { { 0 }, };
159 struct ast_exten *exten;
160 if (!(exten = pbx_find_extension(NULL, NULL, &pfi, test_pattern->context,
161 test_pattern->test_exten, test_pattern->priority, NULL,
162 test_pattern->test_cid, E_MATCH))) {
163 ast_test_status_update(test, "Cannot find extension %s in context %s with the %s pattern match engine. "
164 "Test failed.\n", test_pattern->test_exten, test_pattern->context, (new_engine ? "new" : "old"));
165 return -1;
166 }
167 if (strcmp(ast_get_extension_name(exten), test_pattern->exten->exten)) {
168 ast_test_status_update(test, "Expected extension %s but got extension %s instead with the %s pattern match engine. "
169 "Test failed.\n", test_pattern->exten->exten, ast_get_extension_name(exten), (new_engine ? "new" : "old"));
170 return -1;
171 }
172 if (test_pattern->test_cid && strcmp(ast_get_extension_cidmatch(exten), test_pattern->test_cid)) {
173 ast_test_status_update(test, "Expected CID match %s but got CID match %s instead with the %s pattern match engine. "
174 "Test failed.\n", test_pattern->exten->cid, ast_get_extension_cidmatch(exten), (new_engine ? "new" : "old"));
175 return -1;
176 }
177 if (!ast_canmatch_extension(NULL, test_pattern->context, test_pattern->test_exten,
178 test_pattern->priority, test_pattern->test_cid)) {
179 ast_test_status_update(test, "Partial match failed for extension %s in context %s with the %s pattern match engine. "
180 "Test failed.\n", test_pattern->test_exten, test_pattern->context, (new_engine ? "new" : "old"));
181 return -1;
182 }
183 ast_test_status_update(test, "Successfully matched %s to exten %s in context %s with the %s pattern match engine\n",
184 test_pattern->test_exten, test_pattern->exten->exten, test_pattern->context, (new_engine ? "new" : "old"));
185 return 0;
186}
@ E_MATCH
Definition extconf.h:217
const char * ast_get_extension_cidmatch(struct ast_exten *e)
Definition pbx.c:8577
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition pbx.c:4211
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition ael_main.c:152
const char * ast_get_extension_name(struct ast_exten *exten)
Definition pbx.c:8534
ast_exten: An extension The dialplan is saved as a linked list with each context having it's own link...
Definition pbx.c:252
char * exten
Definition pbx.c:253
const char * exten
Extension pattern.
Definition test_pbx.c:73
const char * cid
CID match.
Definition test_pbx.c:85
const int priority
The priority to find.
Definition test_pbx.c:142
const char * test_cid
Test CID match.
Definition test_pbx.c:138
const char * test_exten
Test extension number.
Definition test_pbx.c:128

References ast_canmatch_extension(), ast_get_extension_cidmatch(), ast_get_extension_name(), ast_test_status_update, exten_info::cid, pbx_test_pattern::context, E_MATCH, ast_exten::exten, exten_info::exten, pbx_test_pattern::exten, NULL, pbx_find_extension(), pbx_test_pattern::priority, pbx_test_pattern::test_cid, and pbx_test_pattern::test_exten.

Referenced by AST_TEST_DEFINE().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 424 of file test_pbx.c.

425{
426 AST_TEST_UNREGISTER(just_pass);
427 AST_TEST_UNREGISTER(just_fail);
428 AST_TEST_UNREGISTER(call_backtrace);
429 AST_TEST_UNREGISTER(call_assert);
431 AST_TEST_UNREGISTER(pattern_match_test);
432 return 0;
433}
#define AST_TEST_UNREGISTER(cb)
Definition test.h:128

References AST_TEST_UNREGISTER.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PBX test module" , .key = ASTERISK_GPL_KEY , .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 446 of file test_pbx.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 446 of file test_pbx.c.