Merge "Revert "app_voicemail: Remove need to subscribe to stasis""
[asterisk/asterisk.git] / tests / test_strings.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * Mark Michelson <mmichelson@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Dynamic string tests
22  *
23  * \author Mark Michelson <mmichelson@digium.com>
24  *
25  * This module will run some dyanmic string tests.
26  *
27  * \ingroup tests
28  */
29
30 /*** MODULEINFO
31         <depend>TEST_FRAMEWORK</depend>
32         <support_level>core</support_level>
33  ***/
34
35 #include "asterisk.h"
36
37 #include "asterisk/test.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/strings.h"
40 #include "asterisk/module.h"
41
42 AST_TEST_DEFINE(str_test)
43 {
44         struct ast_str *stack_str;
45         struct ast_str *heap_str;
46         const char short_string1[] = "apple";
47         const char short_string2[] = "banana";
48         char short_string_cat[30];
49         const char long_string1[] = "applebananapeachmangocherrypeargrapeplumlimetangerinepomegranategravel";
50         const char long_string2[] = "passionuglinectarinepineapplekiwilemonpaintthinner";
51         char long_string_cat[200];
52         char string_limit_cat[11];
53         const int string_limit = 5;
54         int current_size;
55         enum ast_test_result_state res = AST_TEST_PASS;
56
57         switch (cmd) {
58         case TEST_INIT:
59                 info->name = "str_test";
60                 info->category = "/main/strings/";
61                 info->summary = "Test dynamic string operations";
62                 info->description = "Test setting and appending stack and heap-allocated strings";
63                 return AST_TEST_NOT_RUN;
64         case TEST_EXECUTE:
65                 break;
66         }
67         snprintf(short_string_cat, sizeof(short_string_cat), "%s%s", short_string1, short_string2);
68         snprintf(long_string_cat, sizeof(long_string_cat), "%s%s", long_string1, long_string2);
69         snprintf(string_limit_cat, string_limit, "%s", long_string1);
70         strncat(string_limit_cat, long_string2, string_limit);
71
72         if (!(stack_str = ast_str_alloca(15))) {
73                 ast_test_status_update(test, "Failed to allocate an ast_str on the stack\n");
74                 return AST_TEST_FAIL;
75         }
76
77         if (!(heap_str = ast_str_create(15))) {
78                 ast_test_status_update(test, "Failed to allocate an ast_str on the heap\n");
79         }
80
81         /* Stack string tests:
82          * Part 1: Basic tests
83          * a. set a small string
84          * b. append a small string
85          * c. clear a string
86          * Part 2: Advanced tests
87          * a. Set a string that is larger than our allocation
88          * b. Append a string that is larger than our allocation
89          */
90
91         /* Part 1a */
92         if (ast_str_set(&stack_str, 0, "%s", short_string1) < 0) {
93                 ast_test_status_update(test, "Error setting stack string\n");
94                 res = AST_TEST_FAIL;
95                 goto cleanup;
96         }
97         if (strcmp(ast_str_buffer(stack_str), short_string1)) {
98                 ast_test_status_update(test, "ast_str_set failed for stack string. Expected '%s' but"
99                                 "instead got %s\n", short_string1, ast_str_buffer(stack_str));
100                 res = AST_TEST_FAIL;
101                 goto cleanup;
102         }
103         /* Part 1b */
104         if (ast_str_append(&stack_str, 0, "%s", short_string2) < 0) {
105                 ast_test_status_update(test, "Error appending to stack string\n");
106                 res = AST_TEST_FAIL;
107                 goto cleanup;
108         }
109         if (strcmp(ast_str_buffer(stack_str), short_string_cat)) {
110                 ast_test_status_update(test, "ast_str_set failed for stack string. Expected '%s'"
111                                 "but instead got %s\n", short_string_cat, ast_str_buffer(stack_str));
112                 res = AST_TEST_FAIL;
113                 goto cleanup;
114         }
115         /* Part 1c */
116         ast_str_reset(stack_str);
117         if (ast_str_strlen(stack_str) != 0) {
118                 ast_test_status_update(test, "ast_str_reset resulted in non-zero length for stack_str\n");
119                 res = AST_TEST_FAIL;
120                 goto cleanup;
121         }
122
123         /* Part 2a */
124         if (ast_str_set(&stack_str, -1, "%s", long_string1) < 0) {
125                 ast_test_status_update(test, "Error setting stack string with long input\n");
126                 res = AST_TEST_FAIL;
127                 goto cleanup;
128         }
129         if (strncmp(ast_str_buffer(stack_str), long_string1, ast_str_strlen(stack_str))) {
130                 ast_test_status_update(test, "Stack string not set to what is expected.\n");
131                 res = AST_TEST_FAIL;
132                 goto cleanup;
133         }
134         /* Part 2b */
135         if (ast_str_append(&stack_str, -1, "%s", long_string2) < 0) {
136                 ast_test_status_update(test, "Error appending long string to full stack string buffer\n");
137                 res = AST_TEST_FAIL;
138                 goto cleanup;
139         }
140         if (strncmp(ast_str_buffer(stack_str), long_string_cat, ast_str_strlen(stack_str))) {
141                 ast_test_status_update(test, "Stack string not set to what is expected.\n");
142                 res = AST_TEST_FAIL;
143                 goto cleanup;
144         }
145
146         /* Heap string tests
147          *
148          * All stack string tests from part 1.
149          * All stack string tests 2a and 2b.
150          * Tests 2a and 2b from stack string tests, passing 0 as max_len
151          * instead of -1. This allows for the buffer to grow.
152          */
153         /* Part 1a */
154         if (ast_str_set(&heap_str, 0, "%s", short_string1) < 0) {
155                 ast_test_status_update(test, "Error setting heap string\n");
156                 res = AST_TEST_FAIL;
157                 goto cleanup;
158         }
159         if (strcmp(ast_str_buffer(heap_str), short_string1)) {
160                 ast_test_status_update(test, "ast_str_set failed for heap string. Expected '%s' but"
161                                 "instead got %s\n", short_string1, ast_str_buffer(heap_str));
162                 res = AST_TEST_FAIL;
163                 goto cleanup;
164         }
165         /* Part 1b */
166         if (ast_str_append(&heap_str, 0, "%s", short_string2) < 0) {
167                 ast_test_status_update(test, "Error appending to heap string\n");
168                 res = AST_TEST_FAIL;
169                 goto cleanup;
170         }
171         if (strcmp(ast_str_buffer(heap_str), short_string_cat)) {
172                 ast_test_status_update(test, "ast_str_set failed for stack string. Expected '%s'"
173                                 "but instead got %s\n", short_string_cat, ast_str_buffer(stack_str));
174                 res = AST_TEST_FAIL;
175                 goto cleanup;
176         }
177         /* Part 1c */
178         ast_str_reset(heap_str);
179         if (ast_str_strlen(heap_str) != 0) {
180                 ast_test_status_update(test, "ast_str_reset resulted in non-zero length for stack_str\n");
181                 res = AST_TEST_FAIL;
182                 goto cleanup;
183         }
184         /* Part 2a with -1 arg */
185         current_size = ast_str_size(heap_str);
186         if (ast_str_set(&heap_str, -1, "%s", long_string1) < 0) {
187                 ast_test_status_update(test, "Error setting heap string with long input\n");
188                 res = AST_TEST_FAIL;
189                 goto cleanup;
190         }
191         if (current_size != ast_str_size(heap_str)) {
192                 ast_test_status_update(test, "Heap string changed size during ast_str_set when it was"
193                                 "instructed not to. Was %d and now is %d\n", current_size, (int) ast_str_size(heap_str));
194                 res = AST_TEST_FAIL;
195                 goto cleanup;
196         }
197         if (strncmp(ast_str_buffer(heap_str), long_string1, ast_str_strlen(heap_str))) {
198                 ast_test_status_update(test, "Heap string not set to what is expected.\n");
199                 res = AST_TEST_FAIL;
200                 goto cleanup;
201         }
202         /* Part 2b with -1 arg */
203         current_size = ast_str_size(heap_str);
204         if (ast_str_append(&heap_str, -1, "%s", long_string2) < 0) {
205                 ast_test_status_update(test, "Error appending long string to full heap string buffer\n");
206                 res = AST_TEST_FAIL;
207                 goto cleanup;
208         }
209         if (current_size != ast_str_size(heap_str)) {
210                 ast_test_status_update(test, "Heap string changed size during ast_str_append when it was"
211                                 "instructed not to. Was %d and now is %d\n", current_size, (int) ast_str_size(heap_str));
212                 res = AST_TEST_FAIL;
213                 goto cleanup;
214         }
215         if (strncmp(ast_str_buffer(heap_str), long_string_cat, ast_str_strlen(heap_str))) {
216                 ast_test_status_update(test, "Heap string not set to what is expected.\n");
217                 res = AST_TEST_FAIL;
218                 goto cleanup;
219         }
220         /* reset string before continuing */
221         ast_str_reset(heap_str);
222         /* Part 2a with 0 arg */
223         if (ast_str_set(&heap_str, 0, "%s", long_string1) < 0) {
224                 ast_test_status_update(test, "Error setting heap string with long input\n");
225                 res = AST_TEST_FAIL;
226                 goto cleanup;
227         }
228         if (strcmp(ast_str_buffer(heap_str), long_string1)) {
229                 ast_test_status_update(test, "Heap string does not contain what was expected. Expected %s"
230                                 "but have %s instead\n", long_string1, ast_str_buffer(heap_str));
231                 res = AST_TEST_FAIL;
232                 goto cleanup;
233         }
234         /* Part 2b with 0 arg */
235         if (ast_str_append(&heap_str, 0, "%s", long_string2) < 0) {
236                 ast_test_status_update(test, "Error setting heap string with long input\n");
237                 res = AST_TEST_FAIL;
238                 goto cleanup;
239         }
240         if (strcmp(ast_str_buffer(heap_str), long_string_cat)) {
241                 ast_test_status_update(test, "Heap string does not contain what was expected. Expected %s"
242                                 "but have %s instead\n", long_string_cat, ast_str_buffer(heap_str));
243                 res = AST_TEST_FAIL;
244                 goto cleanup;
245         }
246
247 cleanup:
248         ast_free(heap_str);
249         return res;
250 }
251
252 AST_TEST_DEFINE(begins_with_test)
253 {
254         switch (cmd) {
255         case TEST_INIT:
256                 info->name = "begins_with";
257                 info->category = "/main/strings/";
258                 info->summary = "Test ast_begins_with";
259                 info->description = "Test ast_begins_with";
260                 return AST_TEST_NOT_RUN;
261         case TEST_EXECUTE:
262                 break;
263         }
264
265         // prefixes
266         ast_test_validate(test, 1 == ast_begins_with("foobar", "foobar"));
267         ast_test_validate(test, 1 == ast_begins_with("foobar", "foo"));
268         ast_test_validate(test, 1 == ast_begins_with("foobar", ""));
269         ast_test_validate(test, 1 == ast_begins_with("", ""));
270
271         // not prefixes
272         ast_test_validate(test, 0 == ast_begins_with("foobar", "bang"));
273         ast_test_validate(test, 0 == ast_begins_with("foobar", "foobat"));
274         ast_test_validate(test, 0 == ast_begins_with("boo", "boom"));
275         ast_test_validate(test, 0 == ast_begins_with("", "blitz"));
276
277         // nothing failed; we're all good!
278         return AST_TEST_PASS;
279 }
280
281 AST_TEST_DEFINE(ends_with_test)
282 {
283         switch (cmd) {
284         case TEST_INIT:
285                 info->name = "ends_with";
286                 info->category = "/main/strings/";
287                 info->summary = "Test ast_ends_with";
288                 info->description = "Test ast_ends_with";
289                 return AST_TEST_NOT_RUN;
290         case TEST_EXECUTE:
291                 break;
292         }
293
294         // prefixes
295         ast_test_validate(test, 1 == ast_ends_with("foobar", "foobar"));
296         ast_test_validate(test, 1 == ast_ends_with("foobar", "bar"));
297         ast_test_validate(test, 1 == ast_ends_with("foobar", ""));
298         ast_test_validate(test, 1 == ast_ends_with("", ""));
299
300         // not suffixes
301         ast_test_validate(test, 0 == ast_ends_with("bar", "bbar"));
302         ast_test_validate(test, 0 == ast_ends_with("foobar", "bang"));
303         ast_test_validate(test, 0 == ast_ends_with("foobar", "foobat"));
304         ast_test_validate(test, 0 == ast_ends_with("boo", "boom"));
305         ast_test_validate(test, 0 == ast_ends_with("", "blitz"));
306
307         // nothing failed; we're all good!
308         return AST_TEST_PASS;
309 }
310
311 AST_TEST_DEFINE(strsep_test)
312 {
313         char *test1, *test2, *test3;
314
315         switch (cmd) {
316         case TEST_INIT:
317                 info->name = "strsep";
318                 info->category = "/main/strings/";
319                 info->summary = "Test ast_strsep";
320                 info->description = "Test ast_strsep";
321                 return AST_TEST_NOT_RUN;
322         case TEST_EXECUTE:
323                 break;
324         }
325
326         test1 = ast_strdupa("ghi=jkl,mno='pqr,stu',abc=def, vwx = yz1 ,  vwx = yz1 ,  '"
327                 " vwx = yz1 ' ,  ' vwx , yz1 ',v\"w\"x, '\"x,v\",\"x\"' , \" i\\'m a test\""
328                 ", \" i\\'m a, test\", \" i\\'m a, test\", e\\,nd, end\\");
329
330         test2 = ast_strsep(&test1, ',', 0);
331         ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
332
333         test3 = ast_strsep(&test2, '=', 0);
334         ast_test_validate(test, 0 == strcmp("ghi", test3));
335
336         test3 = ast_strsep(&test2, '=', 0);
337         ast_test_validate(test, 0 == strcmp("jkl", test3));
338
339         test2 = ast_strsep(&test1, ',', 0);
340         ast_test_validate(test, 0 == strcmp("mno='pqr,stu'", test2));
341
342         test3 = ast_strsep(&test2, '=', 0);
343         ast_test_validate(test, 0 == strcmp("mno", test3));
344
345         test3 = ast_strsep(&test2, '=', 0);
346         ast_test_validate(test, 0 == strcmp("'pqr,stu'", test3));
347
348         test2 = ast_strsep(&test1, ',', 0);
349         ast_test_validate(test, 0 == strcmp("abc=def", test2));
350
351         test2 = ast_strsep(&test1, ',', 0);
352         ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
353
354         test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
355         ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
356
357         test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP);
358         ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
359
360         test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
361         ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
362
363         test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
364         ast_test_validate(test, 0 == strcmp("v\"w\"x", test2));
365
366         test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
367         ast_test_validate(test, 0 == strcmp("'\"x,v\",\"x\"'", test2));
368
369         test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
370         ast_test_validate(test, 0 == strcmp("\" i\\'m a test\"", test2));
371
372         test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
373         ast_test_validate(test, 0 == strcmp("\" i'm a, test\"", test2));
374
375         test2 = ast_strsep(&test1, ',', AST_STRSEP_ALL);
376         ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
377
378         test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
379         ast_test_validate(test, 0 == strcmp("e,nd", test2));
380
381         test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
382         ast_test_validate(test, 0 == strcmp("end", test2));
383
384         // nothing failed; we're all good!
385         return AST_TEST_PASS;
386 }
387
388 static int test_semi(char *string1, char *string2, int test_len)
389 {
390         char *test2 = NULL;
391
392         if (test_len > 0) {
393                 test2 = ast_alloca(test_len);
394                 *test2 = '\0';
395         } else if (test_len == 0) {
396                 test2 = "";
397         }
398         ast_escape_semicolons(string1, test2, test_len);
399         if (test2 != NULL && strcmp(string2, test2) == 0) {
400                 return 1;
401         } else {
402                 return 0;
403         }
404 }
405
406 AST_TEST_DEFINE(escape_semicolons_test)
407 {
408         switch (cmd) {
409         case TEST_INIT:
410                 info->name = "escape_semicolons";
411                 info->category = "/main/strings/";
412                 info->summary = "Test ast_escape_semicolons";
413                 info->description = "Test ast_escape_semicolons";
414                 return AST_TEST_NOT_RUN;
415         case TEST_EXECUTE:
416                 break;
417         }
418
419
420         ast_test_validate(test, test_semi("this is a ;test", "this is a \\;test", 18));
421         ast_test_validate(test, test_semi(";", "\\;", 3));
422
423         /* The following tests should return empty because there's not enough room to output
424          * an escaped ; or even a single character.
425          */
426         ast_test_validate(test, test_semi(";", "", 0));
427         ast_test_validate(test, test_semi(";", "", 1));
428         ast_test_validate(test, test_semi(";", "", 2));
429         ast_test_validate(test, test_semi("x", "", 0));
430         ast_test_validate(test, test_semi("x", "", 1));
431
432         /* At least some output should be produced now. */
433         ast_test_validate(test, test_semi("xx;xx", "x", 2));
434         ast_test_validate(test, test_semi("xx;xx", "xx", 3));
435
436         /* There's still not enough room to output \; so
437          * don't even print the \
438          */
439         ast_test_validate(test, test_semi("xx;xx", "xx", 4));
440
441         ast_test_validate(test, test_semi("xx;xx", "xx\\;", 5));
442         ast_test_validate(test, test_semi("xx;xx", "xx\\;x", 6));
443         ast_test_validate(test, test_semi("xx;xx", "xx\\;xx", 7));
444         ast_test_validate(test, test_semi("xx;xx", "xx\\;xx", 8));
445
446         /* Random stuff */
447         ast_test_validate(test, test_semi("xx;xx;this is a test", "xx\\;xx\\;this is a test", 32));
448         ast_test_validate(test, test_semi(";;;;;", "\\;\\;\\;\\;\\;", 32));
449         ast_test_validate(test, test_semi(";;;;;", "\\;\\;\\;\\;", 10));
450         ast_test_validate(test, test_semi(";;;;;", "\\;\\;\\;\\;\\;", 11));
451         ast_test_validate(test, test_semi(";;\\;;;", "\\;\\;\\\\;\\;\\;", 32));
452
453         return AST_TEST_PASS;
454 }
455
456 AST_TEST_DEFINE(escape_test)
457 {
458         char buf[128];
459
460 #define TEST_ESCAPE(s, to_escape, expected) \
461         !strcmp(ast_escape(buf, s, ARRAY_LEN(buf), to_escape), expected)
462
463 #define TEST_ESCAPE_C(s, expected) \
464         !strcmp(ast_escape_c(buf, s, ARRAY_LEN(buf)), expected)
465
466 #define TEST_ESCAPE_ALLOC(s, to_escape, expected)               \
467         ({                                                                                                      \
468                 int res = 0;                                                                    \
469                 char *a_buf = ast_escape_alloc(s, to_escape);   \
470                 if (a_buf) {                                                                    \
471                         res = !strcmp(a_buf, expected);                         \
472                         ast_free(a_buf);                                                        \
473                 }                                                                                               \
474                 res;                                                                                    \
475         })
476
477 #define TEST_ESCAPE_C_ALLOC(s, expected)                                \
478         ({                                                                                                      \
479                 int res = 0;                                                                    \
480                 char *a_buf = ast_escape_c_alloc(s);                    \
481                 if (a_buf) {                                                                    \
482                         res = !strcmp(a_buf, expected);                         \
483                         ast_free(a_buf);                                                        \
484                 }                                                                                               \
485                 res;                                                                                    \
486         })
487
488         switch (cmd) {
489         case TEST_INIT:
490                 info->name = "escape";
491                 info->category = "/main/strings/";
492                 info->summary = "Test ast_escape";
493                 info->description = "Test escaping values in a string";
494                 return AST_TEST_NOT_RUN;
495         case TEST_EXECUTE:
496                 break;
497         }
498
499         ast_test_validate(test, TEST_ESCAPE("null escape", NULL, "null escape"));
500         ast_test_validate(test, TEST_ESCAPE("empty escape", "", "empty escape"));
501         ast_test_validate(test, TEST_ESCAPE("", "Z", ""));
502         ast_test_validate(test, TEST_ESCAPE("no matching escape", "Z", "no matching escape"));
503         ast_test_validate(test, TEST_ESCAPE("escape Z", "Z", "escape \\Z"));
504         ast_test_validate(test, TEST_ESCAPE("Z", "Z", "\\Z"));
505         ast_test_validate(test, TEST_ESCAPE(";;", ";", "\\;\\;"));
506         ast_test_validate(test, TEST_ESCAPE("escape \n", "\n", "escape \\n"));
507         ast_test_validate(test, TEST_ESCAPE("escape \n again \n", "\n", "escape \\n again \\n"));
508
509         ast_test_validate(test, TEST_ESCAPE_C("", ""));
510         ast_test_validate(test, TEST_ESCAPE_C("escape \a\b\f\n\r\t\v\\\'\"\?",
511                 "escape \\a\\b\\f\\n\\r\\t\\v\\\\\\\'\\\"\\?"));
512
513         ast_test_validate(test, TEST_ESCAPE_ALLOC("", "Z", ""));
514         ast_test_validate(test, TEST_ESCAPE_ALLOC("Z", "Z", "\\Z"));
515         ast_test_validate(test, TEST_ESCAPE_ALLOC("a", "Z", "a"));
516
517         ast_test_validate(test, TEST_ESCAPE_C_ALLOC("", ""));
518         ast_test_validate(test, TEST_ESCAPE_C_ALLOC("\n", "\\n"));
519         ast_test_validate(test, TEST_ESCAPE_C_ALLOC("a", "a"));
520
521         return AST_TEST_PASS;
522 }
523
524 AST_TEST_DEFINE(strings_match)
525 {
526         switch (cmd) {
527         case TEST_INIT:
528                 info->name = "strings_match";
529                 info->category = "/main/strings/";
530                 info->summary = "Test ast_strings_match";
531                 info->description = "Test ast_strings_match";
532                 return AST_TEST_NOT_RUN;
533         case TEST_EXECUTE:
534                 break;
535         }
536
537         ast_test_validate(test, ast_strings_match("aaa", NULL, "aaa"));
538         ast_test_validate(test, ast_strings_match("aaa", "", "aaa"));
539         ast_test_validate(test, ast_strings_match("aaa", "=", "aaa"));
540         ast_test_validate(test, !ast_strings_match("aaa", "!=", "aaa"));
541         ast_test_validate(test, !ast_strings_match("aaa", NULL, "aba"));
542         ast_test_validate(test, !ast_strings_match("aaa", "", "aba"));
543         ast_test_validate(test, !ast_strings_match("aaa", "=", "aba"));
544         ast_test_validate(test, ast_strings_match("aaa", "!=", "aba"));
545
546         ast_test_validate(test, ast_strings_match("aaa", "<=", "aba"));
547         ast_test_validate(test, ast_strings_match("aaa", "<=", "aaa"));
548         ast_test_validate(test, !ast_strings_match("aaa", "<", "aaa"));
549
550         ast_test_validate(test, !ast_strings_match("aaa", ">=", "aba"));
551         ast_test_validate(test, ast_strings_match("aaa", ">=", "aaa"));
552         ast_test_validate(test, !ast_strings_match("aaa", ">", "aaa"));
553
554         ast_test_validate(test, !ast_strings_match("aaa", "=", "aa"));
555         ast_test_validate(test, ast_strings_match("aaa", ">", "aa"));
556         ast_test_validate(test, !ast_strings_match("aaa", "<", "aa"));
557
558         ast_test_validate(test, ast_strings_match("1", "=", "1"));
559         ast_test_validate(test, !ast_strings_match("1", "!=", "1"));
560         ast_test_validate(test, !ast_strings_match("2", "=", "1"));
561         ast_test_validate(test, ast_strings_match("2", ">", "1"));
562         ast_test_validate(test, ast_strings_match("2", ">=", "1"));
563         ast_test_validate(test, ast_strings_match("2", ">", "1.9888"));
564         ast_test_validate(test, ast_strings_match("2.9", ">", "1"));
565         ast_test_validate(test, ast_strings_match("2", ">", "1"));
566         ast_test_validate(test, ast_strings_match("2.999", "<", "3"));
567         ast_test_validate(test, ast_strings_match("2", ">", "#"));
568
569         ast_test_validate(test, ast_strings_match("abcccc", "like", "%a%c"));
570         ast_test_validate(test, !ast_strings_match("abcccx", "like", "%a%c"));
571         ast_test_validate(test, ast_strings_match("abcccc", "regex", "a[bc]+c"));
572         ast_test_validate(test, !ast_strings_match("abcccx", "regex", "^a[bxdfgtc]+c$"));
573
574         ast_test_validate(test, !ast_strings_match("neener-93joe", "LIKE", "%blah-%"));
575         ast_test_validate(test, ast_strings_match("blah-93joe", "LIKE", "%blah-%"));
576
577         ast_test_validate(test, !ast_strings_match("abcccx", "regex", NULL));
578         ast_test_validate(test, !ast_strings_match("abcccx", NULL, NULL));
579         ast_test_validate(test, !ast_strings_match(NULL, "regex", NULL));
580         ast_test_validate(test, !ast_strings_match(NULL, NULL, "abc"));
581         ast_test_validate(test, !ast_strings_match(NULL, NULL, NULL));
582
583         return AST_TEST_PASS;
584 }
585
586 static int unload_module(void)
587 {
588         AST_TEST_UNREGISTER(str_test);
589         AST_TEST_UNREGISTER(begins_with_test);
590         AST_TEST_UNREGISTER(ends_with_test);
591         AST_TEST_UNREGISTER(strsep_test);
592         AST_TEST_UNREGISTER(escape_semicolons_test);
593         AST_TEST_UNREGISTER(escape_test);
594         AST_TEST_UNREGISTER(strings_match);
595         return 0;
596 }
597
598 static int load_module(void)
599 {
600         AST_TEST_REGISTER(str_test);
601         AST_TEST_REGISTER(begins_with_test);
602         AST_TEST_REGISTER(ends_with_test);
603         AST_TEST_REGISTER(strsep_test);
604         AST_TEST_REGISTER(escape_semicolons_test);
605         AST_TEST_REGISTER(escape_test);
606         AST_TEST_REGISTER(strings_match);
607         return AST_MODULE_LOAD_SUCCESS;
608 }
609
610 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dynamic string test module");