Asterisk - The Open Source Telephony Project GIT-master-f36a736
Macros | Functions | Variables
test_app.c File Reference

App unit test. More...

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

Go to the source code of this file.

Macros

#define BASE_GROUP   "a group"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (app_group)
 
 AST_TEST_DEFINE (options_parsing)
 
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 = "App unit 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

App unit test.

Author
Jeff Peeler jpeel.nosp@m.er@d.nosp@m.igium.nosp@m..com

Definition in file test_app.c.

Macro Definition Documentation

◆ BASE_GROUP

#define BASE_GROUP   "a group"

Definition at line 40 of file test_app.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 238 of file test_app.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 238 of file test_app.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 238 of file test_app.c.

◆ AST_TEST_DEFINE() [1/2]

AST_TEST_DEFINE ( app_group  )

Definition at line 124 of file test_app.c.

125{
126 struct ast_channel *test_channel1 = NULL;
127 struct ast_channel *test_channel2 = NULL;
128 struct ast_channel *test_channel3 = NULL;
129 struct ast_channel *test_channel4 = NULL;
130
131 static const char group1_full[] = BASE_GROUP "groupgroup";
132 static const char group2_full[] = BASE_GROUP "Groupgroup";
133 static const char regex1[] = "gr"; /* matches everything */
134 static const char regex2[] = "(group){2}$"; /* matches only group1_full */
135 static const char regex3[] = "[:ascii:]"; /* matches everything */
136 static const char regex4[] = "^(NOMATCH)"; /* matches nothing */
137 static const char category1_full[] = BASE_GROUP "@a_category"; /* categories shouldn't have spaces */
138 static const char category2_full[] = BASE_GROUP "@another!Category";
139 static const char regex5[] = "(gory)$"; /* matches both categories */
140 static const char regex6[] = "[A-Z]+"; /* matches only category2_full */
141 static const char regex7[] = "[["; /* not valid syntax, yes an expected warning will be displayed */
142 static enum ast_test_result_state res = AST_TEST_PASS;
143 static const struct group_test_params {
144 const char *groupmatch;
145 const char *category;
146 int expected;
147 } subtests[] = {
148 { regex1, "", 4 },
149 { regex2, "", 1 },
150 { regex3, "", 4 },
151 { regex4, "", 0 },
152 { BASE_GROUP, regex5, 2 },
153 { BASE_GROUP, regex6, 1 },
154 /* this test is expected to generate a warning message from the invalid regex */
155 { BASE_GROUP, regex7, 0 }
156 };
157 int i;
158 int returned_count;
159
160 switch (cmd) {
161 case TEST_INIT:
162 info->name = "app_group";
163 info->category = "/main/app/";
164 info->summary = "App group unit test";
165 info->description =
166 "This tests various app group functionality";
167 return AST_TEST_NOT_RUN;
168 case TEST_EXECUTE:
169 break;
170 }
171
172 ast_test_status_update(test, "Creating test channels with the following groups:\n"
173 "'%s', '%s', '%s', '%s'\n", group1_full, group2_full, category1_full, category2_full);
174
175 if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
176 NULL, NULL, NULL, NULL, 0, "TestChannel1"))) {
177 goto exit_group_test;
178 }
179 ast_channel_unlock(test_channel1);
180 if (!(test_channel2 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
181 NULL, NULL, NULL, NULL, 0, "TestChannel2"))) {
182 goto exit_group_test;
183 }
184 ast_channel_unlock(test_channel2);
185 if (!(test_channel3 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
186 NULL, NULL, NULL, NULL, 0, "TestChannel3"))) {
187 goto exit_group_test;
188 }
189 ast_channel_unlock(test_channel3);
190 if (!(test_channel4 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
191 NULL, NULL, NULL, NULL, 0, "TestChannel4"))) {
192 goto exit_group_test;
193 }
194 ast_channel_unlock(test_channel4);
195
196 ast_app_group_set_channel(test_channel1, group1_full);
197 ast_app_group_set_channel(test_channel2, group2_full);
198 ast_app_group_set_channel(test_channel3, category1_full);
199 ast_app_group_set_channel(test_channel4, category2_full);
200
201 for (i = 0; i < ARRAY_LEN(subtests); i++) {
202 ast_assert(subtests[i].groupmatch != NULL || subtests[i].category != NULL);
203 returned_count = ast_app_group_match_get_count(subtests[i].groupmatch, subtests[i].category);
204
205 if (subtests[i].expected != returned_count) {
206 ast_test_status_update(test, "(Subtest %d) Expected %d matches but found %d when examining group:'%s' category:'%s'\n",
207 i + 1, subtests[i].expected, returned_count, subtests[i].groupmatch, subtests[i].category);
208 res = AST_TEST_FAIL;
209 goto exit_group_test;
210 } else {
211 ast_test_status_update(test, "(Subtest %d) Found %d matches as expected when examining group:'%s' category:'%s'\n",
212 i + 1, subtests[i].expected, subtests[i].groupmatch, subtests[i].category);
213 }
214 }
215
216exit_group_test:
217 ast_hangup(test_channel1);
218 ast_hangup(test_channel2);
219 ast_hangup(test_channel3);
220 ast_hangup(test_channel4);
221 return res;
222}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2560
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1299
#define ast_channel_unlock(chan)
Definition: channel.h:2969
@ AST_STATE_DOWN
Definition: channelstate.h:36
int ast_app_group_match_get_count(const char *groupmatch, const char *category)
Get the current channel count of all groups that match the specified pattern and category.
Definition: main/app.c:2260
int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
Set the group for a channel, splitting the provided data into group and category, if specified.
Definition: main/app.c:2193
def info(msg)
#define NULL
Definition: resample.c:96
Main Channel structure associated with a channel.
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
ast_test_result_state
Definition: test.h:193
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
#define BASE_GROUP
Definition: test_app.c:40
#define ast_assert(a)
Definition: utils.h:739
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, ast_app_group_match_get_count(), ast_app_group_set_channel(), ast_assert, ast_channel_alloc, ast_channel_unlock, ast_hangup(), AST_STATE_DOWN, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, BASE_GROUP, sip_to_pjsip::info(), NULL, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [2/2]

