Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Macros | Functions | Variables
test_func_file.c File Reference

Function FILE tests. More...

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

Go to the source code of this file.

Macros

#define C1024    "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_func_file)
 
static char * file2display (struct ast_str **buf, ssize_t len, const char *input)
 
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 = "FILE() Tests" , .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
 
struct { 
 
   const char *   args 
 
   const char *   contents 
 
   const char *   value 
 
read_tests [] 
 
struct { 
 
   const char *   args 
 
   const char *   contents 
 
   const char *   contents2 
 
   const char *   value 
 
write_tests [] 
 

Detailed Description

Function FILE tests.

Author
Tilghman Lesher <tlesher AT digium DOT com> 

Definition in file test_func_file.c.

Macro Definition Documentation

◆ C1024

#define C1024    "1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF"

Definition at line 41 of file test_func_file.c.

43 {
44 const char *contents;
45 const char *args;
46 const char *value;
47} read_tests[] = {
48 /* 4 different ways of specifying the first character */
49 { "123456789", "0,1", "1" },
50 { "123456789", "0,-8", "1" },
51 { "123456789", "-9,1", "1" },
52 { "123456789", "-9,-8", "1" },
53 /* Does 0-length work? */
54 { "123456789", "0,0", "" },
55 { "123456789", "-9,0", "" },
56 { "123456789", "-9,-9", "" },
57 /* Does negative length work? */
58 { "123456789", "5,-6", "" },
59 { "123456789", "-5,-6", "" },
60 /* No length */
61 { "123456789", "-5", "56789" },
62 { "123456789", "4", "56789" },
63 /* Passed file length */
64 { "123456789", "8,10", "9" },
65 { "123456789", "10,1", "" },
66 /* Middle of file */
67 { "123456789", "2,5", "34567" },
68 { "123456789", "-7,5", "34567" },
69 /* Line mode, 4 ways of specifying the first character */
70 { "123\n456\n789\n", "0,1,l", "123\n" },
71 { "123\n456\n789\n", "-3,1,l", "123\n" },
72 { "123\n456\n789\n", "0,-2,l", "123\n" },
73 { "123\n456\n789\n", "-3,-2,l", "123\n" },
74 /* Line mode, 0-length */
75 { "123\n456\n789\n", "0,0,l", "" },
76 { "123\n456\n789\n", "-3,0,l", "" },
77 { "123\n456\n789\n", "-3,-3,l", "" },
78 /* Line mode, negative length */
79 { "123\n456\n789\n", "2,-2,l", "" },
80 { "123\n456\n789\n", "-2,-3,l", "" },
81 /* No length */
82 { "123\n456\n789\n", "1,,l", "456\n789\n" },
83 { "123\n456\n789\n", "-2,,l", "456\n789\n" },
84};
85
86static struct {
87 const char *contents;
88 const char *args;
89 const char *value;
90 const char *contents2;
91} write_tests[] = {
92 /* Single character replace */
93 { "123456789", "0,1", "a", "a23456789" },
94 { "123456789", "-9,1", "a", "a23456789" },
95 { "123456789", "0,-8", "a", "a23456789" },
96 { "123456789", "-9,-8", "a", "a23456789" },
97 { "123456789", "5,1", "b", "12345b789" },
98 { "123456789", "-4,1", "b", "12345b789" },
99 { "123456789", "5,-3", "b", "12345b789" },
100 { "123456789", "-4,-3", "b", "12345b789" },
101 /* Replace 2 characters with 1 */
102 { "123456789", "0,2", "c", "c3456789" },
103 { "123456789", "-9,2", "c", "c3456789" },
104 { "123456789", "0,-7", "c", "c3456789" },
105 { "123456789", "-9,-7", "c", "c3456789" },
106 { "123456789", "4,2", "d", "1234d789" },
107 { "123456789", "-5,2", "d", "1234d789" },
108 { "123456789", "4,-3", "d", "1234d789" },
109 { "123456789", "-5,-3", "d", "1234d789" },
110 /* Truncate file */
111 { "123456789", "5", "e", "12345e" },
112 { "123456789", "5", "", "12345" },
113 { "123456789", "-4", "e", "12345e" },
114 { "123456789", "-4", "", "12345" },
115 /* Replace 1 character with 2 */
116 { "123456789", "0,1", "fg", "fg23456789" },
117 { "123456789", "0,-8", "fg", "fg23456789" },
118 { "123456789", "-9,1", "fg", "fg23456789" },
119 { "123456789", "-9,-8", "fg", "fg23456789" },
120 /* Overwrite file */
121 { "123456789", "", "h", "h" },
122 { "123456789", ",,,", "h", "h" },
123 { "123\n456\n789\n", ",,l", "h", "h\n" },
124 { "123\n456\n789\n", ",,ld", "h", "h" },
125 /* Single line replace, same length */
126 { "123\n456\n789\n", "0,1,l", "abc", "abc\n456\n789\n" },
127 { "123\n456\n789\n", "-3,1,l", "abc", "abc\n456\n789\n" },
128 { "123\n456\n789\n", "0,-2,l", "abc", "abc\n456\n789\n" },
129 { "123\n456\n789\n", "-3,-2,l", "abc", "abc\n456\n789\n" },
130 { "123\n456\n789\n", "1,1,l", "abc", "123\nabc\n789\n" },
131 { "123\n456\n789\n", "1,-1,l", "abc", "123\nabc\n789\n" },
132 { "123\n456\n789\n", "-2,1,l", "abc", "123\nabc\n789\n" },
133 { "123\n456\n789\n", "-2,-1,l", "abc", "123\nabc\n789\n" },
134 /* Single line replace, one character short */
135 { "123\n456\n789\n", "0,1,l", "ab", "ab\n456\n789\n" },
136 { "123\n456\n789\n", "-3,1,l", "ab", "ab\n456\n789\n" },
137 { "123\n456\n789\n", "0,-2,l", "ab", "ab\n456\n789\n" },
138 { "123\n456\n789\n", "-3,-2,l", "ab", "ab\n456\n789\n" },
139 { "123\n456\n789\n", "1,1,l", "ab", "123\nab\n789\n" },
140 { "123\n456\n789\n", "1,-1,l", "ab", "123\nab\n789\n" },
141 { "123\n456\n789\n", "-2,1,l", "ab", "123\nab\n789\n" },
142 { "123\n456\n789\n", "-2,-1,l", "ab", "123\nab\n789\n" },
143 /* Single line replace, one character long */
144 { "123\n456\n789\n", "0,1,l", "abcd", "abcd\n456\n789\n" },
145 { "123\n456\n789\n", "-3,1,l", "abcd", "abcd\n456\n789\n" },
146 { "123\n456\n789\n", "0,-2,l", "abcd", "abcd\n456\n789\n" },
147 { "123\n456\n789\n", "-3,-2,l", "abcd", "abcd\n456\n789\n" },
148 { "123\n456\n789\n", "1,1,l", "abcd", "123\nabcd\n789\n" },
149 { "123\n456\n789\n", "1,-1,l", "abcd", "123\nabcd\n789\n" },
150 { "123\n456\n789\n", "-2,1,l", "abcd", "123\nabcd\n789\n" },
151 { "123\n456\n789\n", "-2,-1,l", "abcd", "123\nabcd\n789\n" },
152 /* Multi-line replace, same number of characters, 2 lines for 1 */
153 { "123\n456\n789\n", "0,2,l", "abcdefg", "abcdefg\n789\n" },
154 { "123\n456\n789\n", "-3,2,l", "abcdefg", "abcdefg\n789\n" },
155 { "123\n456\n789\n", "0,-1,l", "abcdefg", "abcdefg\n789\n" },
156 { "123\n456\n789\n", "-3,-1,l", "abcdefg", "abcdefg\n789\n" },
157 { "123\n456\n789\n", "1,2,l", "abcdefg", "123\nabcdefg\n" },
158 { "123\n456\n789\n", "1,,l", "abcdefg", "123\nabcdefg\n" },
159 { "123\n456\n789\n", "-2,2,l", "abcdefg", "123\nabcdefg\n" },
160 { "123\n456\n789\n", "-2,,l", "abcdefg", "123\nabcdefg\n" },
161 /* Multi-line replace, shorter number of characters, 2 lines for 1 */
162 { "123\n456\n789\n", "0,2,l", "abcd", "abcd\n789\n" },
163 { "123\n456\n789\n", "-3,2,l", "abcd", "abcd\n789\n" },
164 { "123\n456\n789\n", "0,-1,l", "abcd", "abcd\n789\n" },
165 { "123\n456\n789\n", "-3,-1,l", "abcd", "abcd\n789\n" },
166 { "123\n456\n789\n", "1,2,l", "abcd", "123\nabcd\n" },
167 { "123\n456\n789\n", "1,,l", "abcd", "123\nabcd\n" },
168 { "123\n456\n789\n", "-2,2,l", "abcd", "123\nabcd\n" },
169 { "123\n456\n789\n", "-2,,l", "abcd", "123\nabcd\n" },
170 /* Multi-line replace, longer number of characters, 2 lines for 1 */
171 { "123\n456\n789\n", "0,2,l", "abcdefghijklmnop", "abcdefghijklmnop\n789\n" },
172 { "123\n456\n789\n", "-3,2,l", "abcdefghijklmnop", "abcdefghijklmnop\n789\n" },
173 { "123\n456\n789\n", "0,-1,l", "abcdefghijklmnop", "abcdefghijklmnop\n789\n" },
174 { "123\n456\n789\n", "-3,-1,l", "abcdefghijklmnop", "abcdefghijklmnop\n789\n" },
175 { "123\n456\n789\n", "1,2,l", "abcdefghijklmnop", "123\nabcdefghijklmnop\n" },
176 { "123\n456\n789\n", "1,,l", "abcdefghijklmnop", "123\nabcdefghijklmnop\n" },
177 { "123\n456\n789\n", "-2,2,l", "abcdefghijklmnop", "123\nabcdefghijklmnop\n" },
178 { "123\n456\n789\n", "-2,,l", "abcdefghijklmnop", "123\nabcdefghijklmnop\n" },
179 /* Insert line */
180 { "123\n456\n789\n", "0,0,l", "abcd", "abcd\n123\n456\n789\n" },
181 { "123\n456\n789\n", "-3,0,l", "abcd", "abcd\n123\n456\n789\n" },
182 { "123\n456\n789\n", "1,0,l", "abcd", "123\nabcd\n456\n789\n" },
183 { "123\n456\n789\n", "-2,0,l", "abcd", "123\nabcd\n456\n789\n" },
184 { "123\n456\n789\n", "2,0,l", "abcd", "123\n456\nabcd\n789\n" },
185 { "123\n456\n789\n", "-1,0,l", "abcd", "123\n456\nabcd\n789\n" },
186 { "123\n456\n789\n", "3,0,l", "abcd", "123\n456\n789\nabcd\n" },
187 { "123\n456\n789\n", ",,la", "abcd", "123\n456\n789\nabcd\n" },
188 /* Single line, replace with blank line */
189 { "123\n456\n789\n", "0,1,l", "", "\n456\n789\n" },
190 { "123\n456\n789\n", "-3,1,l", "", "\n456\n789\n" },
191 { "123\n456\n789\n", "0,-2,l", "", "\n456\n789\n" },
192 { "123\n456\n789\n", "-3,-2,l", "", "\n456\n789\n" },
193 { "123\n456\n789\n", "1,1,l", "", "123\n\n789\n" },
194 { "123\n456\n789\n", "1,-1,l", "", "123\n\n789\n" },
195 { "123\n456\n789\n", "-2,1,l", "", "123\n\n789\n" },
196 { "123\n456\n789\n", "-2,-1,l", "", "123\n\n789\n" },
197 /* Single line, delete */
198 { "123\n456\n789\n", "0,1,ld", "", "456\n789\n" },
199 { "123\n456\n789\n", "-3,1,ld", "", "456\n789\n" },
200 { "123\n456\n789\n", "0,-2,ld", "", "456\n789\n" },
201 { "123\n456\n789\n", "-3,-2,ld", "", "456\n789\n" },
202 { "123\n456\n789\n", "1,1,ld", "", "123\n789\n" },
203 { "123\n456\n789\n", "1,-1,ld", "", "123\n789\n" },
204 { "123\n456\n789\n", "-2,1,ld", "", "123\n789\n" },
205 { "123\n456\n789\n", "-2,-1,ld", "", "123\n789\n" },
206 /* Really long tests */
207 { "1234567890ABCDEF" C1024 C1024 C1024 C1024 C1024,
208 "0,1", "a",
209 "a234567890ABCDEF" C1024 C1024 C1024 C1024 C1024 },
210 { "1234567890ABCDEF" C1024 C1024 C1024 C1024 C1024,
211 "0,1", "abcd",
212 "abcd234567890ABCDEF" C1024 C1024 C1024 C1024 C1024 },
213 { "1234567890ABCDEF" C1024 C1024 C1024 C1024 C1024,
214 "0,10", "abcd",
215 "abcdABCDEF" C1024 C1024 C1024 C1024 C1024 },
216 { "1" C1024 "\n2" C1024 "\n3" C1024 "\n4" C1024 "\n5" C1024 "\n6" C1024 "\n",
217 "0,1,l", "abcd",
218 "abcd\n2" C1024 "\n3" C1024 "\n4" C1024 "\n5" C1024 "\n6" C1024 "\n" },
219 { "1234\n1" C1024 "\n2" C1024 "\n3" C1024 "\n4" C1024 "\n5" C1024 "\n6" C1024 "\n",
220 "0,1,l", "abcd",
221 "abcd\n1" C1024 "\n2" C1024 "\n3" C1024 "\n4" C1024 "\n5" C1024 "\n6" C1024 "\n" },
222 { "1234\n1" C1024 "\n2" C1024 "\n3" C1024 "\n4" C1024 "\n5" C1024 "\n6" C1024 "\n",
223 "0,1,l", "a",
224 "a\n1" C1024 "\n2" C1024 "\n3" C1024 "\n4" C1024 "\n5" C1024 "\n6" C1024 "\n" },
225};
226
227static char *file2display(struct ast_str **buf, ssize_t len, const char *input)
228{
229 const char *ptr;
231 for (ptr = input; *ptr; ptr++) {
232 if (*ptr == '\n') {
233 ast_str_append(buf, len, "\\n");
234 } else if (*ptr == '\r') {
235 ast_str_append(buf, len, "\\r");
236 } else if (*ptr == '\t') {
237 ast_str_append(buf, len, "\\t");
238 } else if (*ptr < ' ' || *ptr > 125) {
239 ast_str_append(buf, len, "\\x%hhX", *ptr);
240 } else {
241 ast_str_append(buf, len, "%c", *ptr);
242 }
243 }
244 return ast_str_buffer(*buf);
245}
246
247AST_TEST_DEFINE(test_func_file)
248{
249 int res = AST_TEST_PASS;
250 int i;
251 char dir[] = "/tmp/test_func_file.XXXXXX";
252 char file[80], expression[256];
253 struct ast_str *buf, *disp[2] = { NULL, NULL };
254 char fbuf[8192];
255 FILE *fh;
256
257 switch (cmd) {
258 case TEST_INIT:
259 info->name = "func_file";
260 info->category = "/funcs/func_env/";
261 info->summary = "Verify behavior of the FILE() dialplan function";
262 info->description =
263 "Verifies that the examples of the FILE() dialplan function documentation work as described.";
264 return AST_TEST_NOT_RUN;
265 case TEST_EXECUTE:
266 break;
267 }
268
269 if (!mkdtemp(dir)) {
270 ast_test_status_update(test, "Cannot create temporary directory: %s\n", strerror(errno));
271 return AST_TEST_FAIL;
272 }
273
274 disp[0] = ast_str_create(16);
275 disp[1] = ast_str_create(16);
276 if (!(buf = ast_str_create(16)) || !disp[0] || !disp[1]) {
277 ast_free(buf);
278 ast_free(disp[0]);
279 ast_free(disp[1]);
280 rmdir(dir);
281 return AST_TEST_FAIL;
282 }
283
284 snprintf(file, sizeof(file), "%s/test.txt", dir);
285
286 for (i = 0; i < ARRAY_LEN(read_tests); i++) {
287 if (!(fh = fopen(file, "w"))) {
288 ast_test_status_update(test, "Cannot open test file: %s\n", strerror(errno));
289 ast_free(buf);
290 ast_free(disp[0]);
291 ast_free(disp[1]);
292 unlink(file);
293 rmdir(dir);
294 return AST_TEST_FAIL;
295 }
296
297 if (fwrite(read_tests[i].contents, 1, strlen(read_tests[i].contents), fh) < strlen(read_tests[i].contents)) {
298 ast_test_status_update(test, "Cannot write initial values into test file: %s\n", strerror(errno));
299 ast_free(buf);
300 ast_free(disp[0]);
301 ast_free(disp[1]);
302 fclose(fh);
303 unlink(file);
304 rmdir(dir);
305 return AST_TEST_FAIL;
306 }
307
308 fclose(fh);
309
310 snprintf(expression, sizeof(expression), "${FILE(%s,%s)}", file, read_tests[i].args);
311 ast_str_substitute_variables(&buf, 0, NULL, expression);
312
313 if (strcmp(ast_str_buffer(buf), read_tests[i].value)) {
314 ast_test_status_update(test, "Expression '${FILE(...,%s)}' did not produce ('%s') the expected value ('%s')\n",
315 read_tests[i].args, file2display(&disp[0], 0, ast_str_buffer(buf)), file2display(&disp[1], 0, read_tests[i].value));
316 res = AST_TEST_FAIL;
317 }
318 }
319
320 ast_free(buf);
321
322 for (i = 0; i < ARRAY_LEN(write_tests); i++) {
323 if (!(fh = fopen(file, "w"))) {
324 ast_test_status_update(test, "Cannot open test file: %s\n", strerror(errno));
325 ast_free(disp[0]);
326 ast_free(disp[1]);
327 unlink(file);
328 rmdir(dir);
329 return AST_TEST_FAIL;
330 }
331
332 if (fwrite(write_tests[i].contents, 1, strlen(write_tests[i].contents), fh) < strlen(write_tests[i].contents)) {
333 ast_test_status_update(test, "Cannot write initial values into test file: %s\n", strerror(errno));
334 ast_free(disp[0]);
335 ast_free(disp[1]);
336 fclose(fh);
337 unlink(file);
338 rmdir(dir);
339 return AST_TEST_FAIL;
340 }
341
342 fclose(fh);
343
344 snprintf(expression, sizeof(expression), "FILE(%s,%s)", file, write_tests[i].args);
345 ast_func_write(NULL, expression, write_tests[i].value);
346
347 if (!(fh = fopen(file, "r"))) {
348 ast_test_status_update(test, "Cannot open test file: %s\n", strerror(errno));
349 ast_free(disp[0]);
350 ast_free(disp[1]);
351 unlink(file);
352 rmdir(dir);
353 return AST_TEST_FAIL;
354 }
355
356 memset(fbuf, 0, sizeof(fbuf));
357 if (!fread(fbuf, 1, sizeof(fbuf), fh)) {
358 ast_test_status_update(test, "Cannot read write results from test file: %s\n", strerror(errno));
359 ast_free(disp[0]);
360 ast_free(disp[1]);
361 fclose(fh);
362 unlink(file);
363 rmdir(dir);
364 return AST_TEST_FAIL;
365 }
366
367 fclose(fh);
368
369 if (strcmp(fbuf, write_tests[i].contents2)) {
370 ast_test_status_update(test, "Expression 'FILE(...,%s)=%s' did not produce ('%s') the expected result ('%s')\n",
371 write_tests[i].args, write_tests[i].value, file2display(&disp[0], 0, fbuf), file2display(&disp[1], 0, write_tests[i].contents2));
372 res = AST_TEST_FAIL;
373 } else {
374 ast_test_status_update(test, "Expression 'FILE(...,%s)=%s'... OK!\n", write_tests[i].args, write_tests[i].value);
375 }
376 }
377
378 ast_free(disp[0]);
379 ast_free(disp[1]);
380 unlink(file);
381 rmdir(dir);
382
383 return res;
384}
385
386static int unload_module(void)
387{
388 AST_TEST_UNREGISTER(test_func_file);
389 return 0;
390}
391
392static int load_module(void)
393{
394 AST_TEST_REGISTER(test_func_file);
396}
397
char * mkdtemp(char *template_s)
#define ast_free(a)
Definition astmm.h:180
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition module.h:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
int ast_func_write(struct ast_channel *chan, const char *function, const char *value)
executes a write operation on a function
#define NULL
Definition resample.c:96
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition strings.h:693
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
Support for dynamic strings.
Definition strings.h:623
@ TEST_INIT
Definition test.h:200
@ TEST_EXECUTE
Definition test.h:201
#define AST_TEST_REGISTER(cb)
Definition test.h:127
#define ast_test_status_update(a, b, c...)
Definition test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition test.h:128
#define AST_TEST_DEFINE(hdr)
Definition test.h:126
@ AST_TEST_PASS
Definition test.h:195
@ AST_TEST_FAIL
Definition test.h:196
@ AST_TEST_NOT_RUN
Definition test.h:194
static struct @536 read_tests[]
#define C1024
static char * file2display(struct ast_str **buf, ssize_t len, const char *input)
const char * args
const char * value
const char * contents2
static struct @537 write_tests[]
static int load_module(void)
static int unload_module(void)
const char * contents
#define ARRAY_LEN(a)
Definition utils.h:706

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 399 of file test_func_file.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 399 of file test_func_file.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 399 of file test_func_file.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( test_func_file  )

Definition at line 248 of file test_func_file.c.

249{
250 int res = AST_TEST_PASS;
251 int i;
252 char dir[] = "/tmp/test_func_file.XXXXXX";
253 char file[80], expression[256];
254 struct ast_str *buf, *disp[2] = { NULL, NULL };
255 char fbuf[8192];
256 FILE *fh;
257
258 switch (cmd) {
259 case TEST_INIT:
260 info->name = "func_file";
261 info->category = "/funcs/func_env/";
262 info->summary = "Verify behavior of the FILE() dialplan function";
263 info->description =
264 "Verifies that the examples of the FILE() dialplan function documentation work as described.";
265 return AST_TEST_NOT_RUN;
266 case TEST_EXECUTE:
267 break;
268 }
269
270 if (!mkdtemp(dir)) {
271 ast_test_status_update(test, "Cannot create temporary directory: %s\n", strerror(errno));
272 return AST_TEST_FAIL;
273 }
274
275 disp[0] = ast_str_create(16);
276 disp[1] = ast_str_create(16);
277 if (!(buf = ast_str_create(16)) || !disp[0] || !disp[1]) {
278 ast_free(buf);
279 ast_free(disp[0]);
280 ast_free(disp[1]);
281 rmdir(dir);
282 return AST_TEST_FAIL;
283 }
284
285 snprintf(file, sizeof(file), "%s/test.txt", dir);
286
287 for (i = 0; i < ARRAY_LEN(read_tests); i++) {
288 if (!(fh = fopen(file, "w"))) {
289 ast_test_status_update(test, "Cannot open test file: %s\n", strerror(errno));
290 ast_free(buf);
291 ast_free(disp[0]);
292 ast_free(disp[1]);
293 unlink(file);
294 rmdir(dir);
295 return AST_TEST_FAIL;
296 }
297
298 if (fwrite(read_tests[i].contents, 1, strlen(read_tests[i].contents), fh) < strlen(read_tests[i].contents)) {
299 ast_test_status_update(test, "Cannot write initial values into test file: %s\n", strerror(errno));
300 ast_free(buf);
301 ast_free(disp[0]);
302 ast_free(disp[1]);
303 fclose(fh);
304 unlink(file);
305 rmdir(dir);
306 return AST_TEST_FAIL;
307 }
308
309 fclose(fh);
310
311 snprintf(expression, sizeof(expression), "${FILE(%s,%s)}", file, read_tests[i].args);
312 ast_str_substitute_variables(&buf, 0, NULL, expression);
313
314 if (strcmp(ast_str_buffer(buf), read_tests[i].value)) {
315 ast_test_status_update(test, "Expression '${FILE(...,%s)}' did not produce ('%s') the expected value ('%s')\n",
316 read_tests[i].args, file2display(&disp[0], 0, ast_str_buffer(buf)), file2display(&disp[1], 0, read_tests[i].value));
317 res = AST_TEST_FAIL;
318 }
319 }
320
321 ast_free(buf);
322
323 for (i = 0; i < ARRAY_LEN(write_tests); i++) {
324 if (!(fh = fopen(file, "w"))) {
325 ast_test_status_update(test, "Cannot open test file: %s\n", strerror(errno));
326 ast_free(disp[0]);
327 ast_free(disp[1]);
328 unlink(file);
329 rmdir(dir);
330 return AST_TEST_FAIL;
331 }
332
333 if (fwrite(write_tests[i].contents, 1, strlen(write_tests[i].contents), fh) < strlen(write_tests[i].contents)) {
334 ast_test_status_update(test, "Cannot write initial values into test file: %s\n", strerror(errno));
335 ast_free(disp[0]);
336 ast_free(disp[1]);
337 fclose(fh);
338 unlink(file);
339 rmdir(dir);
340 return AST_TEST_FAIL;
341 }
342
343 fclose(fh);
344
345 snprintf(expression, sizeof(expression), "FILE(%s,%s)", file, write_tests[i].args);
346 ast_func_write(NULL, expression, write_tests[i].value);
347
348 if (!(fh = fopen(file, "r"))) {
349 ast_test_status_update(test, "Cannot open test file: %s\n", strerror(errno));
350 ast_free(disp[0]);
351 ast_free(disp[1]);
352 unlink(file);
353 rmdir(dir);
354 return AST_TEST_FAIL;
355 }
356
357 memset(fbuf, 0, sizeof(fbuf));
358 if (!fread(fbuf, 1, sizeof(fbuf), fh)) {
359 ast_test_status_update(test, "Cannot read write results from test file: %s\n", strerror(errno));
360 ast_free(disp[0]);
361 ast_free(disp[1]);
362 fclose(fh);
363 unlink(file);
364 rmdir(dir);
365 return AST_TEST_FAIL;
366 }
367
368 fclose(fh);
369
370 if (strcmp(fbuf, write_tests[i].contents2)) {
371 ast_test_status_update(test, "Expression 'FILE(...,%s)=%s' did not produce ('%s') the expected result ('%s')\n",
372 write_tests[i].args, write_tests[i].value, file2display(&disp[0], 0, fbuf), file2display(&disp[1], 0, write_tests[i].contents2));
373 res = AST_TEST_FAIL;
374 } else {
375 ast_test_status_update(test, "Expression 'FILE(...,%s)=%s'... OK!\n", write_tests[i].args, write_tests[i].value);
376 }
377 }
378
379 ast_free(disp[0]);
380 ast_free(disp[1]);
381 unlink(file);
382 rmdir(dir);
383
384 return res;
385}

References args, ARRAY_LEN, ast_free, ast_func_write(), ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, buf, contents, contents2, errno, file2display(), mkdtemp(), NULL, read_tests, TEST_EXECUTE, TEST_INIT, value, and write_tests.

◆ file2display()

static char * file2display ( struct ast_str **  buf,
ssize_t  len,
const char *  input 
)
static

Definition at line 228 of file test_func_file.c.

229{
230 const char *ptr;
232 for (ptr = input; *ptr; ptr++) {
233 if (*ptr == '\n') {
234 ast_str_append(buf, len, "\\n");
235 } else if (*ptr == '\r') {
236 ast_str_append(buf, len, "\\r");
237 } else if (*ptr == '\t') {
238 ast_str_append(buf, len, "\\t");
239 } else if (*ptr < ' ' || *ptr > 125) {
240 ast_str_append(buf, len, "\\x%hhX", *ptr);
241 } else {
242 ast_str_append(buf, len, "%c", *ptr);
243 }
244 }
245 return ast_str_buffer(*buf);
246}

References ast_str_append(), ast_str_buffer(), ast_str_reset(), buf, and len().

Referenced by AST_TEST_DEFINE().

◆ load_module()

static int load_module ( void  )
static

Definition at line 393 of file test_func_file.c.

394{
395 AST_TEST_REGISTER(test_func_file);
397}

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 387 of file test_func_file.c.

388{
389 AST_TEST_UNREGISTER(test_func_file);
390 return 0;
391}

References AST_TEST_UNREGISTER.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "FILE() Tests" , .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 399 of file test_func_file.c.

◆ args

const char* args

Definition at line 46 of file test_func_file.c.

Referenced by AST_TEST_DEFINE().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 399 of file test_func_file.c.

◆ contents

const char* contents

◆ contents2

const char* contents2

Definition at line 91 of file test_func_file.c.

Referenced by AST_TEST_DEFINE().

◆ [struct]

struct { ... } read_tests[]

Referenced by AST_TEST_DEFINE().

◆ value

const char* value

Definition at line 47 of file test_func_file.c.

Referenced by AST_TEST_DEFINE().

◆ [struct]

struct { ... } write_tests[]

Referenced by AST_TEST_DEFINE().