2 * Copyright (c) 2010 Zmanda, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
18 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
22 #include "testutils.h"
30 test_validate_regexp(void)
35 gboolean should_validate;
45 for (t = tests; t->regexp; t++) {
46 char *validated_err = validate_regexp(t->regexp);
47 if (!validated_err != !!t->should_validate) {
49 if (t->should_validate) {
50 g_fprintf(stderr, "should have validated regular expr %s: %s\n",
51 t->regexp, validated_err);
53 g_fprintf(stderr, "unexpectedly validated regular expr %s\n",
68 gboolean should_match, should_match_no_newline;
70 /* literal, unanchored matching */
71 { "a", "a", TRUE, TRUE },
72 { "a", "A", FALSE, FALSE },
73 { "a", "ab", TRUE, TRUE },
74 { "a", "ba", TRUE, TRUE },
75 { "a", "bab", TRUE, TRUE },
78 { ".", "", FALSE, FALSE },
79 { ".", "a", TRUE, TRUE },
80 { "..", "a", FALSE, FALSE },
81 { "..", "bc", TRUE, TRUE },
84 { "[abc]", "xbx", TRUE, TRUE },
85 { "[abc]", "xyz", FALSE, FALSE },
86 { "[^abc]", "cba", FALSE, FALSE },
87 { "[^abc]", "xyz", TRUE, TRUE },
88 { "[a-c]", "b", TRUE, TRUE },
89 { "[^a-c]", "-", TRUE, TRUE },
90 { "[1-9-]", "-", TRUE, TRUE },
91 { "[ab\\-cd]", "-", FALSE, FALSE }, /* NOTE! */
94 { "^xy", "xyz", TRUE, TRUE },
95 { "^xy", "wxyz", FALSE, FALSE },
96 { "yz$", "xyz", TRUE, TRUE },
97 { "yz$", "yza", FALSE, FALSE },
98 { "^123$", "123", TRUE, TRUE },
99 { "^123$", "0123", FALSE, FALSE },
100 { "^123$", "1234", FALSE, FALSE },
103 { "([a-c])([x-y])", "pqaxyr", TRUE, TRUE },
104 { "([a-c])([x-y])", "paqrxy", FALSE, FALSE },
105 { "([a-c])/\\1", "a/b", FALSE, FALSE },
106 { "([a-c])/\\1", "c/c", TRUE, TRUE },
109 { ">[0-9]*<", "><", TRUE, TRUE },
110 { ">[0-9]*<", ">3<", TRUE, TRUE },
111 { ">[0-9]*<", ">34<", TRUE, TRUE },
112 { ">[0-9]*<", ">345<", TRUE, TRUE },
113 { ">[0-9]*<", ">x<", FALSE, FALSE },
116 { ":(abc|ABC);", ":abc;", TRUE, TRUE },
117 { ":(abc|ABC);", ":ABC;", TRUE, TRUE },
118 { ":(abc|ABC);", ":abcBC;", FALSE, FALSE },
121 { ">[0-9]+<", "><", FALSE, FALSE },
122 { ">[0-9]+<", ">3<", TRUE, TRUE },
123 { ">[0-9]+<", ">34<", TRUE, TRUE },
124 { ">[0-9]+<", ">345<", TRUE, TRUE },
125 { ">[0-9]+<", ">x<", FALSE, FALSE },
128 { ">[0-9]{0,1}<", "><", TRUE, TRUE },
129 { ">[0-9]{0,1}<", ">9<", TRUE, TRUE },
130 { ">[0-9]{0,1}<", ">98<", FALSE, FALSE },
131 { ">[0-9]{2,3}<", "><", FALSE, FALSE },
132 { ">[0-9]{2,3}<", ">5<", FALSE, FALSE },
133 { ">[0-9]{2,3}<", ">55<", TRUE, TRUE },
134 { ">[0-9]{2,3}<", ">555<", TRUE, TRUE },
135 { ">[0-9]{2,3}<", ">5555<", FALSE, FALSE },
137 /* quoting metacharacters */
138 { "\\\\", "\\", TRUE, TRUE },
139 { "\\,", ",", TRUE, TRUE },
140 { "\\[", "[", TRUE, TRUE },
141 { "\\*", "*", TRUE, TRUE },
142 { "\\?", "?", TRUE, TRUE },
143 { "\\+", "+", TRUE, TRUE },
144 { "\\.", ".", TRUE, TRUE },
145 { "\\|", "|", TRUE, TRUE },
146 { "\\^", "^", TRUE, TRUE },
147 { "\\$", "$", TRUE, TRUE },
149 /* differences between match and match_no_newline */
150 { "x.y", "x\ny", FALSE, TRUE },
151 { "x[^yz]y", "x\ny", FALSE, TRUE },
152 { "^y", "x\ny", TRUE, FALSE },
153 { "x$", "x\ny", TRUE, FALSE },
155 { NULL, NULL, FALSE, FALSE },
158 for (t = tests; t->expr; t++) {
159 gboolean matched = match(t->expr, t->str);
160 if (!!matched != !!t->should_match) {
162 if (t->should_match) {
163 g_fprintf(stderr, "%s should have matched regular expr %s\n",
166 g_fprintf(stderr, "%s unexpectedly matched regular expr %s\n",
171 matched = match_no_newline(t->expr, t->str);
172 if (!!matched != !!t->should_match_no_newline) {
174 if (t->should_match) {
175 g_fprintf(stderr, "%s should have matched (no_newline) regular expr %s\n",
178 g_fprintf(stderr, "%s unexpectedly matched (no_newline) regular expr %s\n",
188 test_validate_glob(void)
193 gboolean should_validate;
198 { "x[!abc]y", TRUE },
202 { "**?", TRUE }, /* legal, but weird */
203 { "foo\\", FALSE }, /* un-escaped \ is illegal */
204 { "foo\\\\", TRUE }, /* but escaped is OK */
205 { "(){}+.^$|", TRUE }, /* funny characters OK */
206 { "/usr/bin/*", TRUE }, /* filename seps are OK */
210 for (t = tests; t->glob; t++) {
211 char *validated_err = validate_glob(t->glob);
212 if (!validated_err != !!t->should_validate) {
214 if (t->should_validate) {
215 g_fprintf(stderr, "should have validated glob %s: %s\n",
216 t->glob, validated_err);
218 g_fprintf(stderr, "unexpectedly validated glob %s\n",
228 test_glob_to_regex(void)
231 struct { char *glob, *regex; } tests[] = {
233 { "*.txt", "^[^/]*\\.txt$" },
234 { "?.txt", "^[^/]\\.txt$" },
235 { "?*.txt", "^[^/][^/]*\\.txt$" },
236 { "foo.[tT][xX][tT]", "^foo\\.[tT][xX][tT]$" },
237 { "foo.[tT][!yY][tT]", "^foo\\.[tT][^yY][tT]$" },
238 { "foo\\\\", "^foo\\\\$" },
239 { "(){}+.^$|", "^\\(\\)\\{\\}\\+\\.\\^\\$\\|$" },
240 { "/usr/bin/*", "^/usr/bin/[^/]*$" },
244 for (t = tests; t->glob; t++) {
245 char *regex = glob_to_regex(t->glob);
246 if (0 != strcmp(regex, t->regex)) {
248 g_fprintf(stderr, "glob_to_regex(\"%s\") returned \"%s\"; expected \"%s\"\n",
249 t->glob, regex, t->regex);
257 test_match_glob(void)
262 gboolean should_match;
264 /* literal, unanchored matching */
267 { "abc", "abc", TRUE },
268 { "abc", "abcd", FALSE },
269 { "abc", "dabc", FALSE },
270 { "abc", "/usr/bin/abc", FALSE },
272 { "*.txt", "foo.txt", TRUE },
273 { "*.txt", ".txt", TRUE },
274 { "*.txt", "txt", FALSE },
276 { "?.txt", "X.txt", TRUE },
277 { "?.txt", ".txt", FALSE },
278 { "?.txt", "XY.txt", FALSE },
280 { "?*.txt", ".txt", FALSE },
281 { "?*.txt", "a.txt", TRUE },
282 { "?*.txt", "aa.txt", TRUE },
283 { "?*.txt", "aaa.txt", TRUE },
285 { "foo.[tT][xX][tT]", "foo.txt", TRUE },
286 { "foo.[tT][xX][tT]", "foo.TXt", TRUE },
287 { "foo.[tT][xX][tT]", "foo.TXT", TRUE },
288 { "foo.[tT][xX][tT]", "foo.TaT", FALSE },
290 { "foo.[tT][!yY][tT]", "foo.TXt", TRUE },
291 { "foo.[tT][!yY][tT]", "foo.TXT", TRUE },
292 { "foo.[tT][!yY][tT]", "foo.TyT", FALSE },
294 { "foo\\\\", "foo", FALSE },
295 { "foo\\\\", "foo\\", TRUE },
296 { "foo\\\\", "foo\\\\", FALSE },
298 { "(){}+.^$|", "(){}+.^$|", TRUE },
300 { "/usr/bin/*", "/usr/bin/tar", TRUE },
301 { "/usr/bin/*", "/usr/bin/local/tar", FALSE },
302 { "/usr/bin/*", "/usr/sbin/tar", FALSE },
303 { "/usr/bin/*", "/opt/usr/bin/tar", FALSE },
305 { "/usr?bin", "/usr/bin", FALSE },
306 { "/usr*bin", "/usr/bin", FALSE },
308 { NULL, NULL, FALSE },
311 for (t = tests; t->expr; t++) {
312 gboolean matched = match_glob(t->expr, t->str);
313 if (!!matched != !!t->should_match) {
315 if (t->should_match) {
316 g_fprintf(stderr, "%s should have matched glob %s\n",
319 g_fprintf(stderr, "%s unexpectedly matched glob %s\n",
334 gboolean should_match;
336 /* literal, unanchored matching */
339 { "abc", "abc", TRUE },
340 { "abc", "abcd", FALSE },
341 { "abc", "dabc", FALSE },
342 { "abc", "/usr/bin/abc", TRUE },
344 { "*.txt", "foo.txt", TRUE },
345 { "*.txt", ".txt", TRUE },
346 { "*.txt", "txt", FALSE },
348 { "?.txt", "X.txt", TRUE },
349 { "?.txt", ".txt", FALSE },
350 { "?.txt", "XY.txt", FALSE },
352 { "?*.txt", ".txt", FALSE },
353 { "?*.txt", "a.txt", TRUE },
354 { "?*.txt", "aa.txt", TRUE },
355 { "?*.txt", "aaa.txt", TRUE },
357 { "foo.[tT][xX][tT]", "foo.txt", TRUE },
358 { "foo.[tT][xX][tT]", "foo.TXt", TRUE },
359 { "foo.[tT][xX][tT]", "foo.TXT", TRUE },
360 { "foo.[tT][xX][tT]", "foo.TaT", FALSE },
362 { "foo.[tT][!yY][tT]", "foo.TXt", TRUE },
363 { "foo.[tT][!yY][tT]", "foo.TXT", TRUE },
364 { "foo.[tT][!yY][tT]", "foo.TyT", FALSE },
366 { "foo\\\\", "foo", FALSE },
367 { "foo\\\\", "foo\\", TRUE },
368 { "foo\\\\", "foo\\\\", FALSE },
370 { "(){}+.^$|", "(){}+.^$|", TRUE },
372 { "/usr/bin/*", "/usr/bin/tar", TRUE },
373 { "/usr/bin/*", "/usr/bin/local/tar", TRUE }, /* different from match_glob */
374 { "/usr/bin/*", "/usr/sbin/tar", FALSE },
375 { "/usr/bin/*", "/opt/usr/bin/tar", FALSE },
377 { "/usr?bin", "/usr/bin", FALSE },
378 { "/usr*bin", "/usr/bin", TRUE }, /* different from match_glob */
380 /* examples from the amgtar manpage */
381 { "./temp-files", "./temp-files", TRUE },
382 { "./temp-files", "./temp-files/foo", TRUE },
383 { "./temp-files", "./temp-files/foo/bar", TRUE },
384 { "./temp-files", "./temp-files.bak", FALSE },
385 { "./temp-files", "./backup/temp-files", FALSE },
387 { "./temp-files/", "./temp-files", FALSE },
388 { "./temp-files/", "./temp-files/", TRUE },
389 { "./temp-files/", "./temp-files/foo", FALSE },
390 { "./temp-files/", "./temp-files/foo/bar", FALSE },
391 { "./temp-files/", "./temp-files.bak", FALSE },
393 { "/temp-files/", "./temp-files", FALSE },
394 { "/temp-files/", "./temp-files/", FALSE },
395 { "/temp-files/", "./temp-files/foo", FALSE },
396 { "/temp-files/", "./temp-files/foo/bar", FALSE },
397 { "/temp-files/", "./temp-files.bak", FALSE },
399 { "./temp-files/*", "./temp-files", FALSE },
400 { "./temp-files/*", "./temp-files/", TRUE },
401 { "./temp-files/*", "./temp-files/foo", TRUE },
402 { "./temp-files/*", "./temp-files/foo/bar", TRUE },
404 { "temp-files", "./my/temp-files", TRUE },
405 { "temp-files", "./my/temp-files/bar", TRUE },
406 { "temp-files", "./temp-files", TRUE },
407 { "temp-files", "./her-temp-files", FALSE },
408 { "temp-files", "./her/old-temp-files", FALSE },
409 { "temp-files", "./her/old-temp-files/bar", FALSE },
411 { "generated-*", "./my/generated-xyz", TRUE },
412 { "generated-*", "./my/generated-xyz/bar", TRUE },
413 { "generated-*", "./generated-xyz", TRUE },
414 { "generated-*", "./her-generated-xyz", FALSE },
415 { "generated-*", "./her/old-generated-xyz", FALSE },
416 { "generated-*", "./her/old-generated-xyz/bar", FALSE },
418 { "*.iso", "./my/amanda.iso", TRUE },
419 { "*.iso", "./amanda.iso", TRUE },
421 { "proxy/local/cache", "./usr/proxy/local/cache", TRUE },
422 { "proxy/local/cache", "./proxy/local/cache", TRUE },
423 { "proxy/local/cache", "./proxy/local/cache/7a", TRUE },
425 { NULL, NULL, FALSE },
428 for (t = tests; t->expr; t++) {
429 gboolean matched = match_tar(t->expr, t->str);
430 if (!!matched != !!t->should_match) {
432 if (t->should_match) {
433 g_fprintf(stderr, "%s should have matched tar %s\n",
436 g_fprintf(stderr, "%s unexpectedly matched tar %s\n",
446 test_make_exact_host_expression(void)
450 const char *test_strs[] = {
454 /* note that these will inter-match: */
476 for (i = 0; i < G_N_ELEMENTS(test_strs); i++) {
477 for (j = 0; j < G_N_ELEMENTS(test_strs); j++) {
478 char *expr = make_exact_host_expression(test_strs[i]);
479 gboolean matched = match_host(expr, test_strs[j]);
480 if (!!matched != !!(i == j)) {
483 g_fprintf(stderr, "expr %s for str %s unexpectedly matched %s\n",
484 expr, test_strs[i], test_strs[j]);
486 g_fprintf(stderr, "expr %s for str %s should have matched %s\n",
487 expr, test_strs[i], test_strs[j]);
497 test_match_host(void)
502 gboolean should_match;
504 /* from the amanda(8) manpage */
505 { "hosta", "hosta", TRUE },
506 { "hosta", "foo.hosta.org", TRUE },
507 { "hosta", "hoSTA.dOMAIna.ORG", TRUE },
508 { "hosta", "hostb", FALSE },
509 { "hOsta", "hosta", TRUE },
510 { "hOsta", "foo.hosta.org", TRUE },
511 { "hOsta", "hoSTA.dOMAIna.ORG", TRUE },
512 { "hOsta", "hostb", FALSE },
514 { "host", "host", TRUE },
515 { "host", "hosta", FALSE },
517 { "host?", "hosta", TRUE },
518 { "host?", "hostb", TRUE },
519 { "host?", "host", FALSE },
520 { "host?", "hostabc", FALSE },
522 { "ho*na", "hona", TRUE },
523 { "ho*na", "hoina", TRUE },
524 { "ho*na", "hoina.org", TRUE },
525 { "ho*na", "ns.hoina.org", TRUE },
526 { "ho*na", "ho.aina.org", FALSE },
528 { "ho**na", "hona", TRUE },
529 { "ho**na", "hoina", TRUE },
530 { "ho**na", "hoina.org", TRUE },
531 { "ho**na", "ns.hoina.org", TRUE },
532 { "ho**na", "ho.aina.org", TRUE },
534 { "^hosta", "hosta", TRUE },
535 { "^hosta", "hosta.org", TRUE },
536 { "^hosta", "hostabc", FALSE },
537 { "^hosta", "www.hosta", FALSE },
538 { "^hosta", "www.hosta.org", FALSE },
540 { "/opt", "opt", FALSE },
542 { ".hosta.", "hosta", TRUE },
543 { ".hosta.", "foo.hosta", TRUE },
544 { ".hosta.", "hosta.org", TRUE },
545 { ".hosta.", "foo.hosta.org", TRUE },
546 { "/hosta", "hosta", FALSE },
547 { "/hosta", "foo.hosta", FALSE },
548 { "/hosta", "hosta.org", FALSE },
549 { "/hosta", "foo.hosta.org", FALSE },
551 { ".opt.", "opt", TRUE },
552 { ".opt.", "www.opt", TRUE },
553 { ".opt.", "www.opt.com", TRUE },
554 { ".opt.", "opt.com", TRUE },
557 { "^hosta$", "hosta", TRUE },
558 { "^hosta$", "foo.hosta", FALSE },
559 { "^hosta$", "hosta.org", FALSE },
560 { "^hosta$", "foo.hosta.org", FALSE },
562 { "^lu.vis.ta$", "lu.vis.ta", TRUE },
563 { "^lu.vis.ta$", "lu-vis.ta", FALSE },
564 { "^lu.vis.ta$", "luvista", FALSE },
565 { "^lu.vis.ta$", "foo.lu.vis.ta", FALSE },
566 { "^lu.vis.ta$", "lu.vis.ta.org", FALSE },
567 { "^lu.vis.ta$", "foo.lu.vis.ta.org", FALSE },
569 { "mo[st]a", "mota", TRUE },
570 { "mo[st]a", "mosa", TRUE },
571 { "mo[st]a", "mosta", FALSE },
572 { "mo[!st]a", "mota", FALSE },
573 { "mo[!st]a", "moma", TRUE },
574 { "mo[!st]a", "momma", FALSE },
576 { "host[acd]", "hosta", TRUE },
577 { "host[acd]", "hostb", FALSE },
578 { "host[acd]", "hostc", TRUE },
579 { "host[!acd]", "hosta", FALSE },
580 { "host[!acd]", "hostb", TRUE },
581 { "host[!acd]", "hostc", FALSE },
583 { "toast", "www.toast.com", TRUE },
584 { ".toast", "www.toast.com", TRUE },
585 { "toast.", "www.toast.com", TRUE },
586 { ".toast.", "www.toast.com", TRUE },
588 { NULL, NULL, FALSE },
591 for (t = tests; t->expr; t++) {
592 gboolean matched = match_host(t->expr, t->str);
593 if (!!matched != !!t->should_match) {
595 if (t->should_match) {
596 g_fprintf(stderr, "%s should have matched host expr %s\n",
599 g_fprintf(stderr, "%s unexpectedly matched host expr %s\n",
609 test_make_exact_disk_expression(void)
613 const char *test_strs[] = {
625 /* these intermatch due to some special-casing */
628 "\\\\windows\\share",
632 for (i = 0; i < G_N_ELEMENTS(test_strs); i++) {
633 for (j = 0; j < G_N_ELEMENTS(test_strs); j++) {
634 char *expr = make_exact_disk_expression(test_strs[i]);
635 gboolean matched = match_disk(expr, test_strs[j]);
636 if (!!matched != !!(i == j)) {
639 g_fprintf(stderr, "expr %s for str %s unexpectedly matched %s\n",
640 expr, test_strs[i], test_strs[j]);
642 g_fprintf(stderr, "expr %s for str %s should have matched %s\n",
643 expr, test_strs[i], test_strs[j]);
653 test_match_disk(void)
658 gboolean should_match;
660 /* from the amanda(8) manpage */
661 { "sda*", "/dev/sda1", TRUE },
662 { "sda*", "/dev/sda2", TRUE },
663 { "sda*", "/dev/sdb2", FALSE },
665 { "opt", "opt", TRUE },
666 { "opt", "/opt", TRUE },
667 { "opt", "/opt/foo", TRUE },
668 { "opt", "opt/foo", TRUE },
670 { "/opt", "opt", TRUE },
671 { "/opt", "opt/", TRUE },
672 { "/opt", "/opt", TRUE },
673 { "/opt", "/opt/", TRUE },
674 { "/opt", "/local/opt/", TRUE },
675 { "/opt", "/opt/local/", TRUE },
677 { "opt/", "opt", TRUE },
678 { "opt/", "opt/", TRUE },
679 { "opt/", "/opt", TRUE },
680 { "opt/", "/opt/", TRUE },
681 { "opt/", "/local/opt/", TRUE },
682 { "opt/", "/opt/local/", TRUE },
685 { "/", "/opt/local/", FALSE },
687 { "/usr$", "/", FALSE },
688 { "/usr$", "/usr", TRUE },
689 { "/usr$", "/usr/local", FALSE },
691 { "share", "\\\\windows1\\share", TRUE },
692 { "share", "\\\\windows2\\share", TRUE },
693 { "share", "//windows1/share", TRUE },
694 { "share", "//windows2/share", TRUE },
696 { "share*", "\\\\windows\\share1", TRUE },
697 { "share*", "\\\\windows\\share2", TRUE },
698 { "share*", "//windows/share3", TRUE },
699 { "share*", "//windows/share4", TRUE },
701 { "//windows/share", "//windows/share", TRUE },
702 { "//windows/share", "\\\\windows\\share", TRUE },
703 { "\\\\windows\\share", "//windows/share", FALSE },
704 { "\\\\windows\\share", "\\\\windows\\share", FALSE },
705 { "\\\\\\\\windows\\\\share", "//windows/share", FALSE },
706 { "\\\\\\\\windows\\\\share", "\\\\windows\\share", TRUE },
708 /* other expressions */
709 { "^local", "/local", TRUE },
710 { "^local", "/local/vore", TRUE },
711 { "^local", "/usr/local", FALSE },
713 { "local/bin", "/local/bin", TRUE },
714 { "local/bin", "/opt/local/bin", TRUE },
715 { "local/bin", "/local/bin/git", TRUE },
717 { "//windows/share", "//windows/share/files", TRUE },
718 { "//windows/share", "\\\\windows\\share\\files", TRUE },
719 { "\\\\windows\\share", "//windows/share/files", FALSE },
720 { "\\\\windows\\share", "\\\\windows\\share\\files", FALSE },
722 /* longer expressions */
723 { "local/var", "/local/var", TRUE },
724 { "local/var", "/opt/local/var", TRUE },
725 { "local/var", "/local/var/lib", TRUE },
726 { "local/var", "/local/usr/var", FALSE },
728 /* trailing slashes */
729 { "/usr/bin", "/usr/bin", TRUE },
730 { "/usr/bin", "/usr/bin/", TRUE },
731 { "/usr/bin/", "/usr/bin", TRUE },
732 { "/usr/bin/", "/usr/bin/", TRUE },
733 { "/usr/bin", "/usr/bin//", TRUE },
734 { "/usr/bin//", "/usr/bin", FALSE },
735 { "/usr/bin//", "/usr/bin//", TRUE },
737 /* quoting '/' is weird: it doesn't work on the leading slash. Note that
738 * the documentation does not specify how to quote metacharacters in a host
739 * or disk expression. */
740 { "/usr\\/bin", "/usr/bin", TRUE },
741 { "^/usr\\/bin$", "/usr/bin", TRUE },
742 { "\\/usr\\/bin", "/usr/bin", FALSE },
743 { "^\\/usr\\/bin$", "/usr/bin", FALSE },
745 { NULL, NULL, FALSE },
748 for (t = tests; t->expr; t++) {
749 gboolean matched = match_disk(t->expr, t->str);
750 if (!!matched != !!t->should_match) {
752 if (t->should_match) {
753 g_fprintf(stderr, "%s should have matched disk expr %s\n",
756 g_fprintf(stderr, "%s unexpectedly matched disk expr %s\n",
766 test_match_datestamp(void)
771 gboolean should_match;
773 /* from the amanda(8) manpage */
774 { "20001212-14", "20001212", TRUE },
775 { "20001212-14", "20001212010203", TRUE },
776 { "20001212-14", "20001213", TRUE },
777 { "20001212-14", "20001213010203", TRUE },
778 { "20001212-14", "20001214", TRUE },
779 { "20001212-14", "20001215", FALSE },
781 { "20001212-4", "20001212", TRUE },
782 { "20001212-4", "20001212010203", TRUE },
783 { "20001212-4", "20001213", TRUE },
784 { "20001212-4", "20001213010203", TRUE },
785 { "20001212-4", "20001214", TRUE },
786 { "20001212-4", "20001215", FALSE },
788 { "20001212-214", "20001212", TRUE },
789 { "20001212-214", "20001212010203", TRUE },
790 { "20001212-214", "20001213", TRUE },
791 { "20001212-214", "20001213010203", TRUE },
792 { "20001212-214", "20001214", TRUE },
793 { "20001212-214", "20001215", FALSE },
795 { "20001212-24", "20001211", FALSE },
796 { "20001212-24", "20001214010203", TRUE },
797 { "20001212-24", "20001221010203", TRUE },
798 { "20001212-24", "20001224", TRUE },
799 { "20001212-24", "20001225", FALSE },
801 { "2000121", "20001209", FALSE },
802 { "2000121", "20001210", TRUE },
803 { "2000121", "20001210012345", TRUE },
804 { "2000121", "20001219", TRUE },
805 { "2000121", "20001219012345", TRUE },
806 { "2000121", "20001220", FALSE },
808 { "2", "19991231", FALSE },
809 { "2", "20000101", TRUE },
810 { "2", "20100419", TRUE },
812 { "^2", "19991231", FALSE },
813 { "^2", "20000101", TRUE },
814 { "^2", "20100419", TRUE },
816 { "2000-2010", "19991231235959", FALSE },
817 { "2000-2010", "20001010", TRUE },
818 { "2000-2010", "20101231", TRUE },
819 { "2000-2010", "20111010", FALSE },
821 { "200010$", "200010", TRUE }, /* but it's not a real datestamp */
822 { "200010$", "20001001", FALSE },
823 { "200010$", "20001001061500", FALSE },
825 { "20000615$", "20000615", TRUE },
826 { "20000615$", "20000615000000", FALSE },
827 { "20000615$", "20000615010306", FALSE },
829 { NULL, NULL, FALSE },
832 for (t = tests; t->expr; t++) {
833 gboolean matched = match_datestamp(t->expr, t->str);
834 if (!!matched != !!t->should_match) {
836 if (t->should_match) {
837 g_fprintf(stderr, "%s should have matched datestamp expr %s\n",
840 g_fprintf(stderr, "%s unexpectedly matched datestamp expr %s\n",
850 test_match_level(void)
855 gboolean should_match;
857 /* exact matches, optionally ignoring "^" */
858 { "3$", "2", FALSE },
860 { "3$", "4", FALSE },
861 { "3$", "32", FALSE },
863 { "^3$", "2", FALSE },
864 { "^3$", "3", TRUE },
865 { "^3$", "4", FALSE },
866 { "^3$", "32", FALSE },
875 { "2-5", "1", FALSE },
876 { "2-5", "13", FALSE },
877 { "2-5", "23", FALSE },
878 { "2-5", "2", TRUE },
879 { "2-5", "4", TRUE },
880 { "2-5", "5", TRUE },
881 { "2-5", "53", FALSE },
882 { "2-5", "63", FALSE },
883 { "2-5", "6", FALSE },
885 { "9-15", "8", FALSE },
886 { "9-15", "19", FALSE },
887 { "9-15", "91", FALSE },
888 { "9-15", "9", TRUE },
889 { "9-15", "14", TRUE },
890 { "9-15", "15", TRUE },
891 { "9-15", "152", FALSE },
892 { "9-15", "16", FALSE },
894 { "19-21", "18", FALSE },
895 { "19-21", "19", TRUE },
896 { "19-21", "21", TRUE },
897 { "19-21", "22", FALSE },
899 /* single range is the same as an exact match */
900 { "99-99", "98", FALSE },
901 { "99-99", "99", TRUE },
902 { "99-99", "100", FALSE },
904 /* reversed range never matches */
905 { "21-19", "18", FALSE },
906 { "21-19", "19", FALSE },
907 { "21-19", "21", FALSE },
908 { "21-19", "22", FALSE },
910 { NULL, NULL, FALSE },
913 for (t = tests; t->expr; t++) {
914 gboolean matched = match_level(t->expr, t->str);
915 if (!!matched != !!t->should_match) {
917 if (t->should_match) {
918 g_fprintf(stderr, "%s should have matched level expr %s\n",
921 g_fprintf(stderr, "%s unexpectedly matched level expr %s\n",
936 main(int argc, char **argv)
938 static TestUtilsTest tests[] = {
939 TU_TEST(test_validate_regexp, 90),
940 TU_TEST(test_match, 90),
941 TU_TEST(test_validate_glob, 90),
942 TU_TEST(test_glob_to_regex, 90),
943 TU_TEST(test_match_glob, 90),
944 TU_TEST(test_match_tar, 90),
945 TU_TEST(test_make_exact_host_expression, 90),
946 TU_TEST(test_match_host, 90),
947 TU_TEST(test_make_exact_disk_expression, 90),
948 TU_TEST(test_match_disk, 90),
949 TU_TEST(test_match_datestamp, 90),
950 TU_TEST(test_match_level, 90),
954 return testutils_run_tests(argc, argv, tests);