AST_TEST_DEFINE ( options_parsing  )

Definition at line 42 of file test_app.c.

43{
44 enum test_option_flags {
45 OPT_SIMPLE,
46 OPT_WITHQUOTES,
47 OPT_WITHBACKSLASH,
48 };
49 enum test_option_args {
50 OPT_ARG_SIMPLE,
51 OPT_ARG_WITHQUOTES,
52 OPT_ARG_WITHBACKSLASH,
54 };
56 AST_APP_OPTION_ARG('a', OPT_SIMPLE, OPT_ARG_SIMPLE),
57 AST_APP_OPTION_ARG('b', OPT_WITHQUOTES, OPT_ARG_WITHQUOTES),
58 AST_APP_OPTION_ARG('c', OPT_WITHBACKSLASH, OPT_ARG_WITHBACKSLASH),
59 });
60 struct ast_flags opts = { 0, };
61 struct ast_flags64 opts64 = { 0, };
62 char *opt_args[OPT_ARG_ARRAY_SIZE];
63 struct {
64 const char *string;
65 const char *parse[3];
66 } options[] = {
67 { "a(simple)b(\"quoted\")c(back\\slash)", { "simple", "quoted", "backslash", }, },
68 { "b(\"((())))\")a(simple)c(back\\)slash)", { "simple", "((())))", "back)slash", }, },
69 { "b(\"((\\\"\\)\\(\")a(simple)c(back\\\"\\)\\(\\\"slash)", { "simple", "((\"\\)\\(", "back\")(\"slash", }, },
70 };
71 int i, j, res = AST_TEST_PASS;
72 char buffer[256];
73
74 switch (cmd) {
75 case TEST_INIT:
76 info->name = "options_parsing";
77 info->category = "/main/app/";
78 info->summary = "App options unit test";
79 info->description =
80 "This tests the options parsing code to ensure that it behaves as expected";
81 return AST_TEST_NOT_RUN;
82 case TEST_EXECUTE:
83 break;
84 }
85
86 for (i = 0; i < ARRAY_LEN(options); i++) {
87 ast_copy_string(buffer, options[i].string, sizeof(buffer));
88
89 if (ast_app_parse_options(test_options, &opts, opt_args, buffer)) {
90 ast_test_status_update(test, "ast_app_parse_options() of '%s' failed\n", options[i].string);
91 res = AST_TEST_FAIL;
92 } else {
93 /* Check arguments for success */
94 for (j = 0; j < 3; j++) {
95 if (strcmp(opt_args[j], options[i].parse[j])) {
96 ast_test_status_update(test, "Parse of option %c from '%s' produced '%s', "
97 "but it should have produced '%s'\n",
98 'a' + j, options[i].string, opt_args[j], options[i].parse[j]);
99 res = AST_TEST_FAIL;
100 }
101 }
102 }
103
104 ast_copy_string(buffer, options[i].string, sizeof(buffer));
105 if (ast_app_parse_options64(test_options, &opts64, opt_args, buffer)) {
106 ast_test_status_update(test, "ast_app_parse_options64() of '%s' failed\n", options[i].string);
107 res = AST_TEST_FAIL;
108 } else {
109 /* Check arguments for success */
110 for (j = 0; j < 3; j++) {
111 if (strcmp(opt_args[j], options[i].parse[j])) {
112 ast_test_status_update(test, "Parse of option %c from '%s' produced '%s', "
113 "but it should have produced '%s'\n",
114 'a' + j, options[i].string, opt_args[j], options[i].parse[j]);
115 res = AST_TEST_FAIL;
116 }
117 }
118 }
119 }
120
121 return res;
122}
@ OPT_ARG_ARRAY_SIZE
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3071
const char * string
Definition: presencestate.c:71
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure used to handle a large number of boolean flags == used only in app_dial?
Definition: utils.h:204
Structure used to handle boolean flags.
Definition: utils.h:199
static struct test_options options

References ARRAY_LEN, AST_APP_OPTION_ARG, AST_APP_OPTIONS, ast_app_parse_options(), ast_app_parse_options64(), ast_copy_string(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), OPT_ARG_ARRAY_SIZE, options, string, TEST_EXECUTE, and TEST_INIT.

◆ load_module()

static int load_module ( void  )
static

Definition at line 231 of file test_app.c.

232{
233 AST_TEST_REGISTER(app_group);
234 AST_TEST_REGISTER(options_parsing);
236}
@ 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.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 224 of file test_app.c.

225{
226 AST_TEST_UNREGISTER(app_group);
227 AST_TEST_UNREGISTER(options_parsing);
228 return 0;
229}
#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 = "App unit 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 238 of file test_app.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 238 of file test_app.c.