From 76d7e694cd6efc873983790ff009618447a11faf Mon Sep 17 00:00:00 2001 From: claudio Date: Tue, 20 Feb 2024 09:40:58 +0000 Subject: [PATCH] Add a unit test for rsync special rmatch() function. One pattern is currently disabled since it results in an infinite loop. Fix for that is on the way. --- regress/usr.bin/rsync-unit/Makefile | 15 ++ regress/usr.bin/rsync-unit/rmatch_test.c | 254 +++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 regress/usr.bin/rsync-unit/Makefile create mode 100644 regress/usr.bin/rsync-unit/rmatch_test.c diff --git a/regress/usr.bin/rsync-unit/Makefile b/regress/usr.bin/rsync-unit/Makefile new file mode 100644 index 00000000000..653615db888 --- /dev/null +++ b/regress/usr.bin/rsync-unit/Makefile @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile,v 1.1 2024/02/20 09:40:58 claudio Exp $ + +.PATH: ${.CURDIR}/../../../usr.bin/rsync + +PROGS += rmatch_test + +.for p in ${PROGS} +REGRESS_TARGETS += run-regress-$p +.endfor + +CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../../../usr.bin/rsync + +SRCS_rmatch_test = rmatch_test.c rmatch.c + +.include diff --git a/regress/usr.bin/rsync-unit/rmatch_test.c b/regress/usr.bin/rsync-unit/rmatch_test.c new file mode 100644 index 00000000000..e77a917f776 --- /dev/null +++ b/regress/usr.bin/rsync-unit/rmatch_test.c @@ -0,0 +1,254 @@ +/* $OpenBSD: rmatch_test.c,v 1.1 2024/02/20 09:40:58 claudio Exp $ */ + +/* + * Copyright (c) 2021 Claudio Jeker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include +#include + +int rmatch(const char *, const char *, int); + +struct tv { + const char *pattern; + const char *string; + int result; + const char *reason; +} tvs[] = { + { "*abc", "aaaabc", 0 }, + { "abc", "abc", 0 }, + { "*aaa", "bbbcaa", 1 }, + { "aaa", "aabb", 1 }, + { "[a]??", "aaa", 0 }, + { "*[a]??", "abcabc", 0 }, + { "[b]??", "abcabc", 1 }, + { "*[b]??*", "abcabc", 0 }, + { "[a-z]", "a", 0 }, + { "*[a-z]", "1234a", 0 }, + { "[a-z]", "A", 1 }, + { "*[a-z]", "1234A", 1 }, + { "[[:lower:]]", "a", 0 }, + { "*[[:lower:]]", "1234a", 0 }, + { "[[:lower:]]", "A", 1 }, + { "*[[:lower:]]", "1234A", 1 }, + { "?", "a", 0 }, + { "*?", "1234a", 0 }, + { "\\a", "a", 0 }, + { "*\\a", "1234a", 0 }, + { "/", "/", 0 }, + { "*/", "1234/", 0 }, + { "?", "/", 1 }, + { "*?", "1234/", 1 }, + { "\\/", "/", 0 }, + { "*\\/", "1234/", 0 }, + { "*abc/", "abc/", 0 }, + { "*abc/", "ababc/", 0 }, + { "*abc/*", "abc/xyz", 0 }, + { "*abc/", "xyz/abc", 1 }, + { "*abc/", "ab/", 1 }, + { "*abc/", "abc", 1 }, + { "*abc/", "abc.", 1 }, + { "*abc/", "abcab/", 1 }, + { "*abc/", "abcd/abc", 1 }, + { "**??""?/", "a/aa/aaa/", 0 }, + { "**??""?/", "a/aa/aa/", 1 }, + { "**??""?/", "a/aa/aaaxxxx/", 0 }, + { "**abc/", "a/aa/xxabc/", 0 }, + + /* rysnc wildtest.txt */ + + { "foo", "foo", 0 }, + { "bar", "foo", 1 }, + { "", "", 0 }, + { "???", "foo", 0 }, + { "??", "foo", 1 }, + { "*", "foo", 0 }, + { "f*", "foo", 0 }, + { "*f", "foo", 1 }, + { "*foo*", "foo", 0 }, + { "*ob*a*r*", "foobar", 0 }, + { "*ab", "aaaaaaabababab", 0 }, + { "foo\\*", "foo*", 0 }, + { "foo\\*bar", "foobar", 1 }, + { "f\\\\oo", "f\\oo", 0 }, + { "*[al]?", "ball", 0 }, + { "[ten]", "ten", 1 }, + { "**[!te]", "ten", 0 }, + { "**[!ten]", "ten", 1 }, + { "t[a-g]n", "ten", 0 }, + { "t[!a-g]n", "ten", 1 }, + { "t[!a-g]n", "ton", 0 }, + { "t[^a-g]n", "ton", 0 }, + { "a[]]b", "a]b", 0 }, + { "a[]-]b", "a-b", 0 }, + { "a[]-]b", "a]b", 0 }, + { "a[]-]b", "aab", 1 }, + { "a[]a-]b", "aab", 0 }, + { "]", "]", 0 }, + { "foo*bar", "foo/baz/bar", 1 }, + { "foo**bar", "foo/baz/bar", 0 }, + { "foo?bar", "foo/bar", 1 }, + { "foo[/]bar", "foo/bar", 1 }, + { "f[^eiu][^eiu][^eiu][^eiu][^eiu]r", "foo/bar", 1 }, + { "f[^eiu][^eiu][^eiu][^eiu][^eiu]r", "foo-bar", 0 }, + { "**/foo", "foo", 1 }, + { "**/foo", "/foo", 0 }, + { "**/foo", "bar/baz/foo", 0 }, + { "*/foo", "bar/baz/foo", 1 }, + { "**/bar*", "foo/bar/baz", 1 }, + { "**/bar/*", "deep/foo/bar/baz", 0 }, + { "**/bar/*", "deep/foo/bar/baz/", 1 }, + { "**/bar/**", "deep/foo/bar/baz/", 0 }, + { "**/bar/*", "deep/foo/bar", 1 }, + { "**/bar/**", "deep/foo/bar/", 0 }, + { "**/bar**", "foo/bar/baz", 0 }, + { "*/bar/**", "foo/bar/baz/x", 0 }, + { "*/bar/**", "deep/foo/bar/baz/x", 1 }, + { "**/bar/*/*", "deep/foo/bar/baz/x", 0 }, + { "a[c-c]st", "acrt", 1 }, + { "a[c-c]rt", "acrt", 0 }, + { "[!]-]", "]", 1 }, + { "[!]-]", "a", 0 }, + { "\\", "", 1 }, + { "\\", "\\", 1, "backslash at end is taken literally" }, + { "*/\\", "/\\", 1, "backslash at end is taken literally" }, + { "*/\\\\", "/\\", 0 }, + { "foo", "foo", 0 }, + { "@foo", "@foo", 0 }, + { "@foo", "foo", 1 }, + { "\\[ab]", "[ab]", 0 }, + { "[[]ab]", "[ab]", 0 }, + { "[[:]ab]", "[ab]", 0 }, + { "[[::]ab]", "[ab]", 1, "bad char class taken literally" }, + { "[[:digit]ab]", "[ab]", 0 }, + { "[\\[:]ab]", "[ab]", 0 }, + { "\\??\\?b", "?a?b", 0 }, + { "\\a\\b\\c", "abc", 0 }, + { "", "foo", 1 }, + { "**/t[o]", "foo/bar/baz/to", 0 }, + { "[[:alpha:]][[:digit:]][[:upper:]]", "a1B", 0 }, + { "[[:digit:][:upper:][:space:]]", "a", 1 }, + { "[[:digit:][:upper:][:space:]]", "A", 0 }, + { "[[:digit:][:upper:][:space:]]", "1", 0 }, + { "[[:digit:][:upper:][:spaci:]]", "1", 1 }, + { "[[:digit:][:upper:][:space:]]", " ", 0 }, + { "[[:digit:][:upper:][:space:]]", ".", 1 }, + { "[[:digit:][:punct:][:space:]]", ".", 0 }, + { "[[:xdigit:]]", "5", 0 }, + { "[[:xdigit:]]", "f", 0 }, + { "[[:xdigit:]]", "D", 0 }, + { "[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]", "_", 0 }, + { "[^[:alnum:][:alpha:][:blank:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]", "", 0 }, + { "[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]", ".", 0 }, + { "[a-c[:digit:]x-z]", "5", 0 }, + { "[a-c[:digit:]x-z]", "b", 0 }, + { "[a-c[:digit:]x-z]", "y", 0 }, + { "[a-c[:digit:]x-z]", "q", 1 }, + { "[\\\\-^]", "]", 0 }, + { "[\\\\-^]", "[", 1 }, + { "[\\-_]", "-", 0 }, + { "[\\]]", "]", 0 }, + { "[\\]]", "\\]", 1 }, + { "[\\]]", "\\", 1 }, + { "a[]b", "ab", 1 }, + { "a[]b", "a[]b", 1, "empty [] is taken literally" }, + { "ab[", "ab[", 1, "single [ char taken literally" }, + { "[!", "ab", 1 }, + { "[-", "ab", 1 }, + { "[-]", "-", 0 }, + { "[a-", "-", 1 }, + { "[!a-", "-", 1 }, + { "[--A]", "-", 0 }, + { "[--A]", "5", 0 }, + { "[ --]", " ", 0 }, + { "[ --]", "$", 0 }, + { "[ --]", "-", 0 }, + { "[ --]", "0", 1 }, + { "[---]", "-", 0 }, + { "[------]", "-", 0 }, + { "[a-e-n]", "j", 1 }, + { "[a-e-n]", "-", 0 }, + { "[!------]", "a", 0 }, + { "[]-a]", "[", 1 }, + { "[]-a]", "^", 0 }, + { "[!]-a]", "^", 1 }, + { "[!]-a]", "[", 0 }, + { "[a^bc]", "^", 0 }, + { "[a-]b]", "-b]", 0 }, + { "[\\]", "\\", 1 }, + { "[\\\\]", "\\", 0 }, + { "[!\\\\]", "\\", 1 }, + { "[A-\\\\]", "G", 0 }, + { "b*a", "aaabbb", 1 }, + { "*ba*", "aabcaa", 1 }, + { "[,]", ",", 0 }, + { "[\\\\,]", ",", 0 }, + { "[\\\\,]", "\\", 0 }, + { "[,-.]", "-", 0 }, + { "[,-.]", "+", 1 }, + { "[,-.]", "-.]", 1 }, + { "[\\1-\\3]", "2", 0 }, + { "[\\1-\\3]", "3", 0 }, + { "[\\1-\\3]", "4", 1 }, + { "[[-\\]]", "\\", 0 }, + { "[[-\\]]", "[", 0 }, + { "[[-\\]]", "]", 0 }, + { "[[-\\]]", "-", 1 }, + { "-*-*-*-*-*-*-12-*-*-*-m-*-*-*", "-adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1", 0 }, + { "-*-*-*-*-*-*-12-*-*-*-m-*-*-*", "-adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1", 1 }, + { "-*-*-*-*-*-*-12-*-*-*-m-*-*-*", "-adobe-courier-bold-o-normal--12-120-75-75-/-70-iso8859-1", 1 }, + { "/*/*/*/*/*/*/12/*/*/*/m/*/*/*", "/adobe/courier/bold/o/normal//12/120/75/75/m/70/iso8859/1", 0 }, + { "/*/*/*/*/*/*/12/*/*/*/m/*/*/*", "/adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1", 1 }, + { "**/*a*b*g*n*t", "abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt", 0 }, + { "**/*a*b*g*n*t", "abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz", 1 }, + +#ifdef NOTYET + /* infinte loop test from Kyle Evans */ + { "dir/*.o", "dir1/a.o", 1 }, +#endif + + { NULL }, +}; + +int +main (int argc, char **argv) +{ + const char *p, *s; + size_t i; + int rv = 0; + + for (i = 0; tvs[i].pattern != NULL; i++) { + p = tvs[i].pattern; + s = tvs[i].string; + if (rmatch(p, s, 0) == tvs[i].result) { + printf("string %s pattern %s does %s\n", + tvs[i].string, tvs[i].pattern, + tvs[i].result ? "not match" : "match"); + } else if (tvs[i].reason) { + printf("string %s pattern %s SHOULD %s but %s\n", + tvs[i].string, tvs[i].pattern, + tvs[i].result ? "not match" : "match", + tvs[i].reason); + } else { + printf("FAILED: string %s pattern %s failed to %s\n", + tvs[i].string, tvs[i].pattern, + tvs[i].result ? "not match" : "match"); + rv = 1; + } + } + + return rv; +} -- 2.20.1