diff options
Diffstat (limited to 'tests')
157 files changed, 1313 insertions, 555 deletions
diff --git a/tests/alloc.c b/tests/alloc.c index 6c0defd..f91b428 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -1,41 +1,40 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" + #include "alloc.h" #include "diag.h" + #include <errno.h> #include <stdlib.h> #include <stdint.h> -bool check_alloc(void) { - bool ret = true; - +void check_alloc(void) { // Check sizeof_flex() struct flexible { alignas(64) int foo[8]; int bar[]; }; - ret &= bfs_check(sizeof_flex(struct flexible, bar, 0) >= sizeof(struct flexible)); - ret &= bfs_check(sizeof_flex(struct flexible, bar, 16) % alignof(struct flexible) == 0); + bfs_check(sizeof_flex(struct flexible, bar, 0) >= sizeof(struct flexible)); + bfs_check(sizeof_flex(struct flexible, bar, 16) % alignof(struct flexible) == 0); size_t too_many = SIZE_MAX / sizeof(int) + 1; - ret &= bfs_check(sizeof_flex(struct flexible, bar, too_many) == align_floor(alignof(struct flexible), SIZE_MAX)); + bfs_check(sizeof_flex(struct flexible, bar, too_many) == align_floor(alignof(struct flexible), SIZE_MAX)); // Corner case: sizeof(type) > align_ceil(alignof(type), offsetof(type, member)) // Doesn't happen in typical ABIs - ret &= bfs_check(flex_size(8, 16, 4, 4, 1) == 16); + bfs_check(flex_size(8, 16, 4, 4, 1) == 16); // Make sure we detect allocation size overflows #if __GNUC__ && !__clang__ # pragma GCC diagnostic ignored "-Walloc-size-larger-than=" #endif - ret &= bfs_check(ALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); - ret &= bfs_check(ZALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); - ret &= bfs_check(ALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); - ret &= bfs_check(ZALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); + bfs_check(ALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); + bfs_check(ZALLOC_ARRAY(int, too_many) == NULL && errno == EOVERFLOW); + bfs_check(ALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); + bfs_check(ZALLOC_FLEX(struct flexible, bar, too_many) == NULL && errno == EOVERFLOW); // varena tests struct varena varena; @@ -44,9 +43,8 @@ bool check_alloc(void) { for (size_t i = 0; i < 256; ++i) { bfs_verify(varena_alloc(&varena, i)); struct arena *arena = &varena.arenas[varena.narenas - 1]; - ret &= bfs_check(arena->size >= sizeof_flex(struct flexible, bar, i)); + bfs_check(arena->size >= sizeof_flex(struct flexible, bar, i)); } varena_destroy(&varena); - return ret; } diff --git a/tests/gnu/gid.out b/tests/bfs/Dmulti.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/gid.out +++ b/tests/bfs/Dmulti.out diff --git a/tests/bfs/Dmulti.sh b/tests/bfs/Dmulti.sh new file mode 100644 index 0000000..35d64b1 --- /dev/null +++ b/tests/bfs/Dmulti.sh @@ -0,0 +1 @@ +bfs_diff -Dopt,tree,unknown basic diff --git a/tests/bfs/LD_stat.out b/tests/bfs/LD_stat.out new file mode 100644 index 0000000..ec9e861 --- /dev/null +++ b/tests/bfs/LD_stat.out @@ -0,0 +1,17 @@ +links +links/broken +links/deeply +links/deeply/nested +links/deeply/nested/broken +links/deeply/nested/dir +links/deeply/nested/file +links/deeply/nested/link +links/file +links/hardlink +links/notdir +links/skip +links/skip/broken +links/skip/dir +links/skip/file +links/skip/link +links/symlink diff --git a/tests/bfs/LD_stat.sh b/tests/bfs/LD_stat.sh new file mode 100644 index 0000000..d407de3 --- /dev/null +++ b/tests/bfs/LD_stat.sh @@ -0,0 +1 @@ +bfs_diff -LD stat links diff --git a/tests/bfs/LDstat.out b/tests/bfs/LDstat.out new file mode 100644 index 0000000..ec9e861 --- /dev/null +++ b/tests/bfs/LDstat.out @@ -0,0 +1,17 @@ +links +links/broken +links/deeply +links/deeply/nested +links/deeply/nested/broken +links/deeply/nested/dir +links/deeply/nested/file +links/deeply/nested/link +links/file +links/hardlink +links/notdir +links/skip +links/skip/broken +links/skip/dir +links/skip/file +links/skip/link +links/symlink diff --git a/tests/bfs/LDstat.sh b/tests/bfs/LDstat.sh new file mode 100644 index 0000000..ec6df0b --- /dev/null +++ b/tests/bfs/LDstat.sh @@ -0,0 +1 @@ +bfs_diff -LDstat links diff --git a/tests/bfs/L_noerror.out b/tests/bfs/L_noerror.out new file mode 100644 index 0000000..a514555 --- /dev/null +++ b/tests/bfs/L_noerror.out @@ -0,0 +1,11 @@ +loops +loops/broken +loops/deeply +loops/deeply/nested +loops/deeply/nested/dir +loops/file +loops/notdir +loops/skip +loops/skip/dir +loops/skip/loop +loops/symlink diff --git a/tests/bfs/L_noerror.sh b/tests/bfs/L_noerror.sh new file mode 100644 index 0000000..7db2a4d --- /dev/null +++ b/tests/bfs/L_noerror.sh @@ -0,0 +1 @@ +bfs_diff -L loops -noerror diff --git a/tests/bfs/O_3.sh b/tests/bfs/O_3.sh new file mode 100644 index 0000000..f159852 --- /dev/null +++ b/tests/bfs/O_3.sh @@ -0,0 +1 @@ +! invoke_bfs -O 3 basic diff --git a/tests/bfs/Sbfs.out b/tests/bfs/Sbfs.out new file mode 100644 index 0000000..bb3cd8d --- /dev/null +++ b/tests/bfs/Sbfs.out @@ -0,0 +1,19 @@ +basic +basic/a +basic/b +basic/c +basic/e +basic/g +basic/i +basic/j +basic/k +basic/l +basic/c/d +basic/e/f +basic/g/h +basic/j/foo +basic/k/foo +basic/l/foo +basic/k/foo/bar +basic/l/foo/bar +basic/l/foo/bar/baz diff --git a/tests/bfs/Sbfs.sh b/tests/bfs/Sbfs.sh new file mode 100644 index 0000000..72d92c8 --- /dev/null +++ b/tests/bfs/Sbfs.sh @@ -0,0 +1,2 @@ +invoke_bfs -Sbfs -s basic >"$OUT" +diff_output diff --git a/tests/bfs/color_ext_case.sh b/tests/bfs/color_ext_case.sh index 4adba69..4c14610 100644 --- a/tests/bfs/color_ext_case.sh +++ b/tests/bfs/color_ext_case.sh @@ -1,6 +1,6 @@ -# *.gz=01;31:*.GZ=01;32 -- case sensitive -# *.tAr=01;33:*.TaR=01;33 -- case-insensitive -# *.TAR.gz=01;34:*.tar.GZ=01;35 -- case-sensitive -# *.txt=35:*TXT=36 -- case-insensitive -export LS_COLORS="*.gz=01;31:*.GZ=01;32:*.tAr=01;33:*.TaR=01;33:*.TAR.gz=01;34:*.tar.GZ=01;35:*.txt=35:*TXT=36" +# *.gz=01;30:*.gz=01;31:*.GZ=01;30:*.GZ=01;32 -- case sensitive +# *.tAr=01;33:*.TaR=01;33 -- case-insensitive +# *.TAR.gz=01;34:*.tar.GZ=01;35 -- case-sensitive +# *.txt=35:*TXT=36 -- case-insensitive +export LS_COLORS="*.gz=01;30:*.gz=01;31:*.GZ=01;30:*.GZ=01;32:*.tAr=01;33:*.TaR=01;33:*.TAR.gz=01;34:*.tar.GZ=01;35:*.txt=35:*TXT=36" bfs_diff rainbow -color diff --git a/tests/bfs/color_ext_case_flipflop.out b/tests/bfs/color_ext_case_flipflop.out new file mode 100644 index 0000000..f4cc53c --- /dev/null +++ b/tests/bfs/color_ext_case_flipflop.out @@ -0,0 +1,27 @@ +[01;34m$'rainbow/\e[1m'[0m +[01;34m$'rainbow/\e[1m/'[0m$'\e[0m' +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;33mlower.tar.gz[0m +[01;34mrainbow/[0m[01;33mlu.tar.GZ[0m +[01;34mrainbow/[0m[01;33mul.TAR.gz[0m +[01;34mrainbow/[0m[01;33mupper.TAR.GZ[0m +[01;34mrainbow/[0m[01;35msocket[0m +[01;34mrainbow/[0m[01;36mbroken[0m +[01;34mrainbow/[0m[01;36mchardev_link[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[33mpipe[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mlower.gz +[01;34mrainbow/[0mlower.tar +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 +[01;34mrainbow/[0mupper.GZ +[01;34mrainbow/[0mupper.TAR diff --git a/tests/bfs/color_ext_case_flipflop.sh b/tests/bfs/color_ext_case_flipflop.sh new file mode 100644 index 0000000..4d6f615 --- /dev/null +++ b/tests/bfs/color_ext_case_flipflop.sh @@ -0,0 +1 @@ +LS_COLORS="*.tar.gz=01;31:*.TAR.GZ=01;32:*.TAR.GZ=01;33:*.tar.gz=01;33:" bfs_diff rainbow -color diff --git a/tests/bfs/color_ext_case_priority.out b/tests/bfs/color_ext_case_priority.out new file mode 100644 index 0000000..4a6c9a0 --- /dev/null +++ b/tests/bfs/color_ext_case_priority.out @@ -0,0 +1,27 @@ +[01;34m$'rainbow/\e[1m'[0m +[01;34m$'rainbow/\e[1m/'[0m$'\e[0m' +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;31mlower.tar.gz[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;32mupper.TAR.GZ[0m +[01;34mrainbow/[0m[01;33mlower.gz[0m +[01;34mrainbow/[0m[01;33mlu.tar.GZ[0m +[01;34mrainbow/[0m[01;33mul.TAR.gz[0m +[01;34mrainbow/[0m[01;33mupper.GZ[0m +[01;34mrainbow/[0m[01;35msocket[0m +[01;34mrainbow/[0m[01;36mbroken[0m +[01;34mrainbow/[0m[01;36mchardev_link[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[33mpipe[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mlower.tar +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 +[01;34mrainbow/[0mupper.TAR diff --git a/tests/bfs/color_ext_case_priority.sh b/tests/bfs/color_ext_case_priority.sh new file mode 100644 index 0000000..f178c56 --- /dev/null +++ b/tests/bfs/color_ext_case_priority.sh @@ -0,0 +1 @@ +LS_COLORS="*.gz=01;33:*.tar.gz=01;31:*.TAR.GZ=01;32:" bfs_diff rainbow -color diff --git a/tests/bfs/color_ext_override.sh b/tests/bfs/color_ext_override.sh index ac4c7fb..9f818c9 100644 --- a/tests/bfs/color_ext_override.sh +++ b/tests/bfs/color_ext_override.sh @@ -1 +1 @@ -LS_COLORS="*.tar.gz=01;31:*.TAR=01;32:*.gz=01;33:" bfs_diff rainbow -color +LS_COLORS="*.tar.gz=01;31:*.TAR=01;32:*.gz=01;30:*.gz=01;33:" bfs_diff rainbow -color diff --git a/tests/bfs/noerror.out b/tests/bfs/noerror.out new file mode 100644 index 0000000..c4f8ce4 --- /dev/null +++ b/tests/bfs/noerror.out @@ -0,0 +1,4 @@ +inaccessible +inaccessible/dir +inaccessible/file +inaccessible/link diff --git a/tests/bfs/noerror.sh b/tests/bfs/noerror.sh new file mode 100644 index 0000000..e334f8f --- /dev/null +++ b/tests/bfs/noerror.sh @@ -0,0 +1 @@ +bfs_diff inaccessible -noerror diff --git a/tests/bfs/noerror_nowarn.sh b/tests/bfs/noerror_nowarn.sh new file mode 100644 index 0000000..26e7e68 --- /dev/null +++ b/tests/bfs/noerror_nowarn.sh @@ -0,0 +1,2 @@ +stderr=$(invoke_bfs inaccessible -noerror -nowarn 2>&1 >/dev/null) +[ -z "$stderr" ] diff --git a/tests/bfs/noerror_warn.sh b/tests/bfs/noerror_warn.sh new file mode 100644 index 0000000..ec85f4c --- /dev/null +++ b/tests/bfs/noerror_warn.sh @@ -0,0 +1,2 @@ +stderr=$(invoke_bfs inaccessible -noerror -warn 2>&1 >/dev/null) +[ -n "$stderr" ] diff --git a/tests/bfs/nohidden.out b/tests/bfs/nohidden.out index d3ec901..84e6bd2 100644 --- a/tests/bfs/nohidden.out +++ b/tests/bfs/nohidden.out @@ -1,4 +1,8 @@ + +/n weirdnames +weirdnames/ +weirdnames/ weirdnames/ weirdnames/ /j weirdnames/! @@ -11,6 +15,8 @@ weirdnames/(-/c weirdnames/(/b weirdnames/) weirdnames/)/g +weirdnames/* +weirdnames/*/m weirdnames/, weirdnames/,/f weirdnames/- @@ -19,3 +25,5 @@ weirdnames/[ weirdnames/[/k weirdnames/\ weirdnames/\/i +weirdnames/{ +weirdnames/{/l diff --git a/tests/bfs/nohidden_depth.out b/tests/bfs/nohidden_depth.out index d3ec901..84e6bd2 100644 --- a/tests/bfs/nohidden_depth.out +++ b/tests/bfs/nohidden_depth.out @@ -1,4 +1,8 @@ + +/n weirdnames +weirdnames/ +weirdnames/ weirdnames/ weirdnames/ /j weirdnames/! @@ -11,6 +15,8 @@ weirdnames/(-/c weirdnames/(/b weirdnames/) weirdnames/)/g +weirdnames/* +weirdnames/*/m weirdnames/, weirdnames/,/f weirdnames/- @@ -19,3 +25,5 @@ weirdnames/[ weirdnames/[/k weirdnames/\ weirdnames/\/i +weirdnames/{ +weirdnames/{/l diff --git a/tests/bfs/perm_leading_plus_symbolic.out b/tests/bfs/perm_leading_plus_symbolic.out index e69de29..09bc88f 100644 --- a/tests/bfs/perm_leading_plus_symbolic.out +++ b/tests/bfs/perm_leading_plus_symbolic.out @@ -0,0 +1,3 @@ +perms +perms/drwxr-xr-x +perms/frwxr-xr-x diff --git a/tests/bfs/warn_without_noerror.sh b/tests/bfs/warn_without_noerror.sh new file mode 100644 index 0000000..5167309 --- /dev/null +++ b/tests/bfs/warn_without_noerror.sh @@ -0,0 +1,2 @@ +# bfs shouldn't print "warning: Suppressed errors" without -noerror +! invoke_bfs inaccessible -warn 2>&1 >/dev/null | grep warning >&2 diff --git a/tests/bfs/xtype_depth.sh b/tests/bfs/xtype_depth.sh index 02c8173..4683764 100644 --- a/tests/bfs/xtype_depth.sh +++ b/tests/bfs/xtype_depth.sh @@ -1,2 +1,2 @@ # Make sure -xtype is considered side-effecting for facts_when_impure -! invoke_bfs loops -xtype l -depth 100 +! invoke_bfs inaccessible/link -xtype l -depth 100 diff --git a/tests/bfs/xtype_reorder.sh b/tests/bfs/xtype_reorder.sh index 8d75d7d..c1d94f3 100644 --- a/tests/bfs/xtype_reorder.sh +++ b/tests/bfs/xtype_reorder.sh @@ -1,4 +1,3 @@ # Make sure -xtype is not reordered in front of anything -- if -xtype runs # before -links 100, it will report an ELOOP error -bfs_diff loops -links 100 -xtype l -invoke_bfs loops -links 100 -xtype l +bfs_diff inaccessible/link -links 100 -xtype l diff --git a/tests/bfstd.c b/tests/bfstd.c index f0f61ce..a43783a 100644 --- a/tests/bfstd.c +++ b/tests/bfstd.c @@ -1,93 +1,86 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" + #include "bfstd.h" #include "diag.h" -#include <errno.h> + #include <langinfo.h> #include <stdlib.h> #include <string.h> /** Check the result of xdirname()/xbasename(). */ -static bool check_base_dir(const char *path, const char *dir, const char *base) { - bool ret = true; - +static void check_base_dir(const char *path, const char *dir, const char *base) { char *xdir = xdirname(path); bfs_everify(xdir, "xdirname()"); - ret &= bfs_check(strcmp(xdir, dir) == 0, "xdirname('%s') == '%s' (!= '%s')", path, xdir, dir); + bfs_check(strcmp(xdir, dir) == 0, "xdirname('%s') == '%s' (!= '%s')", path, xdir, dir); free(xdir); char *xbase = xbasename(path); bfs_everify(xbase, "xbasename()"); - ret &= bfs_check(strcmp(xbase, base) == 0, "xbasename('%s') == '%s' (!= '%s')", path, xbase, base); + bfs_check(strcmp(xbase, base) == 0, "xbasename('%s') == '%s' (!= '%s')", path, xbase, base); free(xbase); - - return ret; } /** Check the result of wordesc(). */ -static bool check_wordesc(const char *str, const char *exp, enum wesc_flags flags) { +static void check_wordesc(const char *str, const char *exp, enum wesc_flags flags) { char buf[256]; char *end = buf + sizeof(buf); char *esc = wordesc(buf, end, str, flags); - return bfs_check(esc != end) - && bfs_check(strcmp(buf, exp) == 0, "wordesc('%s') == '%s' (!= '%s')", str, buf, exp); + if (bfs_check(esc != end)) { + bfs_check(strcmp(buf, exp) == 0, "wordesc('%s') == '%s' (!= '%s')", str, buf, exp); + } } -bool check_bfstd(void) { - bool ret = true; - - ret &= bfs_check(asciilen("") == 0); - ret &= bfs_check(asciilen("@") == 1); - ret &= bfs_check(asciilen("@@") == 2); - ret &= bfs_check(asciilen("\xFF@") == 0); - ret &= bfs_check(asciilen("@\xFF") == 1); - ret &= bfs_check(asciilen("@@@@@@@@") == 8); - ret &= bfs_check(asciilen("@@@@@@@@@@@@@@@@") == 16); - ret &= bfs_check(asciilen("@@@@@@@@@@@@@@@@@@@@@@@@") == 24); - ret &= bfs_check(asciilen("@@@@@@@@@@@@@@a\xFF@@@@@@@") == 15); - ret &= bfs_check(asciilen("@@@@@@@@@@@@@@@@\xFF@@@@@@@") == 16); - ret &= bfs_check(asciilen("@@@@@@@@@@@@@@@@a\xFF@@@@@@") == 17); - ret &= bfs_check(asciilen("@@@@@@@\xFF@@@@@@a\xFF@@@@@@@") == 7); - ret &= bfs_check(asciilen("@@@@@@@@\xFF@@@@@a\xFF@@@@@@@") == 8); - ret &= bfs_check(asciilen("@@@@@@@@@\xFF@@@@a\xFF@@@@@@@") == 9); +void check_bfstd(void) { + bfs_check(asciilen("") == 0); + bfs_check(asciilen("@") == 1); + bfs_check(asciilen("@@") == 2); + bfs_check(asciilen("\xFF@") == 0); + bfs_check(asciilen("@\xFF") == 1); + bfs_check(asciilen("@@@@@@@@") == 8); + bfs_check(asciilen("@@@@@@@@@@@@@@@@") == 16); + bfs_check(asciilen("@@@@@@@@@@@@@@@@@@@@@@@@") == 24); + bfs_check(asciilen("@@@@@@@@@@@@@@a\xFF@@@@@@@") == 15); + bfs_check(asciilen("@@@@@@@@@@@@@@@@\xFF@@@@@@@") == 16); + bfs_check(asciilen("@@@@@@@@@@@@@@@@a\xFF@@@@@@") == 17); + bfs_check(asciilen("@@@@@@@\xFF@@@@@@a\xFF@@@@@@@") == 7); + bfs_check(asciilen("@@@@@@@@\xFF@@@@@a\xFF@@@@@@@") == 8); + bfs_check(asciilen("@@@@@@@@@\xFF@@@@a\xFF@@@@@@@") == 9); // From man 3p basename - ret &= check_base_dir("usr", ".", "usr"); - ret &= check_base_dir("usr/", ".", "usr"); - ret &= check_base_dir("", ".", "."); - ret &= check_base_dir("/", "/", "/"); + check_base_dir("usr", ".", "usr"); + check_base_dir("usr/", ".", "usr"); + check_base_dir("", ".", "."); + check_base_dir("/", "/", "/"); // check_base_dir("//", "/" or "//", "/" or "//"); - ret &= check_base_dir("///", "/", "/"); - ret &= check_base_dir("/usr/", "/", "usr"); - ret &= check_base_dir("/usr/lib", "/usr", "lib"); - ret &= check_base_dir("//usr//lib//", "//usr", "lib"); - ret &= check_base_dir("/home//dwc//test", "/home//dwc", "test"); + check_base_dir("///", "/", "/"); + check_base_dir("/usr/", "/", "usr"); + check_base_dir("/usr/lib", "/usr", "lib"); + check_base_dir("//usr//lib//", "//usr", "lib"); + check_base_dir("/home//dwc//test", "/home//dwc", "test"); - ret &= check_wordesc("", "\"\"", WESC_SHELL); - ret &= check_wordesc("word", "word", WESC_SHELL); - ret &= check_wordesc("two words", "\"two words\"", WESC_SHELL); - ret &= check_wordesc("word's", "\"word's\"", WESC_SHELL); - ret &= check_wordesc("\"word\"", "'\"word\"'", WESC_SHELL); - ret &= check_wordesc("\"word's\"", "'\"word'\\''s\"'", WESC_SHELL); - ret &= check_wordesc("\033[1mbold's\033[0m", "$'\\e[1mbold\\'s\\e[0m'", WESC_SHELL | WESC_TTY); - ret &= check_wordesc("\x7F", "$'\\x7F'", WESC_SHELL | WESC_TTY); - ret &= check_wordesc("~user", "\"~user\"", WESC_SHELL); + check_wordesc("", "\"\"", WESC_SHELL); + check_wordesc("word", "word", WESC_SHELL); + check_wordesc("two words", "\"two words\"", WESC_SHELL); + check_wordesc("word's", "\"word's\"", WESC_SHELL); + check_wordesc("\"word\"", "'\"word\"'", WESC_SHELL); + check_wordesc("\"word's\"", "'\"word'\\''s\"'", WESC_SHELL); + check_wordesc("\033[1mbold's\033[0m", "$'\\e[1mbold\\'s\\e[0m'", WESC_SHELL | WESC_TTY); + check_wordesc("\x7F", "$'\\x7F'", WESC_SHELL | WESC_TTY); + check_wordesc("~user", "\"~user\"", WESC_SHELL); const char *charmap = nl_langinfo(CODESET); if (strcmp(charmap, "UTF-8") == 0) { - ret &= check_wordesc("\xF0", "$'\\xF0'", WESC_SHELL | WESC_TTY); - ret &= check_wordesc("\xF0\x9F", "$'\\xF0\\x9F'", WESC_SHELL | WESC_TTY); - ret &= check_wordesc("\xF0\x9F\x98", "$'\\xF0\\x9F\\x98'", WESC_SHELL | WESC_TTY); - ret &= check_wordesc("\xF0\x9F\x98\x80", "\xF0\x9F\x98\x80", WESC_SHELL | WESC_TTY); - ret &= check_wordesc("\xCB\x9Cuser", "\xCB\x9Cuser", WESC_SHELL); + check_wordesc("\xF0", "$'\\xF0'", WESC_SHELL | WESC_TTY); + check_wordesc("\xF0\x9F", "$'\\xF0\\x9F'", WESC_SHELL | WESC_TTY); + check_wordesc("\xF0\x9F\x98", "$'\\xF0\\x9F\\x98'", WESC_SHELL | WESC_TTY); + check_wordesc("\xF0\x9F\x98\x80", "\xF0\x9F\x98\x80", WESC_SHELL | WESC_TTY); + check_wordesc("\xCB\x9Cuser", "\xCB\x9Cuser", WESC_SHELL); } - ret &= bfs_check(xstrwidth("Hello world") == 11); - ret &= bfs_check(xstrwidth("Hello\1world") == 10); - - return ret; + bfs_check(xstrwidth("Hello world") == 11); + bfs_check(xstrwidth("Hello\1world") == 10); } diff --git a/tests/bit.c b/tests/bit.c index 674d1b2..cc95785 100644 --- a/tests/bit.c +++ b/tests/bit.c @@ -1,141 +1,144 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" + +#include "bfs.h" #include "bit.h" -#include "diag.h" + #include <limits.h> #include <stdint.h> #include <string.h> -bfs_static_assert(UMAX_WIDTH(0x1) == 1); -bfs_static_assert(UMAX_WIDTH(0x3) == 2); -bfs_static_assert(UMAX_WIDTH(0x7) == 3); -bfs_static_assert(UMAX_WIDTH(0xF) == 4); -bfs_static_assert(UMAX_WIDTH(0xFF) == 8); -bfs_static_assert(UMAX_WIDTH(0xFFF) == 12); -bfs_static_assert(UMAX_WIDTH(0xFFFF) == 16); +// Polyfill C23's one-argument static_assert() +#if __STDC_VERSION__ < C23 +# undef static_assert +# define static_assert(...) _Static_assert(__VA_ARGS__, #__VA_ARGS__) +#endif + +static_assert(UMAX_WIDTH(0x1) == 1); +static_assert(UMAX_WIDTH(0x3) == 2); +static_assert(UMAX_WIDTH(0x7) == 3); +static_assert(UMAX_WIDTH(0xF) == 4); +static_assert(UMAX_WIDTH(0xFF) == 8); +static_assert(UMAX_WIDTH(0xFFF) == 12); +static_assert(UMAX_WIDTH(0xFFFF) == 16); #define UWIDTH_MAX(n) (2 * ((UINTMAX_C(1) << ((n) - 1)) - 1) + 1) #define IWIDTH_MAX(n) UWIDTH_MAX((n) - 1) #define IWIDTH_MIN(n) (-(intmax_t)IWIDTH_MAX(n) - 1) -bfs_static_assert(UCHAR_MAX == UWIDTH_MAX(UCHAR_WIDTH)); -bfs_static_assert(SCHAR_MIN == IWIDTH_MIN(SCHAR_WIDTH)); -bfs_static_assert(SCHAR_MAX == IWIDTH_MAX(SCHAR_WIDTH)); +static_assert(UCHAR_MAX == UWIDTH_MAX(UCHAR_WIDTH)); +static_assert(SCHAR_MIN == IWIDTH_MIN(SCHAR_WIDTH)); +static_assert(SCHAR_MAX == IWIDTH_MAX(SCHAR_WIDTH)); -bfs_static_assert(USHRT_MAX == UWIDTH_MAX(USHRT_WIDTH)); -bfs_static_assert(SHRT_MIN == IWIDTH_MIN(SHRT_WIDTH)); -bfs_static_assert(SHRT_MAX == IWIDTH_MAX(SHRT_WIDTH)); +static_assert(USHRT_MAX == UWIDTH_MAX(USHRT_WIDTH)); +static_assert(SHRT_MIN == IWIDTH_MIN(SHRT_WIDTH)); +static_assert(SHRT_MAX == IWIDTH_MAX(SHRT_WIDTH)); -bfs_static_assert(UINT_MAX == UWIDTH_MAX(UINT_WIDTH)); -bfs_static_assert(INT_MIN == IWIDTH_MIN(INT_WIDTH)); -bfs_static_assert(INT_MAX == IWIDTH_MAX(INT_WIDTH)); +static_assert(UINT_MAX == UWIDTH_MAX(UINT_WIDTH)); +static_assert(INT_MIN == IWIDTH_MIN(INT_WIDTH)); +static_assert(INT_MAX == IWIDTH_MAX(INT_WIDTH)); -bfs_static_assert(ULONG_MAX == UWIDTH_MAX(ULONG_WIDTH)); -bfs_static_assert(LONG_MIN == IWIDTH_MIN(LONG_WIDTH)); -bfs_static_assert(LONG_MAX == IWIDTH_MAX(LONG_WIDTH)); +static_assert(ULONG_MAX == UWIDTH_MAX(ULONG_WIDTH)); +static_assert(LONG_MIN == IWIDTH_MIN(LONG_WIDTH)); +static_assert(LONG_MAX == IWIDTH_MAX(LONG_WIDTH)); -bfs_static_assert(ULLONG_MAX == UWIDTH_MAX(ULLONG_WIDTH)); -bfs_static_assert(LLONG_MIN == IWIDTH_MIN(LLONG_WIDTH)); -bfs_static_assert(LLONG_MAX == IWIDTH_MAX(LLONG_WIDTH)); +static_assert(ULLONG_MAX == UWIDTH_MAX(ULLONG_WIDTH)); +static_assert(LLONG_MIN == IWIDTH_MIN(LLONG_WIDTH)); +static_assert(LLONG_MAX == IWIDTH_MAX(LLONG_WIDTH)); -bfs_static_assert(SIZE_MAX == UWIDTH_MAX(SIZE_WIDTH)); -bfs_static_assert(PTRDIFF_MIN == IWIDTH_MIN(PTRDIFF_WIDTH)); -bfs_static_assert(PTRDIFF_MAX == IWIDTH_MAX(PTRDIFF_WIDTH)); +static_assert(SIZE_MAX == UWIDTH_MAX(SIZE_WIDTH)); +static_assert(PTRDIFF_MIN == IWIDTH_MIN(PTRDIFF_WIDTH)); +static_assert(PTRDIFF_MAX == IWIDTH_MAX(PTRDIFF_WIDTH)); -bfs_static_assert(UINTPTR_MAX == UWIDTH_MAX(UINTPTR_WIDTH)); -bfs_static_assert(INTPTR_MIN == IWIDTH_MIN(INTPTR_WIDTH)); -bfs_static_assert(INTPTR_MAX == IWIDTH_MAX(INTPTR_WIDTH)); +static_assert(UINTPTR_MAX == UWIDTH_MAX(UINTPTR_WIDTH)); +static_assert(INTPTR_MIN == IWIDTH_MIN(INTPTR_WIDTH)); +static_assert(INTPTR_MAX == IWIDTH_MAX(INTPTR_WIDTH)); -bfs_static_assert(UINTMAX_MAX == UWIDTH_MAX(UINTMAX_WIDTH)); -bfs_static_assert(INTMAX_MIN == IWIDTH_MIN(INTMAX_WIDTH)); -bfs_static_assert(INTMAX_MAX == IWIDTH_MAX(INTMAX_WIDTH)); +static_assert(UINTMAX_MAX == UWIDTH_MAX(UINTMAX_WIDTH)); +static_assert(INTMAX_MIN == IWIDTH_MIN(INTMAX_WIDTH)); +static_assert(INTMAX_MAX == IWIDTH_MAX(INTMAX_WIDTH)); #define check_eq(a, b) \ bfs_check((a) == (b), "(0x%jX) %s != %s (0x%jX)", (uintmax_t)(a), #a, #b, (uintmax_t)(b)) -bool check_bit(void) { - bool ret = true; - +void check_bit(void) { const char *str = "\x1\x2\x3\x4"; uint32_t word; memcpy(&word, str, sizeof(word)); #if ENDIAN_NATIVE == ENDIAN_LITTLE - ret &= check_eq(word, 0x04030201); + check_eq(word, 0x04030201); #elif ENDIAN_NATIVE == ENDIAN_BIG - ret &= check_eq(word, 0x01020304); + check_eq(word, 0x01020304); #else # warning "Skipping byte order tests on mixed/unknown-endian machine" #endif - ret &= check_eq(bswap((uint8_t)0x12), 0x12); - ret &= check_eq(bswap((uint16_t)0x1234), 0x3412); - ret &= check_eq(bswap((uint32_t)0x12345678), 0x78563412); - ret &= check_eq(bswap((uint64_t)0x1234567812345678), 0x7856341278563412); - - ret &= check_eq(count_ones(0x0), 0); - ret &= check_eq(count_ones(0x1), 1); - ret &= check_eq(count_ones(0x2), 1); - ret &= check_eq(count_ones(0x3), 2); - ret &= check_eq(count_ones(0x137F), 10); - - ret &= check_eq(count_zeros(0), INT_WIDTH); - ret &= check_eq(count_zeros(0L), LONG_WIDTH); - ret &= check_eq(count_zeros(0LL), LLONG_WIDTH); - ret &= check_eq(count_zeros((uint8_t)0), 8); - ret &= check_eq(count_zeros((uint16_t)0), 16); - ret &= check_eq(count_zeros((uint32_t)0), 32); - ret &= check_eq(count_zeros((uint64_t)0), 64); - - ret &= check_eq(rotate_left((uint8_t)0xA1, 4), 0x1A); - ret &= check_eq(rotate_left((uint16_t)0x1234, 12), 0x4123); - ret &= check_eq(rotate_left((uint32_t)0x12345678, 20), 0x67812345); - ret &= check_eq(rotate_left((uint32_t)0x12345678, 0), 0x12345678); - - ret &= check_eq(rotate_right((uint8_t)0xA1, 4), 0x1A); - ret &= check_eq(rotate_right((uint16_t)0x1234, 12), 0x2341); - ret &= check_eq(rotate_right((uint32_t)0x12345678, 20), 0x45678123); - ret &= check_eq(rotate_right((uint32_t)0x12345678, 0), 0x12345678); - - for (int i = 0; i < 16; ++i) { + check_eq(bswap((uint8_t)0x12), 0x12); + check_eq(bswap((uint16_t)0x1234), 0x3412); + check_eq(bswap((uint32_t)0x12345678), 0x78563412); + check_eq(bswap((uint64_t)0x1234567812345678), 0x7856341278563412); + + check_eq(count_ones(0x0U), 0); + check_eq(count_ones(0x1U), 1); + check_eq(count_ones(0x2U), 1); + check_eq(count_ones(0x3U), 2); + check_eq(count_ones(0x137FU), 10); + + check_eq(count_zeros(0U), UINT_WIDTH); + check_eq(count_zeros(0UL), ULONG_WIDTH); + check_eq(count_zeros(0ULL), ULLONG_WIDTH); + check_eq(count_zeros((uint8_t)0), 8); + check_eq(count_zeros((uint16_t)0), 16); + check_eq(count_zeros((uint32_t)0), 32); + check_eq(count_zeros((uint64_t)0), 64); + + check_eq(rotate_left((uint8_t)0xA1, 4), 0x1A); + check_eq(rotate_left((uint16_t)0x1234, 12), 0x4123); + check_eq(rotate_left((uint32_t)0x12345678, 20), 0x67812345); + check_eq(rotate_left((uint32_t)0x12345678, 0), 0x12345678); + + check_eq(rotate_right((uint8_t)0xA1, 4), 0x1A); + check_eq(rotate_right((uint16_t)0x1234, 12), 0x2341); + check_eq(rotate_right((uint32_t)0x12345678, 20), 0x45678123); + check_eq(rotate_right((uint32_t)0x12345678, 0), 0x12345678); + + for (unsigned int i = 0; i < 16; ++i) { uint16_t n = (uint16_t)1 << i; - for (int j = i; j < 16; ++j) { + for (unsigned int j = i; j < 16; ++j) { uint16_t m = (uint16_t)1 << j; uint16_t nm = n | m; - ret &= check_eq(count_ones(nm), 1 + (n != m)); - ret &= check_eq(count_zeros(nm), 15 - (n != m)); - ret &= check_eq(leading_zeros(nm), 15 - j); - ret &= check_eq(trailing_zeros(nm), i); - ret &= check_eq(first_leading_one(nm), j + 1); - ret &= check_eq(first_trailing_one(nm), i + 1); - ret &= check_eq(bit_width(nm), j + 1); - ret &= check_eq(bit_floor(nm), m); + check_eq(count_ones(nm), 1 + (n != m)); + check_eq(count_zeros(nm), 15 - (n != m)); + check_eq(leading_zeros(nm), 15 - j); + check_eq(trailing_zeros(nm), i); + check_eq(first_leading_one(nm), 16 - j); + check_eq(first_trailing_one(nm), i + 1); + check_eq(bit_width(nm), j + 1); + check_eq(bit_floor(nm), m); if (n == m) { - ret &= check_eq(bit_ceil(nm), m); - ret &= bfs_check(has_single_bit(nm)); + check_eq(bit_ceil(nm), m); + bfs_check(has_single_bit(nm)); } else { if (j < 15) { - ret &= check_eq(bit_ceil(nm), (m << 1)); + check_eq(bit_ceil(nm), (m << 1)); } - ret &= bfs_check(!has_single_bit(nm)); + bfs_check(!has_single_bit(nm)); } } } - ret &= check_eq(leading_zeros((uint16_t)0), 16); - ret &= check_eq(trailing_zeros((uint16_t)0), 16); - ret &= check_eq(first_leading_one(0), 0); - ret &= check_eq(first_trailing_one(0), 0); - ret &= check_eq(bit_width(0), 0); - ret &= check_eq(bit_floor(0), 0); - ret &= check_eq(bit_ceil(0), 1); - - ret &= bfs_check(!has_single_bit(0)); - ret &= bfs_check(!has_single_bit(UINT32_MAX)); - ret &= bfs_check(has_single_bit((uint32_t)1 << (UINT_WIDTH - 1))); - - return ret; + check_eq(leading_zeros((uint16_t)0), 16); + check_eq(trailing_zeros((uint16_t)0), 16); + check_eq(first_leading_one(0U), 0); + check_eq(first_trailing_one(0U), 0); + check_eq(bit_width(0U), 0); + check_eq(bit_floor(0U), 0); + check_eq(bit_ceil(0U), 1); + + bfs_check(!has_single_bit(0U)); + bfs_check(!has_single_bit(UINT32_MAX)); + bfs_check(has_single_bit((uint32_t)1 << (UINT_WIDTH - 1))); } diff --git a/tests/bsd/Hf.out b/tests/bsd/Hf.out new file mode 100644 index 0000000..ff635ff --- /dev/null +++ b/tests/bsd/Hf.out @@ -0,0 +1 @@ +links/deeply/nested/dir diff --git a/tests/bsd/Hf.sh b/tests/bsd/Hf.sh new file mode 100644 index 0000000..333280c --- /dev/null +++ b/tests/bsd/Hf.sh @@ -0,0 +1 @@ +bfs_diff -Hf links/deeply/nested/dir diff --git a/tests/bsd/X.out b/tests/bsd/X.out index afa84f7..dbe2408 100644 --- a/tests/bsd/X.out +++ b/tests/bsd/X.out @@ -9,6 +9,8 @@ weirdnames/(-/c weirdnames/(/b weirdnames/) weirdnames/)/g +weirdnames/* +weirdnames/*/m weirdnames/, weirdnames/,/f weirdnames/- @@ -17,3 +19,5 @@ weirdnames/... weirdnames/.../h weirdnames/[ weirdnames/[/k +weirdnames/{ +weirdnames/{/l diff --git a/tests/bsd/perm_000_plus.out b/tests/bsd/perm_000_plus.out index d7494b8..e279684 100644 --- a/tests/bsd/perm_000_plus.out +++ b/tests/bsd/perm_000_plus.out @@ -1,8 +1,29 @@ perms -perms/0 -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f--------- +perms/f--x------ +perms/f--x--x--x +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/bsd/perm_222_plus.out b/tests/bsd/perm_222_plus.out index 9a5b95a..1b6d885 100644 --- a/tests/bsd/perm_222_plus.out +++ b/tests/bsd/perm_222_plus.out @@ -1,5 +1,20 @@ perms -perms/rw -perms/rwx -perms/w -perms/wx +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/bsd/perm_644_plus.out b/tests/bsd/perm_644_plus.out index 7e5ae98..eef88ca 100644 --- a/tests/bsd/perm_644_plus.out +++ b/tests/bsd/perm_644_plus.out @@ -1,7 +1,26 @@ perms -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/bsd/printx.out b/tests/bsd/printx.out index 04bf9a9..034b2da 100644 --- a/tests/bsd/printx.out +++ b/tests/bsd/printx.out @@ -1,3 +1,5 @@ + +/n weirdnames weirdnames/! weirdnames/!- @@ -9,6 +11,8 @@ weirdnames/(-/c weirdnames/(/b weirdnames/) weirdnames/)/g +weirdnames/* +weirdnames/*/m weirdnames/, weirdnames/,/f weirdnames/- @@ -17,7 +21,11 @@ weirdnames/... weirdnames/.../h weirdnames/[ weirdnames/[/k +weirdnames/\ +weirdnames/\ weirdnames/\ weirdnames/\ /j weirdnames/\\ weirdnames/\\/i +weirdnames/{ +weirdnames/{/l diff --git a/tests/bsd/s.out b/tests/bsd/s.out index 6b790c2..5c85ac8 100644 --- a/tests/bsd/s.out +++ b/tests/bsd/s.out @@ -1,12 +1,16 @@ weirdnames +weirdnames/ + weirdnames/ weirdnames/! weirdnames/!- weirdnames/( weirdnames/(- weirdnames/) +weirdnames/* weirdnames/, weirdnames/- weirdnames/... weirdnames/[ weirdnames/\ +weirdnames/{ diff --git a/tests/common/HLP.out b/tests/common/HLP.out new file mode 100644 index 0000000..ff635ff --- /dev/null +++ b/tests/common/HLP.out @@ -0,0 +1 @@ +links/deeply/nested/dir diff --git a/tests/common/HLP.sh b/tests/common/HLP.sh new file mode 100644 index 0000000..4b6d631 --- /dev/null +++ b/tests/common/HLP.sh @@ -0,0 +1 @@ +bfs_diff -HLP links/deeply/nested/dir diff --git a/tests/common/L_mount.out b/tests/common/L_mount.out deleted file mode 100644 index 788579d..0000000 --- a/tests/common/L_mount.out +++ /dev/null @@ -1,5 +0,0 @@ -. -./foo -./foo/bar -./foo/qux -./mnt diff --git a/tests/common/amin.out b/tests/common/amin.out new file mode 100644 index 0000000..af57325 --- /dev/null +++ b/tests/common/amin.out @@ -0,0 +1,6 @@ +-amin 1: ./one_minute_ago +-amin +1: ./one_hour_ago +-amin +1: ./two_minutes_ago +-amin -1: ./in_one_hour +-amin -1: ./in_one_minute +-amin -1: ./thirty_seconds_ago diff --git a/tests/common/amin.sh b/tests/common/amin.sh new file mode 100644 index 0000000..92c3531 --- /dev/null +++ b/tests/common/amin.sh @@ -0,0 +1,15 @@ +cd "$TEST" + +now=$(epoch_time) + +"$XTOUCH" -at "@$((now - 60 * 60))" one_hour_ago +"$XTOUCH" -at "@$((now - 121))" two_minutes_ago +"$XTOUCH" -at "@$((now - 61))" one_minute_ago +"$XTOUCH" -at "@$((now - 30))" thirty_seconds_ago +"$XTOUCH" -at "@$((now + 60))" in_one_minute +"$XTOUCH" -at "@$((now + 60 * 60))" in_one_hour + +bfs_diff . -mindepth 1 \ + \( -amin -1 -exec printf -- '-amin -1: %s\n' {} \; -o -true \) \ + \( -amin 1 -exec printf -- '-amin 1: %s\n' {} \; -o -true \) \ + \( -amin +1 -exec printf -- '-amin +1: %s\n' {} \; -o -true \) diff --git a/tests/common/empty_error.out b/tests/common/empty_error.out index da45e23..49f773d 100644 --- a/tests/common/empty_error.out +++ b/tests/common/empty_error.out @@ -1,3 +1 @@ -./bar -./baz -./qux +inaccessible/file diff --git a/tests/common/empty_error.sh b/tests/common/empty_error.sh index 7c8049c..3438cca 100644 --- a/tests/common/empty_error.sh +++ b/tests/common/empty_error.sh @@ -1,7 +1 @@ -cd "$TEST" - -"$XTOUCH" -p foo/ bar/ baz qux -chmod -r foo baz -defer chmod +r foo baz - -! bfs_diff . -empty +! bfs_diff inaccessible -empty diff --git a/tests/gnu/gid_minus.out b/tests/common/gid.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/gid_minus.out +++ b/tests/common/gid.out diff --git a/tests/gnu/gid.sh b/tests/common/gid.sh index 2707b4a..2707b4a 100644 --- a/tests/gnu/gid.sh +++ b/tests/common/gid.sh diff --git a/tests/common/gid_invalid_id.sh b/tests/common/gid_invalid_id.sh new file mode 100644 index 0000000..74f0055 --- /dev/null +++ b/tests/common/gid_invalid_id.sh @@ -0,0 +1 @@ +! invoke_bfs -gid 1eW6f5RM9Qi diff --git a/tests/common/gid_invalid_name.sh b/tests/common/gid_invalid_name.sh new file mode 100644 index 0000000..0e2e5f5 --- /dev/null +++ b/tests/common/gid_invalid_name.sh @@ -0,0 +1 @@ +! invoke_bfs -gid eW6f5RM9Qi diff --git a/tests/gnu/gid_minus_plus.out b/tests/common/gid_minus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/gid_minus_plus.out +++ b/tests/common/gid_minus.out diff --git a/tests/gnu/gid_minus.sh b/tests/common/gid_minus.sh index e3822f0..e3822f0 100644 --- a/tests/gnu/gid_minus.sh +++ b/tests/common/gid_minus.sh diff --git a/tests/gnu/gid_plus.out b/tests/common/gid_minus_plus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/gid_plus.out +++ b/tests/common/gid_minus_plus.out diff --git a/tests/gnu/gid_minus_plus.sh b/tests/common/gid_minus_plus.sh index 4ff0877..4ff0877 100644 --- a/tests/gnu/gid_minus_plus.sh +++ b/tests/common/gid_minus_plus.sh diff --git a/tests/gnu/gid_plus_plus.out b/tests/common/gid_plus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/gid_plus_plus.out +++ b/tests/common/gid_plus.out diff --git a/tests/gnu/gid_plus.sh b/tests/common/gid_plus.sh index ccba0e6..ccba0e6 100644 --- a/tests/gnu/gid_plus.sh +++ b/tests/common/gid_plus.sh diff --git a/tests/gnu/uid.out b/tests/common/gid_plus_plus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/uid.out +++ b/tests/common/gid_plus_plus.out diff --git a/tests/gnu/gid_plus_plus.sh b/tests/common/gid_plus_plus.sh index ec7ae86..ec7ae86 100644 --- a/tests/gnu/gid_plus_plus.sh +++ b/tests/common/gid_plus_plus.sh diff --git a/tests/common/iname.sh b/tests/common/iname.sh deleted file mode 100644 index c25a646..0000000 --- a/tests/common/iname.sh +++ /dev/null @@ -1,2 +0,0 @@ -invoke_bfs -quit -iname PATTERN || skip -bfs_diff basic -iname '*F*' diff --git a/tests/common/mmin.out b/tests/common/mmin.out new file mode 100644 index 0000000..4c79a16 --- /dev/null +++ b/tests/common/mmin.out @@ -0,0 +1,6 @@ +-mmin 1: ./one_minute_ago +-mmin +1: ./one_hour_ago +-mmin +1: ./two_minutes_ago +-mmin -1: ./in_one_hour +-mmin -1: ./in_one_minute +-mmin -1: ./thirty_seconds_ago diff --git a/tests/common/mmin.sh b/tests/common/mmin.sh new file mode 100644 index 0000000..4e1d19c --- /dev/null +++ b/tests/common/mmin.sh @@ -0,0 +1,15 @@ +cd "$TEST" + +now=$(epoch_time) + +"$XTOUCH" -mt "@$((now - 60 * 60))" one_hour_ago +"$XTOUCH" -mt "@$((now - 121))" two_minutes_ago +"$XTOUCH" -mt "@$((now - 61))" one_minute_ago +"$XTOUCH" -mt "@$((now - 30))" thirty_seconds_ago +"$XTOUCH" -mt "@$((now + 60))" in_one_minute +"$XTOUCH" -mt "@$((now + 60 * 60))" in_one_hour + +bfs_diff . -mindepth 1 \ + \( -mmin -1 -exec printf -- '-mmin -1: %s\n' {} \; -o -true \) \ + \( -mmin 1 -exec printf -- '-mmin 1: %s\n' {} \; -o -true \) \ + \( -mmin +1 -exec printf -- '-mmin +1: %s\n' {} \; -o -true \) diff --git a/tests/common/name_slash.sh b/tests/common/name_slash.sh deleted file mode 100644 index 8d89623..0000000 --- a/tests/common/name_slash.sh +++ /dev/null @@ -1 +0,0 @@ -bfs_diff / -maxdepth 0 -name / diff --git a/tests/common/name_slashes.sh b/tests/common/name_slashes.sh deleted file mode 100644 index 78d0a84..0000000 --- a/tests/common/name_slashes.sh +++ /dev/null @@ -1 +0,0 @@ -bfs_diff /// -maxdepth 0 -name / diff --git a/tests/gnu/uid_minus.out b/tests/common/uid.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/uid_minus.out +++ b/tests/common/uid.out diff --git a/tests/gnu/uid.sh b/tests/common/uid.sh index fb3cd93..fb3cd93 100644 --- a/tests/gnu/uid.sh +++ b/tests/common/uid.sh diff --git a/tests/common/uid_invalid_id.sh b/tests/common/uid_invalid_id.sh new file mode 100644 index 0000000..f5b952d --- /dev/null +++ b/tests/common/uid_invalid_id.sh @@ -0,0 +1 @@ +! invoke_bfs -uid 1eW6f5RM9Qi diff --git a/tests/common/uid_invalid_name.sh b/tests/common/uid_invalid_name.sh new file mode 100644 index 0000000..a2c359f --- /dev/null +++ b/tests/common/uid_invalid_name.sh @@ -0,0 +1 @@ +! invoke_bfs -uid eW6f5RM9Qi diff --git a/tests/gnu/uid_minus_plus.out b/tests/common/uid_minus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/uid_minus_plus.out +++ b/tests/common/uid_minus.out diff --git a/tests/gnu/uid_minus.sh b/tests/common/uid_minus.sh index 6d371f2..6d371f2 100644 --- a/tests/gnu/uid_minus.sh +++ b/tests/common/uid_minus.sh diff --git a/tests/gnu/uid_plus.out b/tests/common/uid_minus_plus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/uid_plus.out +++ b/tests/common/uid_minus_plus.out diff --git a/tests/gnu/uid_minus_plus.sh b/tests/common/uid_minus_plus.sh index e7a0496..e7a0496 100644 --- a/tests/gnu/uid_minus_plus.sh +++ b/tests/common/uid_minus_plus.sh diff --git a/tests/gnu/uid_plus_plus.out b/tests/common/uid_plus.out index a7ccfe4..a7ccfe4 100644 --- a/tests/gnu/uid_plus_plus.out +++ b/tests/common/uid_plus.out diff --git a/tests/gnu/uid_plus.sh b/tests/common/uid_plus.sh index 22b2c8e..22b2c8e 100644 --- a/tests/gnu/uid_plus.sh +++ b/tests/common/uid_plus.sh diff --git a/tests/common/uid_plus_plus.out b/tests/common/uid_plus_plus.out new file mode 100644 index 0000000..a7ccfe4 --- /dev/null +++ b/tests/common/uid_plus_plus.out @@ -0,0 +1,19 @@ +basic +basic/a +basic/b +basic/c +basic/c/d +basic/e +basic/e/f +basic/g +basic/g/h +basic/i +basic/j +basic/j/foo +basic/k +basic/k/foo +basic/k/foo/bar +basic/l +basic/l/foo +basic/l/foo/bar +basic/l/foo/bar/baz diff --git a/tests/gnu/uid_plus_plus.sh b/tests/common/uid_plus_plus.sh index e021888..e021888 100644 --- a/tests/gnu/uid_plus_plus.sh +++ b/tests/common/uid_plus_plus.sh diff --git a/tests/gnu/executable.out b/tests/gnu/executable.out index 49c1b21..e256554 100644 --- a/tests/gnu/executable.out +++ b/tests/gnu/executable.out @@ -1,4 +1,19 @@ perms -perms/rwx -perms/rx -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f--x------ +perms/f--x--x--x +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-x------ +perms/fr-xr-xr-x +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/files0_from_file.out b/tests/gnu/files0_from_file.out index 1d87e6b..0f6b00d 100644 --- a/tests/gnu/files0_from_file.out +++ b/tests/gnu/files0_from_file.out @@ -1,3 +1,7 @@ + + + + /j /j @@ -16,6 +20,9 @@ ) )/g )/g +* +*/m +*/m , ,/f ,/f @@ -25,9 +32,14 @@ ... .../h .../h +/n +/n [ [/k [/k \ \/i \/i +{ +{/l +{/l diff --git a/tests/gnu/files0_from_stdin.out b/tests/gnu/files0_from_stdin.out index 1d87e6b..0f6b00d 100644 --- a/tests/gnu/files0_from_stdin.out +++ b/tests/gnu/files0_from_stdin.out @@ -1,3 +1,7 @@ + + + + /j /j @@ -16,6 +20,9 @@ ) )/g )/g +* +*/m +*/m , ,/f ,/f @@ -25,9 +32,14 @@ ... .../h .../h +/n +/n [ [/k [/k \ \/i \/i +{ +{/l +{/l diff --git a/tests/gnu/follow_comma.out b/tests/gnu/follow_comma.out index 920b3d3..5e4b806 100644 --- a/tests/gnu/follow_comma.out +++ b/tests/gnu/follow_comma.out @@ -1,4 +1,7 @@ + . +./ +./ ./ ./ /j ./! @@ -11,6 +14,8 @@ ./(/b ./) ./)/g +./* +./*/m ./, ./,/f ./- @@ -21,3 +26,6 @@ ./[/k ./\ ./\/i +./{ +./{/l +/n diff --git a/tests/gnu/fprint_noerror.sh b/tests/gnu/fprint_unreached_error.sh index f13a62b..f13a62b 100644 --- a/tests/gnu/fprint_noerror.sh +++ b/tests/gnu/fprint_unreached_error.sh diff --git a/tests/gnu/ignore_readdir_race_loop.out b/tests/gnu/ignore_readdir_race_loop.out new file mode 100644 index 0000000..a514555 --- /dev/null +++ b/tests/gnu/ignore_readdir_race_loop.out @@ -0,0 +1,11 @@ +loops +loops/broken +loops/deeply +loops/deeply/nested +loops/deeply/nested/dir +loops/file +loops/notdir +loops/skip +loops/skip/dir +loops/skip/loop +loops/symlink diff --git a/tests/gnu/ignore_readdir_race_loop.sh b/tests/gnu/ignore_readdir_race_loop.sh new file mode 100644 index 0000000..3329169 --- /dev/null +++ b/tests/gnu/ignore_readdir_race_loop.sh @@ -0,0 +1,2 @@ +# Make sure -ignore_readdir_race doesn't suppress ELOOP from an actual filesystem loop +! bfs_diff -L loops -ignore_readdir_race diff --git a/tests/gnu/not_comma.out b/tests/gnu/not_comma.out new file mode 100644 index 0000000..b90468e --- /dev/null +++ b/tests/gnu/not_comma.out @@ -0,0 +1,34 @@ +basic +basic +basic/a +basic/a +basic/b +basic/b +basic/c +basic/c +basic/c/d +basic/c/d +basic/e +basic/e +basic/e/f +basic/g +basic/g +basic/g/h +basic/g/h +basic/i +basic/i +basic/j +basic/j +basic/j/foo +basic/k +basic/k +basic/k/foo +basic/k/foo/bar +basic/k/foo/bar +basic/l +basic/l +basic/l/foo +basic/l/foo/bar +basic/l/foo/bar +basic/l/foo/bar/baz +basic/l/foo/bar/baz diff --git a/tests/gnu/not_comma.sh b/tests/gnu/not_comma.sh new file mode 100644 index 0000000..04c0195 --- /dev/null +++ b/tests/gnu/not_comma.sh @@ -0,0 +1,2 @@ +# Regression test: assertion failure in sink_not_comma() +bfs_diff basic -not \( -print , -name '*f*' \) -print diff --git a/tests/gnu/perm_000_slash.out b/tests/gnu/perm_000_slash.out index d7494b8..e279684 100644 --- a/tests/gnu/perm_000_slash.out +++ b/tests/gnu/perm_000_slash.out @@ -1,8 +1,29 @@ perms -perms/0 -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f--------- +perms/f--x------ +perms/f--x--x--x +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/perm_222_slash.out b/tests/gnu/perm_222_slash.out index 9a5b95a..1b6d885 100644 --- a/tests/gnu/perm_222_slash.out +++ b/tests/gnu/perm_222_slash.out @@ -1,5 +1,20 @@ perms -perms/rw -perms/rwx -perms/w -perms/wx +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/perm_644_slash.out b/tests/gnu/perm_644_slash.out index 7e5ae98..eef88ca 100644 --- a/tests/gnu/perm_644_slash.out +++ b/tests/gnu/perm_644_slash.out @@ -1,7 +1,26 @@ perms -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/perm_leading_plus_symbolic_slash.out b/tests/gnu/perm_leading_plus_symbolic_slash.out index 7e5ae98..fcbf49e 100644 --- a/tests/gnu/perm_leading_plus_symbolic_slash.out +++ b/tests/gnu/perm_leading_plus_symbolic_slash.out @@ -1,7 +1,28 @@ perms -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f--x------ +perms/f--x--x--x +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/perm_symbolic_slash.out b/tests/gnu/perm_symbolic_slash.out index 7e5ae98..5a21321 100644 --- a/tests/gnu/perm_symbolic_slash.out +++ b/tests/gnu/perm_symbolic_slash.out @@ -1,7 +1,24 @@ perms -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr--r--r-- +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/readable.out b/tests/gnu/readable.out index 386feba..56d1f52 100644 --- a/tests/gnu/readable.out +++ b/tests/gnu/readable.out @@ -1,5 +1,19 @@ perms -perms/r -perms/rw -perms/rwx -perms/rx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/regextype_awk.out b/tests/gnu/regextype_awk.out new file mode 100644 index 0000000..0f32fc4 --- /dev/null +++ b/tests/gnu/regextype_awk.out @@ -0,0 +1,2 @@ +weirdnames/*/m +weirdnames/[/k diff --git a/tests/gnu/regextype_awk.sh b/tests/gnu/regextype_awk.sh new file mode 100644 index 0000000..3718473 --- /dev/null +++ b/tests/gnu/regextype_awk.sh @@ -0,0 +1,3 @@ +invoke_bfs -regextype awk -quit || skip + +bfs_diff weirdnames -regextype awk -regex '.*/[\[\*]/.*' diff --git a/tests/gnu/regextype_egrep.out b/tests/gnu/regextype_egrep.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/gnu/regextype_egrep.out diff --git a/tests/gnu/regextype_egrep.sh b/tests/gnu/regextype_egrep.sh new file mode 100644 index 0000000..281d9c0 --- /dev/null +++ b/tests/gnu/regextype_egrep.sh @@ -0,0 +1,3 @@ +invoke_bfs -regextype egrep -quit || skip + +bfs_diff weirdnames -regextype egrep -regex '*.*/{l' diff --git a/tests/gnu/regextype_emacs.sh b/tests/gnu/regextype_emacs.sh index 3cc388c..164d17a 100644 --- a/tests/gnu/regextype_emacs.sh +++ b/tests/gnu/regextype_emacs.sh @@ -1,3 +1,3 @@ invoke_bfs -regextype emacs -quit || skip -bfs_diff basic -regextype emacs -regex '.*/\(f+o?o?\|bar\)' +bfs_diff basic -regextype emacs -regex '.*/\(?:f+o?o?\|bar\)' diff --git a/tests/gnu/regextype_findutils_default.out b/tests/gnu/regextype_findutils_default.out new file mode 100644 index 0000000..709a7ba --- /dev/null +++ b/tests/gnu/regextype_findutils_default.out @@ -0,0 +1,3 @@ +/n +weirdnames/ +weirdnames/*/m diff --git a/tests/gnu/regextype_findutils_default.sh b/tests/gnu/regextype_findutils_default.sh new file mode 100644 index 0000000..c870312 --- /dev/null +++ b/tests/gnu/regextype_findutils_default.sh @@ -0,0 +1,3 @@ +invoke_bfs -regextype findutils-default -quit || skip + +bfs_diff weirdnames -regextype findutils-default -regex '.*/./\(m\|n\)' diff --git a/tests/gnu/regextype_gnu_awk.out b/tests/gnu/regextype_gnu_awk.out new file mode 100644 index 0000000..0f32fc4 --- /dev/null +++ b/tests/gnu/regextype_gnu_awk.out @@ -0,0 +1,2 @@ +weirdnames/*/m +weirdnames/[/k diff --git a/tests/gnu/regextype_gnu_awk.sh b/tests/gnu/regextype_gnu_awk.sh new file mode 100644 index 0000000..6b66496 --- /dev/null +++ b/tests/gnu/regextype_gnu_awk.sh @@ -0,0 +1,3 @@ +invoke_bfs -regextype gnu-awk -quit || skip + +bfs_diff weirdnames -regextype gnu-awk -regex '.*/[\[\*]/(\<.\>)' diff --git a/tests/gnu/regextype_posix_awk.out b/tests/gnu/regextype_posix_awk.out new file mode 100644 index 0000000..0f32fc4 --- /dev/null +++ b/tests/gnu/regextype_posix_awk.out @@ -0,0 +1,2 @@ +weirdnames/*/m +weirdnames/[/k diff --git a/tests/gnu/regextype_posix_awk.sh b/tests/gnu/regextype_posix_awk.sh new file mode 100644 index 0000000..86377d7 --- /dev/null +++ b/tests/gnu/regextype_posix_awk.sh @@ -0,0 +1,3 @@ +invoke_bfs -regextype posix-awk -quit || skip + +bfs_diff weirdnames -regextype posix-awk -regex '.*/[\[\*]/.*' diff --git a/tests/gnu/regextype_posix_minimal_basic.out b/tests/gnu/regextype_posix_minimal_basic.out new file mode 100644 index 0000000..0f0971e --- /dev/null +++ b/tests/gnu/regextype_posix_minimal_basic.out @@ -0,0 +1 @@ +./( diff --git a/tests/gnu/regextype_posix_minimal_basic.sh b/tests/gnu/regextype_posix_minimal_basic.sh new file mode 100644 index 0000000..ee324f3 --- /dev/null +++ b/tests/gnu/regextype_posix_minimal_basic.sh @@ -0,0 +1,2 @@ +cd weirdnames +bfs_diff -regextype posix-minimal-basic -regex '\./\((\)' diff --git a/tests/gnu/used.sh b/tests/gnu/used.sh index 5e5d4e9..fe0a778 100644 --- a/tests/gnu/used.sh +++ b/tests/gnu/used.sh @@ -1,37 +1,18 @@ -iso8601() { - printf '%04d-%02d-%02dT%02d:%02d:%02d\n' "$@" -} - cd "$TEST" -now=$(date '+%Y-%m-%dT%H:%M:%S') - -# Parse the current date -[[ "$now" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})$ ]] || fail -# Treat leading zeros as decimal, not octal -YYYY=$((10#${BASH_REMATCH[1]})) -MM=$((10#${BASH_REMATCH[2]})) -DD=$((10#${BASH_REMATCH[3]})) -hh=$((10#${BASH_REMATCH[4]})) -mm=$((10#${BASH_REMATCH[5]})) -ss=$((10#${BASH_REMATCH[6]})) +now=$(epoch_time) # -used is always false if atime < ctime -yesterday=$(iso8601 $YYYY $MM $((DD - 1)) $hh $mm $ss) -"$XTOUCH" -at "$yesterday" yesterday +"$XTOUCH" -at "@$((now - 60 * 60 * 24))" yesterday # -used rounds up -tomorrow=$(iso8601 $YYYY $MM $DD $((hh + 1)) $mm $ss) -"$XTOUCH" -at "$tomorrow" tomorrow +"$XTOUCH" -at "@$((now + 60 * 60))" tomorrow -dayafter=$(iso8601 $YYYY $MM $((DD + 1)) $((hh + 1)) $mm $ss) -"$XTOUCH" -at "$dayafter" dayafter +"$XTOUCH" -at "@$((now + 60 * 60 * 25))" dayafter -nextweek=$(iso8601 $YYYY $MM $((DD + 6)) $((hh + 1)) $mm $ss) -"$XTOUCH" -at "$nextweek" nextweek +"$XTOUCH" -at "@$((now + 60 * 60 * (24 * 6 + 1)))" nextweek -nextyear=$(iso8601 $((YYYY + 1)) $MM $DD $hh $mm $ss) -"$XTOUCH" -at "$nextyear" nextyear +"$XTOUCH" -at "@$((now + 60 * 60 * 24 * 365))" nextyear bfs_diff -mindepth 1 \ -a -used 1 -printf '-used 1: %p\n' \ diff --git a/tests/gnu/writable.out b/tests/gnu/writable.out index 9a5b95a..1b6d885 100644 --- a/tests/gnu/writable.out +++ b/tests/gnu/writable.out @@ -1,5 +1,20 @@ perms -perms/rw -perms/rwx -perms/w -perms/wx +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/gnu/xtype_l_loops.out b/tests/gnu/xtype_l_loops.out new file mode 100644 index 0000000..fdaccab --- /dev/null +++ b/tests/gnu/xtype_l_loops.out @@ -0,0 +1,3 @@ +loops/broken +loops/loop +loops/notdir diff --git a/tests/gnu/xtype_l_loops.sh b/tests/gnu/xtype_l_loops.sh new file mode 100644 index 0000000..6893134 --- /dev/null +++ b/tests/gnu/xtype_l_loops.sh @@ -0,0 +1 @@ +bfs_diff loops -xtype l diff --git a/tests/ioq.c b/tests/ioq.c index 99c98a2..f067436 100644 --- a/tests/ioq.c +++ b/tests/ioq.c @@ -1,13 +1,12 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" -#include "ioq.h" -#include "bfstd.h" + #include "diag.h" #include "dir.h" -#include <errno.h> +#include "ioq.h" + #include <fcntl.h> #include <stdlib.h> @@ -71,7 +70,6 @@ static void check_ioq_push_block(void) { ioq_destroy(ioq); } -bool check_ioq(void) { +void check_ioq(void) { check_ioq_push_block(); - return true; } diff --git a/tests/list.c b/tests/list.c new file mode 100644 index 0000000..5d0403f --- /dev/null +++ b/tests/list.c @@ -0,0 +1,99 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +#include "tests.h" + +#include "bfs.h" +#include "diag.h" +#include "list.h" + +#include <stddef.h> + +struct item { + int n; + struct item *next; +}; + +struct list { + struct item *head; + struct item **tail; +}; + +static bool check_list_items(struct list *list, int *array, size_t size) { + struct item **cur = &list->head; + for (size_t i = 0; i < size; ++i) { + if (!bfs_check(*cur != NULL)) { + return false; + } + int n = (*cur)->n; + if (!bfs_check(n == array[i], "%d != %d", n, array[i])) { + return false; + } + cur = &(*cur)->next; + } + + if (!bfs_check(*cur == NULL)) { + return false; + } + if (!bfs_check(list->tail == cur)) { + return false; + } + + return true; +} + +#define ARRAY(...) (int[]){ __VA_ARGS__ }, countof((int[]){ __VA_ARGS__ }) +#define EMPTY() NULL, 0 + +void check_list(void) { + struct list l1; + SLIST_INIT(&l1); + bfs_verify(check_list_items(&l1, EMPTY())); + + struct list l2; + SLIST_INIT(&l2); + bfs_verify(check_list_items(&l2, EMPTY())); + + SLIST_EXTEND(&l1, &l2); + bfs_verify(check_list_items(&l1, EMPTY())); + + struct item i10 = { .n = 10 }; + SLIST_APPEND(&l1, &i10); + bfs_verify(check_list_items(&l1, ARRAY(10))); + + SLIST_EXTEND(&l1, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10))); + + SLIST_SPLICE(&l1, &l1.head, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10))); + + struct item i20 = { .n = 20 }; + SLIST_PREPEND(&l2, &i20); + bfs_verify(check_list_items(&l2, ARRAY(20))); + + SLIST_EXTEND(&l1, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10, 20))); + bfs_verify(check_list_items(&l2, EMPTY())); + + struct item i15 = { .n = 15 }; + SLIST_APPEND(&l2, &i15); + SLIST_SPLICE(&l1, &i10.next, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10, 15, 20))); + bfs_verify(check_list_items(&l2, EMPTY())); + + SLIST_EXTEND(&l1, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10, 15, 20))); + + SLIST_SPLICE(&l1, &i10.next, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10, 15, 20))); + + SLIST_SPLICE(&l1, &l1.head, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10, 15, 20))); + + struct item i11 = { .n = 11 }; + struct item i12 = { .n = 12 }; + SLIST_APPEND(&l2, &i11); + SLIST_APPEND(&l2, &i12); + SLIST_SPLICE(&l1, &l1.head->next, &l2); + bfs_verify(check_list_items(&l1, ARRAY(10, 11, 12, 15, 20))); +} diff --git a/tests/main.c b/tests/main.c index aef0583..81c2311 100644 --- a/tests/main.c +++ b/tests/main.c @@ -5,18 +5,29 @@ * Entry point for unit tests. */ -#include "prelude.h" #include "tests.h" -#include "bfstd.h" + #include "color.h" + #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> +/** Result of the current test. */ +static thread_local bool pass; + +bool bfs_check_impl(bool result) { + pass &= result; + return result; +} + +/** Unit test function type. */ +typedef void test_fn(void); + /** - * Test context. + * Global test context. */ struct test_ctx { /** Number of command line arguments. */ @@ -80,7 +91,10 @@ static bool should_run(const struct test_ctx *ctx, const char *test) { /** Run a test if it's enabled. */ static void run_test(struct test_ctx *ctx, const char *test, test_fn *fn) { if (should_run(ctx, test)) { - if (fn()) { + pass = true; + fn(); + + if (pass) { cfprintf(ctx->cout, "${grn}[PASS]${rs} ${bld}%s${rs}\n", test); } else { cfprintf(ctx->cout, "${red}[FAIL]${rs} ${bld}%s${rs}\n", test); @@ -111,6 +125,7 @@ int main(int argc, char *argv[]) { run_test(&ctx, "bfstd", check_bfstd); run_test(&ctx, "bit", check_bit); run_test(&ctx, "ioq", check_ioq); + run_test(&ctx, "list", check_list); run_test(&ctx, "sighook", check_sighook); run_test(&ctx, "trie", check_trie); run_test(&ctx, "xspawn", check_xspawn); diff --git a/tests/mksock.c b/tests/mksock.c index 5786cb6..f46df96 100644 --- a/tests/mksock.c +++ b/tests/mksock.c @@ -7,6 +7,7 @@ */ #include "bfstd.h" + #include <errno.h> #include <stdio.h> #include <stdlib.h> diff --git a/tests/posix/HL.out b/tests/posix/HL.out new file mode 100644 index 0000000..ec9e861 --- /dev/null +++ b/tests/posix/HL.out @@ -0,0 +1,17 @@ +links +links/broken +links/deeply +links/deeply/nested +links/deeply/nested/broken +links/deeply/nested/dir +links/deeply/nested/file +links/deeply/nested/link +links/file +links/hardlink +links/notdir +links/skip +links/skip/broken +links/skip/dir +links/skip/file +links/skip/link +links/symlink diff --git a/tests/posix/HL.sh b/tests/posix/HL.sh new file mode 100644 index 0000000..1858982 --- /dev/null +++ b/tests/posix/HL.sh @@ -0,0 +1 @@ +bfs_diff -HL links diff --git a/tests/posix/LH.out b/tests/posix/LH.out new file mode 100644 index 0000000..ff635ff --- /dev/null +++ b/tests/posix/LH.out @@ -0,0 +1 @@ +links/deeply/nested/dir diff --git a/tests/posix/LH.sh b/tests/posix/LH.sh new file mode 100644 index 0000000..ef1d980 --- /dev/null +++ b/tests/posix/LH.sh @@ -0,0 +1 @@ +bfs_diff -LH links/deeply/nested/dir diff --git a/tests/posix/L_mount.out b/tests/posix/L_mount.out new file mode 100644 index 0000000..7ed5f0d --- /dev/null +++ b/tests/posix/L_mount.out @@ -0,0 +1,2 @@ +. +./foo diff --git a/tests/common/L_mount.sh b/tests/posix/L_mount.sh index fd8042a..fd8042a 100644 --- a/tests/common/L_mount.sh +++ b/tests/posix/L_mount.sh diff --git a/tests/posix/atime.out b/tests/posix/atime.out new file mode 100644 index 0000000..5ed206b --- /dev/null +++ b/tests/posix/atime.out @@ -0,0 +1,6 @@ +-atime 1: ./yesterday +-atime +1: ./last_week +-atime +1: ./two_days_ago +-atime -1: ./now +-atime -1: ./one_hour_ago +-atime -1: ./tomorrow diff --git a/tests/posix/atime.sh b/tests/posix/atime.sh new file mode 100644 index 0000000..25dfd7e --- /dev/null +++ b/tests/posix/atime.sh @@ -0,0 +1,15 @@ +cd "$TEST" + +now=$(epoch_time) + +"$XTOUCH" -at "@$((now - 60 * 60 * 24 * 7))" last_week +"$XTOUCH" -at "@$((now - 60 * 60 * 49))" two_days_ago +"$XTOUCH" -at "@$((now - 60 * 60 * 25))" yesterday +"$XTOUCH" -at "@$((now - 60 * 60))" one_hour_ago +"$XTOUCH" -at "@$((now))" now +"$XTOUCH" -at "@$((now + 60 * 60 * 24))" tomorrow + +bfs_diff . \! -name . \ + \( -atime -1 -exec printf -- '-atime -1: %s\n' {} \; -o -prune \) \ + \( -atime 1 -exec printf -- '-atime 1: %s\n' {} \; -o -prune \) \ + \( -atime +1 -exec printf -- '-atime +1: %s\n' {} \; -o -prune \) diff --git a/tests/posix/depth_error.out b/tests/posix/depth_error.out index 7ed5f0d..c4f8ce4 100644 --- a/tests/posix/depth_error.out +++ b/tests/posix/depth_error.out @@ -1,2 +1,4 @@ -. -./foo +inaccessible +inaccessible/dir +inaccessible/file +inaccessible/link diff --git a/tests/posix/depth_error.sh b/tests/posix/depth_error.sh index db414ba..9b29385 100644 --- a/tests/posix/depth_error.sh +++ b/tests/posix/depth_error.sh @@ -1,7 +1 @@ -cd "$TEST" -"$XTOUCH" -p foo/bar - -chmod a-r foo -defer chmod +r foo - -! bfs_diff . -depth +! bfs_diff inaccessible -depth diff --git a/tests/posix/group_invalid_id.sh b/tests/posix/group_invalid_id.sh new file mode 100644 index 0000000..1a89747 --- /dev/null +++ b/tests/posix/group_invalid_id.sh @@ -0,0 +1 @@ +! invoke_bfs -group 1eW6f5RM9Qi diff --git a/tests/posix/group_invalid_name.sh b/tests/posix/group_invalid_name.sh new file mode 100644 index 0000000..a08dc72 --- /dev/null +++ b/tests/posix/group_invalid_name.sh @@ -0,0 +1 @@ +! invoke_bfs -group eW6f5RM9Qi diff --git a/tests/common/iname.out b/tests/posix/iname.out index a9e5d42..a9e5d42 100644 --- a/tests/common/iname.out +++ b/tests/posix/iname.out diff --git a/tests/posix/iname.sh b/tests/posix/iname.sh new file mode 100644 index 0000000..a9297ac --- /dev/null +++ b/tests/posix/iname.sh @@ -0,0 +1 @@ +bfs_diff basic -iname '*F*' diff --git a/tests/common/mount.out b/tests/posix/mount.out index 6253434..b0ad937 100644 --- a/tests/common/mount.out +++ b/tests/posix/mount.out @@ -1,4 +1,3 @@ . ./foo ./foo/bar -./mnt diff --git a/tests/common/mount.sh b/tests/posix/mount.sh index c9abde5..c9abde5 100644 --- a/tests/common/mount.sh +++ b/tests/posix/mount.sh diff --git a/tests/posix/mtime.out b/tests/posix/mtime.out new file mode 100644 index 0000000..91f0114 --- /dev/null +++ b/tests/posix/mtime.out @@ -0,0 +1,6 @@ +-mtime 1: ./yesterday +-mtime +1: ./last_week +-mtime +1: ./two_days_ago +-mtime -1: ./now +-mtime -1: ./one_hour_ago +-mtime -1: ./tomorrow diff --git a/tests/posix/mtime.sh b/tests/posix/mtime.sh new file mode 100644 index 0000000..8367631 --- /dev/null +++ b/tests/posix/mtime.sh @@ -0,0 +1,15 @@ +cd "$TEST" + +now=$(epoch_time) + +"$XTOUCH" -mt "@$((now - 60 * 60 * 24 * 7))" last_week +"$XTOUCH" -mt "@$((now - 60 * 60 * 49))" two_days_ago +"$XTOUCH" -mt "@$((now - 60 * 60 * 25))" yesterday +"$XTOUCH" -mt "@$((now - 60 * 60))" one_hour_ago +"$XTOUCH" -mt "@$((now))" now +"$XTOUCH" -mt "@$((now + 60 * 60 * 24))" tomorrow + +bfs_diff . \! -name . \ + \( -mtime -1 -exec printf -- '-mtime -1: %s\n' {} \; -o -prune \) \ + \( -mtime 1 -exec printf -- '-mtime 1: %s\n' {} \; -o -prune \) \ + \( -mtime +1 -exec printf -- '-mtime +1: %s\n' {} \; -o -prune \) diff --git a/tests/common/name_slash.out b/tests/posix/name_slash.out index b498fd4..b498fd4 100644 --- a/tests/common/name_slash.out +++ b/tests/posix/name_slash.out diff --git a/tests/posix/name_slash.sh b/tests/posix/name_slash.sh new file mode 100644 index 0000000..b42b145 --- /dev/null +++ b/tests/posix/name_slash.sh @@ -0,0 +1 @@ +bfs_diff / -prune -name / diff --git a/tests/common/name_slashes.out b/tests/posix/name_slashes.out index 187b81f..187b81f 100644 --- a/tests/common/name_slashes.out +++ b/tests/posix/name_slashes.out diff --git a/tests/posix/name_slashes.sh b/tests/posix/name_slashes.sh new file mode 100644 index 0000000..45a39d3 --- /dev/null +++ b/tests/posix/name_slashes.sh @@ -0,0 +1 @@ +bfs_diff /// -prune -name / diff --git a/tests/posix/perm_000.out b/tests/posix/perm_000.out index 5fd30bc..9df7f46 100644 --- a/tests/posix/perm_000.out +++ b/tests/posix/perm_000.out @@ -1 +1 @@ -perms/0 +perms/f--------- diff --git a/tests/posix/perm_000_minus.out b/tests/posix/perm_000_minus.out index d7494b8..e279684 100644 --- a/tests/posix/perm_000_minus.out +++ b/tests/posix/perm_000_minus.out @@ -1,8 +1,29 @@ perms -perms/0 -perms/r -perms/rw -perms/rwx -perms/rx -perms/w -perms/wx +perms/dr-x------ +perms/dr-xr-xr-x +perms/drwx------ +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f--------- +perms/f--x------ +perms/f--x--x--x +perms/f-w------- +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx------ +perms/f-wx--x--x +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/fr-------- +perms/fr--r--r-- +perms/fr-x------ +perms/fr-xr-xr-x +perms/frw------- +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr----- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/posix/perm_222.out b/tests/posix/perm_222.out index 1690e43..bdc5590 100644 --- a/tests/posix/perm_222.out +++ b/tests/posix/perm_222.out @@ -1 +1 @@ -perms/w +perms/f-w--w--w- diff --git a/tests/posix/perm_222_minus.out b/tests/posix/perm_222_minus.out index 1690e43..342b285 100644 --- a/tests/posix/perm_222_minus.out +++ b/tests/posix/perm_222_minus.out @@ -1 +1,5 @@ -perms/w +perms/drwxrwxrwx +perms/f-w--w--w- +perms/f-wx-wx-wx +perms/frw-rw-rw- +perms/frwxrwxrwx diff --git a/tests/posix/perm_644.out b/tests/posix/perm_644.out index 4e64e49..9f77ce6 100644 --- a/tests/posix/perm_644.out +++ b/tests/posix/perm_644.out @@ -1 +1 @@ -perms/rw +perms/frw-r--r-- diff --git a/tests/posix/perm_644_minus.out b/tests/posix/perm_644_minus.out index 2e2576b..84f69f5 100644 --- a/tests/posix/perm_644_minus.out +++ b/tests/posix/perm_644_minus.out @@ -1,3 +1,10 @@ perms -perms/rw -perms/rwx +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/posix/perm_leading_plus_symbolic_minus.out b/tests/posix/perm_leading_plus_symbolic_minus.out index e69de29..38d0e1c 100644 --- a/tests/posix/perm_leading_plus_symbolic_minus.out +++ b/tests/posix/perm_leading_plus_symbolic_minus.out @@ -0,0 +1,7 @@ +perms +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/posix/perm_leading_plus_umask.out b/tests/posix/perm_leading_plus_umask.out new file mode 100644 index 0000000..6ed4b7f --- /dev/null +++ b/tests/posix/perm_leading_plus_umask.out @@ -0,0 +1,10 @@ +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/f-w--w---- +perms/f-w--w--w- +perms/f-wx-wx--x +perms/f-wx-wx-wx +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/posix/perm_leading_plus_umask.sh b/tests/posix/perm_leading_plus_umask.sh new file mode 100644 index 0000000..948b4ad --- /dev/null +++ b/tests/posix/perm_leading_plus_umask.sh @@ -0,0 +1,3 @@ +# Test for https://www.austingroupbugs.net/view.php?id=1392 +umask 002 +bfs_diff perms -perm -+w diff --git a/tests/posix/perm_symbolic_minus.out b/tests/posix/perm_symbolic_minus.out index 2e2576b..84f69f5 100644 --- a/tests/posix/perm_symbolic_minus.out +++ b/tests/posix/perm_symbolic_minus.out @@ -1,3 +1,10 @@ perms -perms/rw -perms/rwx +perms/drwxr-xr-x +perms/drwxrwxr-x +perms/drwxrwxrwx +perms/frw-r--r-- +perms/frw-rw-r-- +perms/frw-rw-rw- +perms/frwxr-xr-x +perms/frwxrwxr-x +perms/frwxrwxrwx diff --git a/tests/posix/permcopy.out b/tests/posix/permcopy.out index 4e64e49..9f77ce6 100644 --- a/tests/posix/permcopy.out +++ b/tests/posix/permcopy.out @@ -1 +1 @@ -perms/rw +perms/frw-r--r-- diff --git a/tests/gnu/print0.out b/tests/posix/print0.out Binary files differindex 1347444..1347444 100644 --- a/tests/gnu/print0.out +++ b/tests/posix/print0.out diff --git a/tests/gnu/print0.sh b/tests/posix/print0.sh index b916172..b916172 100644 --- a/tests/gnu/print0.sh +++ b/tests/posix/print0.sh diff --git a/tests/posix/prune_error.out b/tests/posix/prune_error.out new file mode 100644 index 0000000..436c48e --- /dev/null +++ b/tests/posix/prune_error.out @@ -0,0 +1 @@ +inaccessible diff --git a/tests/posix/prune_error.sh b/tests/posix/prune_error.sh new file mode 100644 index 0000000..07a2523 --- /dev/null +++ b/tests/posix/prune_error.sh @@ -0,0 +1 @@ +! bfs_diff -L inaccessible -path '*/*' -prune -o -print diff --git a/tests/posix/user_invalid_id.sh b/tests/posix/user_invalid_id.sh new file mode 100644 index 0000000..c378f7e --- /dev/null +++ b/tests/posix/user_invalid_id.sh @@ -0,0 +1 @@ +! invoke_bfs -user 1eW6f5RM9Qi diff --git a/tests/posix/user_invalid_name.sh b/tests/posix/user_invalid_name.sh new file mode 100644 index 0000000..bbf3031 --- /dev/null +++ b/tests/posix/user_invalid_name.sh @@ -0,0 +1 @@ +! invoke_bfs -user eW6f5RM9Qi diff --git a/tests/run.sh b/tests/run.sh index 381b03e..612e11a 100644 --- a/tests/run.sh +++ b/tests/run.sh @@ -94,9 +94,10 @@ reap_test() { # Wait for a background test to finish wait_test() { - local pid + local pid line ret while true; do + line=$((LINENO + 1)) wait -n -ppid ret=$? @@ -106,7 +107,7 @@ wait_test() { # Interrupted by signal continue else - debug "${BASH_SOURCE[0]}" $((LINENO - 3)) "${RED}error $ret${RST}" >&$DUPERR + debug "${BASH_SOURCE[0]}" $line "${RED}error $ret${RST}" >&$DUPERR exit 1 fi done @@ -120,7 +121,9 @@ wait_ready() { # We'd like to parse the output of jobs -n, but we can't run it in a # subshell or we won't get the right output jobs -n >"$TMP/jobs" - while read -r job status ret foo; do + + local job status ret rest + while read -r job status ret rest; do case "$status" in Done) reap_test 0 @@ -410,14 +413,20 @@ make_xattrs() { esac } +# Get the Unix epoch time in seconds +epoch_time() { + # https://stackoverflow.com/a/12746260/502399 + awk 'BEGIN { srand(); print srand(); }' +} + ## Snapshot testing # Return value when a difference is detected EX_DIFF=20 # Detect colored diff support -if diff --color /dev/null /dev/null &>/dev/null; then - DIFF="diff --color" +if ((COLOR_STDERR)) && diff --color=always /dev/null /dev/null &>/dev/null; then + DIFF="diff --color=always" else DIFF="diff" fi diff --git a/tests/sighook.c b/tests/sighook.c index c94526e..aa01c36 100644 --- a/tests/sighook.c +++ b/tests/sighook.c @@ -1,97 +1,112 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" -#include "sighook.h" + #include "atomic.h" #include "thread.h" +#include "sighook.h" + +#include <stddef.h> +#include <errno.h> #include <pthread.h> #include <signal.h> #include <sys/time.h> +/** Counts SIGALRM deliveries. */ static atomic size_t count = 0; +/** Keeps the background thread alive. */ +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static bool done = false; + /** SIGALRM handler. */ static void alrm_hook(int sig, siginfo_t *info, void *arg) { fetch_add(&count, 1, relaxed); } -/** Swap out an old hook for a new hook. */ -static int swap_hooks(struct sighook **hook) { - struct sighook *next = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); - if (!bfs_echeck(next, "sighook(SIGALRM)")) { - return -1; +/** Background thread that receives signals. */ +static void *hook_thread(void *ptr) { + mutex_lock(&mutex); + while (!done) { + cond_wait(&cond, &mutex); } - - sigunhook(*hook); - *hook = next; - return 0; + mutex_unlock(&mutex); + return NULL; } -/** Background thread that rapidly (un)registers signal hooks. */ -static void *hook_thread(void *ptr) { - struct sighook *hook = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); - if (!bfs_echeck(hook, "sighook(SIGALRM)")) { - return NULL; +/** Block a signal in this thread. */ +static int block_signal(int sig, sigset_t *old) { + sigset_t set; + if (sigemptyset(&set) != 0) { + return -1; + } + if (sigaddset(&set, sig) != 0) { + return -1; } - while (load(&count, relaxed) < 1000) { - if (swap_hooks(&hook) != 0) { - sigunhook(hook); - return NULL; - } + errno = pthread_sigmask(SIG_BLOCK, &set, old); + if (errno != 0) { + return -1; } - sigunhook(hook); - return &count; + return 0; } -bool check_sighook(void) { - bool ret = true; - +void check_sighook(void) { struct sighook *hook = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); - ret &= bfs_echeck(hook, "sighook(SIGALRM)"); - if (!ret) { - goto done; + if (!bfs_echeck(hook, "sighook(SIGALRM)")) { + return; } - struct itimerval ival = { - .it_value = { - .tv_usec = 100, - }, - .it_interval = { - .tv_usec = 100, - }, - }; - ret &= bfs_echeck(setitimer(ITIMER_REAL, &ival, NULL) == 0); - if (!ret) { + // Create a timer that sends SIGALRM every 100 microseconds + struct itimerval ival = {0}; + ival.it_value.tv_usec = 100; + ival.it_interval.tv_usec = 100; + if (!bfs_echeck(setitimer(ITIMER_REAL, &ival, NULL) == 0)) { goto unhook; } + // Create a background thread to receive signals pthread_t thread; - ret &= bfs_echeck(thread_create(&thread, NULL, hook_thread, NULL) == 0); - if (!ret) { + if (!bfs_echeck(thread_create(&thread, NULL, hook_thread, NULL) == 0)) { goto untime; } - while (ret && load(&count, relaxed) < 1000) { - ret &= swap_hooks(&hook) == 0; + // Block SIGALRM in this thread so the handler runs concurrently with + // sighook()/sigunhook() + sigset_t mask; + if (!bfs_echeck(block_signal(SIGALRM, &mask) == 0)) { + goto untime; } - void *ptr; - thread_join(thread, &ptr); - ret &= bfs_check(ptr); + // Rapidly register/unregister SIGALRM hooks + while (load(&count, relaxed) < 1000) { + struct sighook *next = sighook(SIGALRM, alrm_hook, NULL, SH_CONTINUE); + if (!bfs_echeck(next, "sighook(SIGALRM)")) { + break; + } -untime: - ival.it_value.tv_usec = 0; - ret &= bfs_echeck(setitimer(ITIMER_REAL, &ival, NULL) == 0); - if (!ret) { - goto unhook; + sigunhook(hook); + hook = next; } + // Quit the background thread + mutex_lock(&mutex); + done = true; + mutex_unlock(&mutex); + cond_signal(&cond); + thread_join(thread, NULL); + + // Restore the old signal mask + errno = pthread_sigmask(SIG_SETMASK, &mask, NULL); + bfs_echeck(errno == 0, "pthread_sigmask()"); +untime: + // Stop the timer + ival.it_value.tv_usec = 0; + bfs_echeck(setitimer(ITIMER_REAL, &ival, NULL) == 0); unhook: + // Unregister the SIGALRM hook sigunhook(hook); -done: - return ret; } diff --git a/tests/stddirs.sh b/tests/stddirs.sh index e08e6bf..1183970 100644 --- a/tests/stddirs.sh +++ b/tests/stddirs.sh @@ -14,13 +14,31 @@ make_basic() { # Creates a file+directory structure with various permissions for tests make_perms() { - "$XTOUCH" -p -M000 "$1/0" - "$XTOUCH" -p -M444 "$1/r" - "$XTOUCH" -p -M222 "$1/w" - "$XTOUCH" -p -M644 "$1/rw" - "$XTOUCH" -p -M555 "$1/rx" - "$XTOUCH" -p -M311 "$1/wx" - "$XTOUCH" -p -M755 "$1/rwx" + "$XTOUCH" -p -M000 "$1/f---------" + "$XTOUCH" -p -M111 "$1/f--x--x--x" + "$XTOUCH" -p -M222 "$1/f-w--w--w-" + "$XTOUCH" -p -M333 "$1/f-wx-wx-wx" + "$XTOUCH" -p -M444 "$1/fr--r--r--" + "$XTOUCH" -p -M555 "$1/fr-xr-xr-x" "$1/dr-xr-xr-x/" + "$XTOUCH" -p -M666 "$1/frw-rw-rw-" + "$XTOUCH" -p -M777 "$1/frwxrwxrwx" "$1/drwxrwxrwx/" + + "$XTOUCH" -p -M220 "$1/f-w--w----" + "$XTOUCH" -p -M331 "$1/f-wx-wx--x" + "$XTOUCH" -p -M664 "$1/frw-rw-r--" + "$XTOUCH" -p -M775 "$1/frwxrwxr-x" "$1/drwxrwxr-x/" + + "$XTOUCH" -p -M311 "$1/f-wx--x--x" + "$XTOUCH" -p -M644 "$1/frw-r--r--" + "$XTOUCH" -p -M755 "$1/frwxr-xr-x" "$1/drwxr-xr-x/" + + "$XTOUCH" -p -M100 "$1/f--x------" + "$XTOUCH" -p -M200 "$1/f-w-------" + "$XTOUCH" -p -M300 "$1/f-wx------" + "$XTOUCH" -p -M400 "$1/fr--------" + "$XTOUCH" -p -M500 "$1/fr-x------" "$1/dr-x------/" + "$XTOUCH" -p -M600 "$1/frw-------" + "$XTOUCH" -p -M700 "$1/frwxr-----" "$1/drwx------/" } # Creates a file+directory structure with various symbolic and hard links @@ -48,6 +66,12 @@ make_loops() { ln -s deeply/nested/loop/nested "$1/skip" } +# Creates a file+directory structure with inaccessible files +make_inaccessible() { + "$XTOUCH" -p -M000 "$1/file" "$1/dir/" + ln -s dir/file "$1/link" +} + # Creates a file+directory structure with varying timestamps make_times() { "$XTOUCH" -p -t "1991-12-14 00:00" "$1/a" @@ -71,6 +95,9 @@ make_weirdnames() { "$XTOUCH" -p "$1/\\/i" "$XTOUCH" -p "$1/ /j" "$XTOUCH" -p "$1/[/k" + "$XTOUCH" -p "$1/{/l" + "$XTOUCH" -p "$1/*/m" + "$XTOUCH" -p "$1/"$'\n/n' } # Creates a very deep directory structure for testing PATH_MAX handling @@ -133,6 +160,7 @@ make_stddirs() { make_perms "$TMP/perms" make_links "$TMP/links" make_loops "$TMP/loops" + make_inaccessible "$TMP/inaccessible" make_times "$TMP/times" make_weirdnames "$TMP/weirdnames" make_deep "$TMP/deep" @@ -148,5 +176,6 @@ clean_stddirs() { fi done + chmod -R +rwX "$TMP" rm -rf "$TMP" } diff --git a/tests/tests.h b/tests/tests.h index de95a49..4c6b3d2 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -8,48 +8,44 @@ #ifndef BFS_TESTS_H #define BFS_TESTS_H -#include "prelude.h" #include "bfstd.h" #include "diag.h" -/** Unit test function type. */ -typedef bool test_fn(void); - /** Memory allocation tests. */ -bool check_alloc(void); +void check_alloc(void); /** Standard library wrapper tests. */ -bool check_bfstd(void); +void check_bfstd(void); /** Bit manipulation tests. */ -bool check_bit(void); +void check_bit(void); /** I/O queue tests. */ -bool check_ioq(void); +void check_ioq(void); + +/** Linked list tests. */ +void check_list(void); /** Signal hook tests. */ -bool check_sighook(void); +void check_sighook(void); /** Trie tests. */ -bool check_trie(void); +void check_trie(void); /** Process spawning tests. */ -bool check_xspawn(void); +void check_xspawn(void); /** Time tests. */ -bool check_xtime(void); +void check_xtime(void); -/** Don't ignore the bfs_check() return value. */ -attr(nodiscard) -static inline bool bfs_check(bool ret) { - return ret; -} +/** Record a single check and return the result. */ +bool bfs_check_impl(bool result); /** * Check a condition, logging a message on failure but continuing. */ #define bfs_check(...) \ - bfs_check(bfs_check_(#__VA_ARGS__, __VA_ARGS__, "", "")) + bfs_check_impl(bfs_check_(#__VA_ARGS__, __VA_ARGS__, "", "")) #define bfs_check_(str, cond, format, ...) \ ((cond) ? true : (bfs_diag( \ @@ -62,7 +58,7 @@ static inline bool bfs_check(bool ret) { * Check a condition, logging the current error string on failure. */ #define bfs_echeck(...) \ - bfs_echeck_(#__VA_ARGS__, __VA_ARGS__, "", errstr()) + bfs_check_impl(bfs_echeck_(#__VA_ARGS__, __VA_ARGS__, "", errstr())) #define bfs_echeck_(str, cond, format, ...) \ ((cond) ? true : (bfs_diag( \ diff --git a/tests/trie.c b/tests/trie.c index 4667322..9e9a294 100644 --- a/tests/trie.c +++ b/tests/trie.c @@ -1,14 +1,16 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" -#include "trie.h" + +#include "bfs.h" #include "diag.h" +#include "trie.h" + #include <stdlib.h> #include <string.h> -const char *keys[] = { +static const char *keys[] = { "foo", "bar", "baz", @@ -37,16 +39,14 @@ const char *keys[] = { ">>>", }; -const size_t nkeys = countof(keys); - -bool check_trie(void) { - bool ret = true; +static const size_t nkeys = countof(keys); +void check_trie(void) { struct trie trie; trie_init(&trie); for (size_t i = 0; i < nkeys; ++i) { - ret &= bfs_check(!trie_find_str(&trie, keys[i])); + bfs_check(!trie_find_str(&trie, keys[i])); const char *prefix = NULL; for (size_t j = 0; j < i; ++j) { @@ -60,37 +60,37 @@ bool check_trie(void) { struct trie_leaf *leaf = trie_find_prefix(&trie, keys[i]); if (prefix) { bfs_verify(leaf); - ret &= bfs_check(strcmp(prefix, leaf->key) == 0); + bfs_check(strcmp(prefix, leaf->key) == 0); } else { - ret &= bfs_check(!leaf); + bfs_check(!leaf); } leaf = trie_insert_str(&trie, keys[i]); bfs_verify(leaf); - ret &= bfs_check(strcmp(keys[i], leaf->key) == 0); - ret &= bfs_check(leaf->length == strlen(keys[i]) + 1); + bfs_check(strcmp(keys[i], leaf->key) == 0); + bfs_check(leaf->length == strlen(keys[i]) + 1); } { size_t i = 0; for_trie (leaf, &trie) { - ret &= bfs_check(leaf == trie_find_str(&trie, keys[i])); - ret &= bfs_check(!leaf->prev || leaf->prev->next == leaf); - ret &= bfs_check(!leaf->next || leaf->next->prev == leaf); + bfs_check(leaf == trie_find_str(&trie, keys[i])); + bfs_check(!leaf->prev || leaf->prev->next == leaf); + bfs_check(!leaf->next || leaf->next->prev == leaf); ++i; } - ret &= bfs_check(i == nkeys); + bfs_check(i == nkeys); } for (size_t i = 0; i < nkeys; ++i) { struct trie_leaf *leaf = trie_find_str(&trie, keys[i]); bfs_verify(leaf); - ret &= bfs_check(strcmp(keys[i], leaf->key) == 0); - ret &= bfs_check(leaf->length == strlen(keys[i]) + 1); + bfs_check(strcmp(keys[i], leaf->key) == 0); + bfs_check(leaf->length == strlen(keys[i]) + 1); trie_remove(&trie, leaf); leaf = trie_find_str(&trie, keys[i]); - ret &= bfs_check(!leaf); + bfs_check(!leaf); const char *postfix = NULL; for (size_t j = i + 1; j < nkeys; ++j) { @@ -104,14 +104,14 @@ bool check_trie(void) { leaf = trie_find_postfix(&trie, keys[i]); if (postfix) { bfs_verify(leaf); - ret &= bfs_check(strcmp(postfix, leaf->key) == 0); + bfs_check(strcmp(postfix, leaf->key) == 0); } else { - ret &= bfs_check(!leaf); + bfs_check(!leaf); } } for_trie (leaf, &trie) { - ret &= bfs_check(false, "trie should be empty"); + bfs_check(false, "trie should be empty"); } // This tests the "jump" node handling on 32-bit platforms @@ -120,18 +120,17 @@ bool check_trie(void) { bfs_verify(longstr); memset(longstr, 0xAC, longsize); - ret &= bfs_check(!trie_find_mem(&trie, longstr, longsize)); - ret &= bfs_check(trie_insert_mem(&trie, longstr, longsize)); + bfs_check(!trie_find_mem(&trie, longstr, longsize)); + bfs_check(trie_insert_mem(&trie, longstr, longsize)); memset(longstr + longsize / 2, 0xAB, longsize / 2); - ret &= bfs_check(!trie_find_mem(&trie, longstr, longsize)); - ret &= bfs_check(trie_insert_mem(&trie, longstr, longsize)); + bfs_check(!trie_find_mem(&trie, longstr, longsize)); + bfs_check(trie_insert_mem(&trie, longstr, longsize)); memset(longstr, 0xAA, longsize / 2); - ret &= bfs_check(!trie_find_mem(&trie, longstr, longsize)); - ret &= bfs_check(trie_insert_mem(&trie, longstr, longsize)); + bfs_check(!trie_find_mem(&trie, longstr, longsize)); + bfs_check(trie_insert_mem(&trie, longstr, longsize)); free(longstr); trie_destroy(&trie); - return ret; } diff --git a/tests/xspawn.c b/tests/xspawn.c index b1d6dc1..3194adc 100644 --- a/tests/xspawn.c +++ b/tests/xspawn.c @@ -1,12 +1,13 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" + #include "alloc.h" #include "bfstd.h" #include "dstring.h" #include "xspawn.h" + #include <stdlib.h> #include <string.h> #include <sys/wait.h> @@ -50,13 +51,10 @@ fail: } /** Check that we resolve executables in $PATH correctly. */ -static bool check_use_path(bool use_posix) { - bool ret = true; - +static void check_use_path(bool use_posix) { struct bfs_spawn spawn; - ret &= bfs_echeck(bfs_spawn_init(&spawn) == 0); - if (!ret) { - goto out; + if (!bfs_echeck(bfs_spawn_init(&spawn) == 0)) { + return; } spawn.flags |= BFS_SPAWN_USE_PATH; @@ -64,19 +62,18 @@ static bool check_use_path(bool use_posix) { spawn.flags &= ~BFS_SPAWN_USE_POSIX; } - ret &= bfs_echeck(bfs_spawn_addopen(&spawn, 10, "bin", O_RDONLY | O_DIRECTORY, 0) == 0); - ret &= bfs_echeck(bfs_spawn_adddup2(&spawn, 10, 11) == 0); - ret &= bfs_echeck(bfs_spawn_addclose(&spawn, 10) == 0); - ret &= bfs_echeck(bfs_spawn_addfchdir(&spawn, 11) == 0); - ret &= bfs_echeck(bfs_spawn_addclose(&spawn, 11) == 0); - if (!ret) { + bool init = bfs_echeck(bfs_spawn_addopen(&spawn, 10, "bin", O_RDONLY | O_DIRECTORY, 0) == 0) + && bfs_echeck(bfs_spawn_adddup2(&spawn, 10, 11) == 0) + && bfs_echeck(bfs_spawn_addclose(&spawn, 10) == 0) + && bfs_echeck(bfs_spawn_addfchdir(&spawn, 11) == 0) + && bfs_echeck(bfs_spawn_addclose(&spawn, 11) == 0); + if (!init) { goto destroy; } // Check that $PATH is resolved in the parent's environment - char **envp; - ret &= bfs_echeck(envp = envdup()); - if (!ret) { + char **envp = envdup(); + if (!bfs_echeck(envp, "envdup()")) { goto destroy; } @@ -84,44 +81,41 @@ static bool check_use_path(bool use_posix) { char *old_path = getenv("PATH"); dchar *new_path = NULL; if (old_path) { - ret &= bfs_echeck(old_path = strdup(old_path)); - if (!ret) { + old_path = strdup(old_path); + if (!bfs_echeck(old_path, "strdup()")) { goto env; } new_path = dstrprintf("tests:%s", old_path); } else { new_path = dstrdup("tests"); } - ret &= bfs_check(new_path); - if (!ret) { + if (!bfs_check(new_path)) { goto path; } - ret &= bfs_echeck(setenv("PATH", new_path, true) == 0); - if (!ret) { + if (!bfs_echeck(setenv("PATH", new_path, true) == 0)) { goto path; } char *argv[] = {"xspawnee", old_path, NULL}; pid_t pid = bfs_spawn("xspawnee", &spawn, argv, envp); - ret &= bfs_echeck(pid >= 0, "bfs_spawn()"); - if (!ret) { + if (!bfs_echeck(pid >= 0, "bfs_spawn()")) { goto unset; } int wstatus; - ret &= bfs_echeck(xwaitpid(pid, &wstatus, 0) == pid) + bool exited = bfs_echeck(xwaitpid(pid, &wstatus, 0) == pid) && bfs_check(WIFEXITED(wstatus)); - if (ret) { + if (exited) { int wexit = WEXITSTATUS(wstatus); - ret &= bfs_check(wexit == EXIT_SUCCESS, "xspawnee: exit(%d)", wexit); + bfs_check(wexit == EXIT_SUCCESS, "xspawnee: exit(%d)", wexit); } unset: if (old_path) { - ret &= bfs_echeck(setenv("PATH", old_path, true) == 0); + bfs_echeck(setenv("PATH", old_path, true) == 0); } else { - ret &= bfs_echeck(unsetenv("PATH") == 0); + bfs_echeck(unsetenv("PATH") == 0); } path: dstrfree(new_path); @@ -132,19 +126,14 @@ env: } free(envp); destroy: - ret &= bfs_echeck(bfs_spawn_destroy(&spawn) == 0); -out: - return ret; + bfs_echeck(bfs_spawn_destroy(&spawn) == 0); } /** Check path resolution of non-existent executables. */ -static bool check_enoent(bool use_posix) { - bool ret = true; - +static void check_enoent(bool use_posix) { struct bfs_spawn spawn; - ret &= bfs_echeck(bfs_spawn_init(&spawn) == 0); - if (!ret) { - goto out; + if (!bfs_echeck(bfs_spawn_init(&spawn) == 0)) { + return; } spawn.flags |= BFS_SPAWN_USE_PATH; @@ -154,44 +143,37 @@ static bool check_enoent(bool use_posix) { char *argv[] = {"eW6f5RM9Qi", NULL}; pid_t pid = bfs_spawn("eW6f5RM9Qi", &spawn, argv, NULL); - ret &= bfs_echeck(pid < 0 && errno == ENOENT, "bfs_spawn()"); + bfs_echeck(pid < 0 && errno == ENOENT, "bfs_spawn()"); - ret &= bfs_echeck(bfs_spawn_destroy(&spawn) == 0); -out: - return ret; + bfs_echeck(bfs_spawn_destroy(&spawn) == 0); } -static bool check_resolve(void) { - bool ret = true; +static void check_resolve(void) { char *exe; exe = bfs_spawn_resolve("sh"); - ret &= bfs_echeck(exe, "bfs_spawn_resolve('sh')"); + bfs_echeck(exe, "bfs_spawn_resolve('sh')"); free(exe); exe = bfs_spawn_resolve("/bin/sh"); - ret &= bfs_echeck(exe && strcmp(exe, "/bin/sh") == 0); + bfs_echeck(exe && strcmp(exe, "/bin/sh") == 0); free(exe); exe = bfs_spawn_resolve("bin/tests/xspawnee"); - ret &= bfs_echeck(exe && strcmp(exe, "bin/tests/xspawnee") == 0); + bfs_echeck(exe && strcmp(exe, "bin/tests/xspawnee") == 0); free(exe); - ret &= bfs_echeck(!bfs_spawn_resolve("eW6f5RM9Qi") && errno == ENOENT); + bfs_echeck(!bfs_spawn_resolve("eW6f5RM9Qi") && errno == ENOENT); - return ret; + bfs_echeck(!bfs_spawn_resolve("bin/eW6f5RM9Qi") && errno == ENOENT); } -bool check_xspawn(void) { - bool ret = true; - - ret &= check_use_path(true); - ret &= check_use_path(false); - - ret &= check_enoent(true); - ret &= check_enoent(false); +void check_xspawn(void) { + check_use_path(true); + check_use_path(false); - ret &= check_resolve(); + check_enoent(true); + check_enoent(false); - return ret; + check_resolve(); } diff --git a/tests/xtime.c b/tests/xtime.c index 1907e26..3472bea 100644 --- a/tests/xtime.c +++ b/tests/xtime.c @@ -1,11 +1,12 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "tests.h" -#include "xtime.h" -#include "bfstd.h" + +#include "bfs.h" #include "diag.h" +#include "xtime.h" + #include <errno.h> #include <limits.h> #include <stdint.h> @@ -39,35 +40,31 @@ static bool check_one_xgetdate(const char *str, int error, time_t expected) { } /** xgetdate() tests. */ -static bool check_xgetdate(void) { - bool ret = true; - - ret &= check_one_xgetdate("", EINVAL, 0); - ret &= check_one_xgetdate("????", EINVAL, 0); - ret &= check_one_xgetdate("1991", EINVAL, 0); - ret &= check_one_xgetdate("1991-??", EINVAL, 0); - ret &= check_one_xgetdate("1991-12", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-??", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14", 0, 692668800); - ret &= check_one_xgetdate("1991-12-14-", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14T", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14T??", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14T10", 0, 692704800); - ret &= check_one_xgetdate("1991-12-14T10:??", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14T10:11", 0, 692705460); - ret &= check_one_xgetdate("1991-12-14T10:11:??", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14T10:11:12", 0, 692705472); - ret &= check_one_xgetdate("1991-12-14T10Z", 0, 692704800); - ret &= check_one_xgetdate("1991-12-14T10:11Z", 0, 692705460); - ret &= check_one_xgetdate("1991-12-14T10:11:12Z", 0, 692705472); - ret &= check_one_xgetdate("1991-12-14T10:11:12?", EINVAL, 0); - ret &= check_one_xgetdate("1991-12-14T03-07", 0, 692704800); - ret &= check_one_xgetdate("1991-12-14T06:41-03:30", 0, 692705460); - ret &= check_one_xgetdate("1991-12-14T03:11:12-07:00", 0, 692705472); - ret &= check_one_xgetdate("19911214 031112-0700", 0, 692705472);; - - return ret; +static void check_xgetdate(void) { + check_one_xgetdate("", EINVAL, 0); + check_one_xgetdate("????", EINVAL, 0); + check_one_xgetdate("1991", EINVAL, 0); + check_one_xgetdate("1991-??", EINVAL, 0); + check_one_xgetdate("1991-12", EINVAL, 0); + check_one_xgetdate("1991-12-", EINVAL, 0); + check_one_xgetdate("1991-12-??", EINVAL, 0); + check_one_xgetdate("1991-12-14", 0, 692668800); + check_one_xgetdate("1991-12-14-", EINVAL, 0); + check_one_xgetdate("1991-12-14T", EINVAL, 0); + check_one_xgetdate("1991-12-14T??", EINVAL, 0); + check_one_xgetdate("1991-12-14T10", 0, 692704800); + check_one_xgetdate("1991-12-14T10:??", EINVAL, 0); + check_one_xgetdate("1991-12-14T10:11", 0, 692705460); + check_one_xgetdate("1991-12-14T10:11:??", EINVAL, 0); + check_one_xgetdate("1991-12-14T10:11:12", 0, 692705472); + check_one_xgetdate("1991-12-14T10Z", 0, 692704800); + check_one_xgetdate("1991-12-14T10:11Z", 0, 692705460); + check_one_xgetdate("1991-12-14T10:11:12Z", 0, 692705472); + check_one_xgetdate("1991-12-14T10:11:12?", EINVAL, 0); + check_one_xgetdate("1991-12-14T03-07", 0, 692704800); + check_one_xgetdate("1991-12-14T06:41-03:30", 0, 692705460); + check_one_xgetdate("1991-12-14T03:11:12-07:00", 0, 692705472); + check_one_xgetdate("19911214 031112-0700", 0, 692705472);; } #define TM_FORMAT "%04d-%02d-%02d %02d:%02d:%02d (%d/7, %d/365%s)" @@ -92,11 +89,9 @@ static bool check_one_xmktime(time_t expected) { } /** xmktime() tests. */ -static bool check_xmktime(void) { - bool ret = true; - +static void check_xmktime(void) { for (time_t time = -10; time <= 10; ++time) { - ret &= check_one_xmktime(time); + check_one_xmktime(time); } // Attempt to trigger overflow (but don't test for it, since it's not mandatory) @@ -111,12 +106,10 @@ static bool check_xmktime(void) { }; time_t time; xmktime(&tm, &time); - - return ret; } /** Check one xtimegm() result. */ -static bool check_one_xtimegm(const struct tm *tm) { +static void check_one_xtimegm(const struct tm *tm) { struct tm tma = *tm, tmb = *tm; time_t ta, tb; ta = mktime(&tma); @@ -124,43 +117,39 @@ static bool check_one_xtimegm(const struct tm *tm) { tb = -1; } - bool ret = true; - ret &= bfs_check(ta == tb, "%jd != %jd", (intmax_t)ta, (intmax_t)tb); - ret &= bfs_check(ta == -1 || tm_equal(&tma, &tmb)); + bool pass = true; + pass &= bfs_check(ta == tb, "%jd != %jd", (intmax_t)ta, (intmax_t)tb); + if (ta != -1) { + pass &= bfs_check(tm_equal(&tma, &tmb)); + } - if (!ret) { + if (!pass) { bfs_diag("mktime(): " TM_FORMAT, TM_PRINTF(tma)); bfs_diag("xtimegm(): " TM_FORMAT, TM_PRINTF(tmb)); bfs_diag("(input): " TM_FORMAT, TM_PRINTF(*tm)); } - - return ret; } #if !BFS_HAS_TIMEGM /** Check an overflowing xtimegm() call. */ -static bool check_xtimegm_overflow(const struct tm *tm) { +static void check_xtimegm_overflow(const struct tm *tm) { struct tm copy = *tm; time_t time = 123; - bool ret = true; - ret &= bfs_check(xtimegm(©, &time) == -1 && errno == EOVERFLOW); - ret &= bfs_check(tm_equal(©, tm)); - ret &= bfs_check(time == 123); + bool pass = true; + pass &= bfs_check(xtimegm(©, &time) == -1 && errno == EOVERFLOW); + pass &= bfs_check(tm_equal(©, tm)); + pass &= bfs_check(time == 123); - if (!ret) { + if (!pass) { bfs_diag("xtimegm(): " TM_FORMAT, TM_PRINTF(copy)); bfs_diag("(input): " TM_FORMAT, TM_PRINTF(*tm)); } - - return ret; } #endif /** xtimegm() tests. */ -static bool check_xtimegm(void) { - bool ret = true; - +static void check_xtimegm(void) { struct tm tm = { .tm_isdst = -1, }; @@ -172,24 +161,20 @@ static bool check_xtimegm(void) { for (tm.tm_hour = -1; tm.tm_hour <= 24; tm.tm_hour += 5) for (tm.tm_min = -1; tm.tm_min <= 60; tm.tm_min += 31) for (tm.tm_sec = -60; tm.tm_sec <= 120; tm.tm_sec += 5) { - ret &= check_one_xtimegm(&tm); + check_one_xtimegm(&tm); } #if !BFS_HAS_TIMEGM // Check integer overflow cases - ret &= check_xtimegm_overflow(&(struct tm) { .tm_sec = INT_MAX, .tm_min = INT_MAX }); - ret &= check_xtimegm_overflow(&(struct tm) { .tm_min = INT_MAX, .tm_hour = INT_MAX }); - ret &= check_xtimegm_overflow(&(struct tm) { .tm_hour = INT_MAX, .tm_mday = INT_MAX }); - ret &= check_xtimegm_overflow(&(struct tm) { .tm_mon = INT_MAX, .tm_year = INT_MAX }); + check_xtimegm_overflow(&(struct tm) { .tm_sec = INT_MAX, .tm_min = INT_MAX }); + check_xtimegm_overflow(&(struct tm) { .tm_min = INT_MAX, .tm_hour = INT_MAX }); + check_xtimegm_overflow(&(struct tm) { .tm_hour = INT_MAX, .tm_mday = INT_MAX }); + check_xtimegm_overflow(&(struct tm) { .tm_mon = INT_MAX, .tm_year = INT_MAX }); #endif - - return ret; } -bool check_xtime(void) { - bool ret = true; - ret &= check_xgetdate(); - ret &= check_xmktime(); - ret &= check_xtimegm(); - return ret; +void check_xtime(void) { + check_xgetdate(); + check_xmktime(); + check_xtimegm(); } diff --git a/tests/xtouch.c b/tests/xtouch.c index 427e3e0..e7c2e00 100644 --- a/tests/xtouch.c +++ b/tests/xtouch.c @@ -1,10 +1,10 @@ // Copyright © Tavian Barnes <tavianator@tavianator.com> // SPDX-License-Identifier: 0BSD -#include "prelude.h" #include "bfstd.h" #include "sanity.h" #include "xtime.h" + #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -247,8 +247,8 @@ int main(int argc, char *argv[]) { times[1] = times[0]; } else { // Don't use UTIME_NOW, so that multiple paths all get the same timestamp - if (xgettime(×[0]) != 0) { - perror("xgettime()"); + if (clock_gettime(CLOCK_REALTIME, ×[0]) != 0) { + perror("clock_gettime()"); return EXIT_FAILURE; } times[1] = times[0]; |