2 * Copyright (c) 2010-2012 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", FALSE },
710 { "^/local", "/local", TRUE },
711 { "^local", "/local/vore", FALSE },
712 { "^/local", "/local/vore", TRUE },
713 { "^local", "/usr/local", FALSE },
715 { "local/bin", "/local/bin", TRUE },
716 { "local/bin", "/opt/local/bin", TRUE },
717 { "local/bin", "/local/bin/git", TRUE },
719 { "//windows/share", "//windows/share/files", TRUE },
720 { "//windows/share", "\\\\windows\\share\\files", TRUE },
721 { "\\\\windows\\share", "//windows/share/files", FALSE },
722 { "\\\\windows\\share", "\\\\windows\\share\\files", FALSE },
724 /* longer expressions */
725 { "local/var", "/local/var", TRUE },
726 { "local/var", "/opt/local/var", TRUE },
727 { "local/var", "/local/var/lib", TRUE },
728 { "local/var", "/local/usr/var", FALSE },
730 /* trailing slashes */
731 { "/usr/bin", "/usr/bin", TRUE },
732 { "/usr/bin", "/usr/bin/", TRUE },
733 { "/usr/bin/", "/usr/bin", TRUE },
734 { "/usr/bin/", "/usr/bin/", TRUE },
735 { "/usr/bin", "/usr/bin//", TRUE },
736 { "/usr/bin//", "/usr/bin", FALSE },
737 { "/usr/bin//", "/usr/bin//", TRUE },
739 /* quoting '/' is weird: it doesn't work on the leading slash. Note that
740 * the documentation does not specify how to quote metacharacters in a host
741 * or disk expression. */
742 { "/usr\\/bin", "/usr/bin", TRUE },
743 { "^/usr\\/bin$", "/usr/bin", TRUE },
744 { "\\/usr\\/bin", "/usr/bin", FALSE },
745 { "^\\/usr\\/bin$", "/usr/bin", TRUE },
746 { "/usr\\/bin\\/", "/usr/bin/", TRUE },
747 { "^/usr\\/bin\\/$", "/usr/bin/", TRUE },
748 { "\\/usr\\/bin\\/", "/usr/bin/", FALSE },
749 { "^\\/usr\\/bin\\/$", "/usr/bin/", TRUE },
751 { "oracle", "oracle", TRUE },
752 { "oracle", "/oracle", TRUE },
753 { "oracle", "oracle/", TRUE },
754 { "oracle", "/oracle/", TRUE },
755 { "/oracle", "oracle", TRUE },
756 { "/oracle", "/oracle", TRUE },
757 { "/oracle", "oracle/", TRUE },
758 { "/oracle", "/oracle/", TRUE },
759 { "^oracle", "oracle", TRUE },
760 { "^oracle", "/oracle", FALSE },
761 { "^oracle", "oracle/", TRUE },
762 { "^oracle", "/oracle/", FALSE },
763 { "^/oracle", "oracle", FALSE },
764 { "^/oracle", "/oracle", TRUE },
765 { "^/oracle", "oracle/", FALSE },
766 { "^/oracle", "/oracle/", TRUE },
768 { "oracle", "oracle", TRUE },
769 { "oracle", "/oracle", TRUE },
770 { "oracle", "oracle/", TRUE },
771 { "oracle", "/oracle/", TRUE },
772 { "oracle$", "oracle", TRUE },
773 { "oracle$", "/oracle", TRUE },
774 { "oracle$", "oracle/", FALSE },
775 { "oracle$", "/oracle/", FALSE },
776 { "oracle/$", "oracle", FALSE },
777 { "oracle/$", "/oracle", FALSE },
778 { "oracle/$", "oracle/", TRUE },
779 { "oracle/$", "/oracle/", TRUE },
781 { NULL, NULL, FALSE },
784 for (t = tests; t->expr; t++) {
785 gboolean matched = match_disk(t->expr, t->str);
786 if (!!matched != !!t->should_match) {
788 if (t->should_match) {
789 g_fprintf(stderr, "%s should have matched disk expr %s\n",
792 g_fprintf(stderr, "%s unexpectedly matched disk expr %s\n",
802 test_match_datestamp(void)
807 gboolean should_match;
809 /* from the amanda(8) manpage */
810 { "20001212-14", "20001212", TRUE },
811 { "20001212-14", "20001212010203", TRUE },
812 { "20001212-14", "20001213", TRUE },
813 { "20001212-14", "20001213010203", TRUE },
814 { "20001212-14", "20001214", TRUE },
815 { "20001212-14", "20001215", FALSE },
817 { "20001212-4", "20001212", TRUE },
818 { "20001212-4", "20001212010203", TRUE },
819 { "20001212-4", "20001213", TRUE },
820 { "20001212-4", "20001213010203", TRUE },
821 { "20001212-4", "20001214", TRUE },
822 { "20001212-4", "20001215", FALSE },
824 { "20001212-214", "20001212", TRUE },
825 { "20001212-214", "20001212010203", TRUE },
826 { "20001212-214", "20001213", TRUE },
827 { "20001212-214", "20001213010203", TRUE },
828 { "20001212-214", "20001214", TRUE },
829 { "20001212-214", "20001215", FALSE },
831 { "20001212-24", "20001211", FALSE },
832 { "20001212-24", "20001214010203", TRUE },
833 { "20001212-24", "20001221010203", TRUE },
834 { "20001212-24", "20001224", TRUE },
835 { "20001212-24", "20001225", FALSE },
837 { "2000121", "20001209", FALSE },
838 { "2000121", "20001210", TRUE },
839 { "2000121", "20001210012345", TRUE },
840 { "2000121", "20001219", TRUE },
841 { "2000121", "20001219012345", TRUE },
842 { "2000121", "20001220", FALSE },
844 { "2", "19991231", FALSE },
845 { "2", "20000101", TRUE },
846 { "2", "20100419", TRUE },
848 { "^2", "19991231", FALSE },
849 { "^2", "20000101", TRUE },
850 { "^2", "20100419", TRUE },
852 { "2000-2010", "19991231235959", FALSE },
853 { "2000-2010", "20001010", TRUE },
854 { "2000-2010", "20101231", TRUE },
855 { "2000-2010", "20111010", FALSE },
857 { "200010$", "200010", TRUE }, /* but it's not a real datestamp */
858 { "200010$", "20001001", FALSE },
859 { "200010$", "20001001061500", FALSE },
861 { "20000615$", "20000615", TRUE },
862 { "20000615$", "20000615000000", FALSE },
863 { "20000615$", "20000615010306", FALSE },
865 { NULL, NULL, FALSE },
868 for (t = tests; t->expr; t++) {
869 gboolean matched = match_datestamp(t->expr, t->str);
870 if (!!matched != !!t->should_match) {
872 if (t->should_match) {
873 g_fprintf(stderr, "%s should have matched datestamp expr %s\n",
876 g_fprintf(stderr, "%s unexpectedly matched datestamp expr %s\n",
886 test_match_level(void)
891 gboolean should_match;
893 /* exact matches, optionally ignoring "^" */
894 { "3$", "2", FALSE },
896 { "3$", "4", FALSE },
897 { "3$", "32", FALSE },
899 { "^3$", "2", FALSE },
900 { "^3$", "3", TRUE },
901 { "^3$", "4", FALSE },
902 { "^3$", "32", FALSE },
911 { "2-5", "1", FALSE },
912 { "2-5", "13", FALSE },
913 { "2-5", "23", FALSE },
914 { "2-5", "2", TRUE },
915 { "2-5", "4", TRUE },
916 { "2-5", "5", TRUE },
917 { "2-5", "53", FALSE },
918 { "2-5", "63", FALSE },
919 { "2-5", "6", FALSE },
921 { "9-15", "8", FALSE },
922 { "9-15", "19", FALSE },
923 { "9-15", "91", FALSE },
924 { "9-15", "9", TRUE },
925 { "9-15", "14", TRUE },
926 { "9-15", "15", TRUE },
927 { "9-15", "152", FALSE },
928 { "9-15", "16", FALSE },
930 { "19-21", "18", FALSE },
931 { "19-21", "19", TRUE },
932 { "19-21", "21", TRUE },
933 { "19-21", "22", FALSE },
935 /* single range is the same as an exact match */
936 { "99-99", "98", FALSE },
937 { "99-99", "99", TRUE },
938 { "99-99", "100", FALSE },
940 /* reversed range never matches */
941 { "21-19", "18", FALSE },
942 { "21-19", "19", FALSE },
943 { "21-19", "21", FALSE },
944 { "21-19", "22", FALSE },
946 { NULL, NULL, FALSE },
949 for (t = tests; t->expr; t++) {
950 gboolean matched = match_level(t->expr, t->str);
951 if (!!matched != !!t->should_match) {
953 if (t->should_match) {
954 g_fprintf(stderr, "%s should have matched level expr %s\n",
957 g_fprintf(stderr, "%s unexpectedly matched level expr %s\n",
972 main(int argc, char **argv)
974 static TestUtilsTest tests[] = {
975 TU_TEST(test_validate_regexp, 90),
976 TU_TEST(test_match, 90),
977 TU_TEST(test_validate_glob, 90),
978 TU_TEST(test_glob_to_regex, 90),
979 TU_TEST(test_match_glob, 90),
980 TU_TEST(test_match_tar, 90),
981 TU_TEST(test_make_exact_host_expression, 90),
982 TU_TEST(test_match_host, 90),
983 TU_TEST(test_make_exact_disk_expression, 90),
984 TU_TEST(test_match_disk, 90),
985 TU_TEST(test_match_datestamp, 90),
986 TU_TEST(test_match_level, 90),
990 return testutils_run_tests(argc, argv, tests);