summaryrefslogtreecommitdiffstats
path: root/tests/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'tests/gnu')
-rw-r--r--tests/gnu/L_delete.out4
-rw-r--r--tests/gnu/L_delete.sh11
-rw-r--r--tests/gnu/L_loops_continue.sh3
-rw-r--r--tests/gnu/daystart.sh2
-rw-r--r--tests/gnu/daystart_twice.sh2
-rw-r--r--tests/gnu/empty.out8
-rw-r--r--tests/gnu/empty.sh1
-rw-r--r--tests/gnu/empty_special.out14
-rw-r--r--tests/gnu/empty_special.sh1
-rw-r--r--tests/gnu/exec_flush_fail.sh4
-rw-r--r--tests/gnu/exec_nothing.sh2
-rw-r--r--tests/gnu/exec_plus_flush_fail.sh4
-rw-r--r--tests/gnu/execdir_path_dot.sh1
-rw-r--r--tests/gnu/execdir_path_empty.sh1
-rw-r--r--tests/gnu/execdir_path_relative.sh1
-rw-r--r--tests/gnu/execdir_ulimit.out16
-rw-r--r--tests/gnu/execdir_ulimit.sh2
-rw-r--r--tests/gnu/files0_from_empty.sh2
-rw-r--r--tests/gnu/files0_from_error.sh2
-rw-r--r--tests/gnu/files0_from_file.sh6
-rw-r--r--tests/gnu/files0_from_none.out0
-rw-r--r--tests/gnu/files0_from_none.sh2
-rw-r--r--tests/gnu/files0_from_nothing.sh2
-rw-r--r--tests/gnu/files0_from_nowhere.sh2
-rw-r--r--tests/gnu/files0_from_ok.sh2
-rw-r--r--tests/gnu/fls.sh3
-rw-r--r--tests/gnu/fls_nonexistent.sh2
-rw-r--r--tests/gnu/fprint0_nonexistent.sh2
-rw-r--r--tests/gnu/fprint_duplicate.sh10
-rw-r--r--tests/gnu/fprint_error.sh4
-rw-r--r--tests/gnu/fprint_noarg.sh2
-rw-r--r--tests/gnu/fprint_noerror.sh2
-rw-r--r--tests/gnu/fprint_nonexistent.sh2
-rw-r--r--tests/gnu/fprintf_nofile.sh2
-rw-r--r--tests/gnu/fprintf_noformat.sh2
-rw-r--r--tests/gnu/fprintf_nonexistent.sh2
-rw-r--r--tests/gnu/fstype.sh3
-rw-r--r--tests/gnu/fstype_stacked.out1
-rw-r--r--tests/gnu/fstype_stacked.sh12
-rw-r--r--tests/gnu/fstype_umount.out0
-rw-r--r--tests/gnu/fstype_umount.sh12
-rw-r--r--tests/gnu/gid_plus.sh2
-rw-r--r--tests/gnu/gid_plus_plus.sh2
-rw-r--r--tests/gnu/ignore_readdir_race.sh6
-rw-r--r--tests/gnu/ignore_readdir_race_notdir.sh8
-rw-r--r--tests/gnu/ignore_readdir_race_root.sh2
-rw-r--r--tests/gnu/inum_automount.out2
-rw-r--r--tests/gnu/inum_automount.sh21
-rw-r--r--tests/gnu/iwholename.sh2
-rw-r--r--tests/gnu/newer_link.out1
-rw-r--r--tests/gnu/newer_link.sh1
-rw-r--r--tests/gnu/ok_nothing.sh2
-rw-r--r--tests/gnu/okdir_path_dot.sh1
-rw-r--r--tests/gnu/okdir_path_empty.sh1
-rw-r--r--tests/gnu/okdir_path_relative.sh1
-rw-r--r--tests/gnu/print_error.sh4
-rw-r--r--tests/gnu/printf_Y_error.out6
-rw-r--r--tests/gnu/printf_Y_error.sh16
-rw-r--r--tests/gnu/printf_times.sh2
-rw-r--r--tests/gnu/printf_u_g_ulimit.sh3
-rw-r--r--tests/gnu/regex_error.sh2
-rw-r--r--tests/gnu/regex_invalid_utf8.out2
-rw-r--r--tests/gnu/regex_invalid_utf8.sh10
-rw-r--r--tests/gnu/regextype_emacs.sh2
-rw-r--r--tests/gnu/regextype_grep.sh2
-rw-r--r--tests/gnu/uid_plus.sh2
-rw-r--r--tests/gnu/uid_plus_plus.sh2
-rw-r--r--tests/gnu/used.out4
-rw-r--r--tests/gnu/used.sh40
-rw-r--r--tests/gnu/xtype_bind_mount.out4
-rw-r--r--tests/gnu/xtype_bind_mount.sh17
71 files changed, 192 insertions, 134 deletions
diff --git a/tests/gnu/L_delete.out b/tests/gnu/L_delete.out
index ed0e9a1..7ed5f0d 100644
--- a/tests/gnu/L_delete.out
+++ b/tests/gnu/L_delete.out
@@ -1,2 +1,2 @@
-scratch
-scratch/foo
+.
+./foo
diff --git a/tests/gnu/L_delete.sh b/tests/gnu/L_delete.sh
index 6ec167c..0559c49 100644
--- a/tests/gnu/L_delete.sh
+++ b/tests/gnu/L_delete.sh
@@ -1,9 +1,8 @@
-clean_scratch
-mkdir scratch/foo
-mkdir scratch/bar
-ln -s ../foo scratch/bar/baz
+cd "$TEST"
+mkdir foo bar
+ln -s ../foo bar/baz
# Don't try to rmdir() a symlink
-invoke_bfs -L scratch/bar -delete || return 1
+invoke_bfs -L bar -delete
-bfs_diff scratch
+bfs_diff .
diff --git a/tests/gnu/L_loops_continue.sh b/tests/gnu/L_loops_continue.sh
index 0244137..55aeb33 100644
--- a/tests/gnu/L_loops_continue.sh
+++ b/tests/gnu/L_loops_continue.sh
@@ -1,2 +1 @@
-bfs_diff -L loops
-[ $? -eq $EX_BFS ]
+! bfs_diff -L loops
diff --git a/tests/gnu/daystart.sh b/tests/gnu/daystart.sh
index 9799bca..9c3be1a 100644
--- a/tests/gnu/daystart.sh
+++ b/tests/gnu/daystart.sh
@@ -1 +1 @@
-bfs_diff basic -daystart -mtime 0
+TZ=WAT-1 bfs_diff basic -daystart -mtime 0
diff --git a/tests/gnu/daystart_twice.sh b/tests/gnu/daystart_twice.sh
index 21b2c0f..edbf18d 100644
--- a/tests/gnu/daystart_twice.sh
+++ b/tests/gnu/daystart_twice.sh
@@ -1 +1 @@
-bfs_diff basic -daystart -daystart -mtime 0
+TZ=WAT-1 bfs_diff basic -daystart -daystart -mtime 0
diff --git a/tests/gnu/empty.out b/tests/gnu/empty.out
deleted file mode 100644
index a0f4b76..0000000
--- a/tests/gnu/empty.out
+++ /dev/null
@@ -1,8 +0,0 @@
-basic/a
-basic/b
-basic/c/d
-basic/e/f
-basic/g/h
-basic/i
-basic/j/foo
-basic/k/foo/bar
diff --git a/tests/gnu/empty.sh b/tests/gnu/empty.sh
deleted file mode 100644
index 95ee988..0000000
--- a/tests/gnu/empty.sh
+++ /dev/null
@@ -1 +0,0 @@
-bfs_diff basic -empty
diff --git a/tests/gnu/empty_special.out b/tests/gnu/empty_special.out
deleted file mode 100644
index 3927f2b..0000000
--- a/tests/gnu/empty_special.out
+++ /dev/null
@@ -1,14 +0,0 @@
-rainbow/exec.sh
-rainbow/file.dat
-rainbow/file.txt
-rainbow/mh1
-rainbow/mh2
-rainbow/ow
-rainbow/sgid
-rainbow/star.gz
-rainbow/star.tar
-rainbow/star.tar.gz
-rainbow/sticky
-rainbow/sticky_ow
-rainbow/sugid
-rainbow/suid
diff --git a/tests/gnu/empty_special.sh b/tests/gnu/empty_special.sh
deleted file mode 100644
index 31e9d2e..0000000
--- a/tests/gnu/empty_special.sh
+++ /dev/null
@@ -1 +0,0 @@
-bfs_diff rainbow -empty
diff --git a/tests/gnu/exec_flush_fail.sh b/tests/gnu/exec_flush_fail.sh
index 4772a14..5505f7a 100644
--- a/tests/gnu/exec_flush_fail.sh
+++ b/tests/gnu/exec_flush_fail.sh
@@ -1,3 +1,3 @@
# Failure to flush streams before exec should be caught
-skip_unless test -e /dev/full
-fail invoke_bfs basic -print0 -exec true \; >/dev/full
+test -e /dev/full || skip
+! invoke_bfs basic -print0 -exec true \; >/dev/full
diff --git a/tests/gnu/exec_nothing.sh b/tests/gnu/exec_nothing.sh
index 9d613e8..443aa0d 100644
--- a/tests/gnu/exec_nothing.sh
+++ b/tests/gnu/exec_nothing.sh
@@ -1,2 +1,2 @@
# Regression test: don't segfault on missing command
-fail invoke_bfs basic -exec \;
+! invoke_bfs basic -exec \;
diff --git a/tests/gnu/exec_plus_flush_fail.sh b/tests/gnu/exec_plus_flush_fail.sh
index 5c74fd8..53a50e5 100644
--- a/tests/gnu/exec_plus_flush_fail.sh
+++ b/tests/gnu/exec_plus_flush_fail.sh
@@ -1,2 +1,2 @@
-skip_unless test -e /dev/full
-fail invoke_bfs basic/a -print0 -exec echo found {} + >/dev/full
+test -e /dev/full || skip
+! invoke_bfs basic/a -print0 -exec echo found {} + >/dev/full
diff --git a/tests/gnu/execdir_path_dot.sh b/tests/gnu/execdir_path_dot.sh
new file mode 100644
index 0000000..632dbb4
--- /dev/null
+++ b/tests/gnu/execdir_path_dot.sh
@@ -0,0 +1 @@
+! PATH=".:$PATH" invoke_bfs basic -execdir echo {} +
diff --git a/tests/gnu/execdir_path_empty.sh b/tests/gnu/execdir_path_empty.sh
new file mode 100644
index 0000000..eda6b1c
--- /dev/null
+++ b/tests/gnu/execdir_path_empty.sh
@@ -0,0 +1 @@
+! PATH=":$PATH" invoke_bfs basic -execdir echo {} +
diff --git a/tests/gnu/execdir_path_relative.sh b/tests/gnu/execdir_path_relative.sh
new file mode 100644
index 0000000..69899ad
--- /dev/null
+++ b/tests/gnu/execdir_path_relative.sh
@@ -0,0 +1 @@
+! PATH="foo:$PATH" invoke_bfs basic -execdir echo {} +
diff --git a/tests/gnu/execdir_ulimit.out b/tests/gnu/execdir_ulimit.out
new file mode 100644
index 0000000..6749f7d
--- /dev/null
+++ b/tests/gnu/execdir_ulimit.out
@@ -0,0 +1,16 @@
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
+64 ./0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
diff --git a/tests/gnu/execdir_ulimit.sh b/tests/gnu/execdir_ulimit.sh
new file mode 100644
index 0000000..e14e716
--- /dev/null
+++ b/tests/gnu/execdir_ulimit.sh
@@ -0,0 +1,2 @@
+ulimit -Sn 64
+bfs_diff deep -type f -execdir bash -c 'printf "%d %s\n" $(ulimit -Sn) "$1"' bash {} \;
diff --git a/tests/gnu/files0_from_empty.sh b/tests/gnu/files0_from_empty.sh
index bd4fbf4..85eee8f 100644
--- a/tests/gnu/files0_from_empty.sh
+++ b/tests/gnu/files0_from_empty.sh
@@ -1 +1 @@
-printf "\0" | fail invoke_bfs -files0-from -
+! printf "\0" | invoke_bfs -files0-from -
diff --git a/tests/gnu/files0_from_error.sh b/tests/gnu/files0_from_error.sh
index ab27ea2..1515d0b 100644
--- a/tests/gnu/files0_from_error.sh
+++ b/tests/gnu/files0_from_error.sh
@@ -1 +1 @@
-fail invoke_bfs -files0-from basic
+! invoke_bfs -files0-from basic
diff --git a/tests/gnu/files0_from_file.sh b/tests/gnu/files0_from_file.sh
index 089a20e..81435a0 100644
--- a/tests/gnu/files0_from_file.sh
+++ b/tests/gnu/files0_from_file.sh
@@ -1,4 +1,4 @@
-clean_scratch
+FILE="$TMP/$TEST.in"
cd weirdnames
-invoke_bfs -mindepth 1 -fprintf ../scratch/files0.in "%P\0"
-bfs_diff -files0-from ../scratch/files0.in
+invoke_bfs -mindepth 1 -fprintf "$FILE" "%P\0"
+bfs_diff -files0-from "$FILE"
diff --git a/tests/gnu/files0_from_none.out b/tests/gnu/files0_from_none.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/gnu/files0_from_none.out
diff --git a/tests/gnu/files0_from_none.sh b/tests/gnu/files0_from_none.sh
index c6e5b97..1633163 100644
--- a/tests/gnu/files0_from_none.sh
+++ b/tests/gnu/files0_from_none.sh
@@ -1 +1 @@
-printf "" | fail invoke_bfs -files0-from -
+printf "" | bfs_diff -files0-from -
diff --git a/tests/gnu/files0_from_nothing.sh b/tests/gnu/files0_from_nothing.sh
index 5fdae60..fee50a8 100644
--- a/tests/gnu/files0_from_nothing.sh
+++ b/tests/gnu/files0_from_nothing.sh
@@ -1 +1 @@
-fail invoke_bfs -files0-from basic/nonexistent
+! invoke_bfs -files0-from basic/nonexistent
diff --git a/tests/gnu/files0_from_nowhere.sh b/tests/gnu/files0_from_nowhere.sh
index 2337613..68eea4b 100644
--- a/tests/gnu/files0_from_nowhere.sh
+++ b/tests/gnu/files0_from_nowhere.sh
@@ -1 +1 @@
-fail invoke_bfs -files0-from
+! invoke_bfs -files0-from
diff --git a/tests/gnu/files0_from_ok.sh b/tests/gnu/files0_from_ok.sh
index 5387e5c..8e145ce 100644
--- a/tests/gnu/files0_from_ok.sh
+++ b/tests/gnu/files0_from_ok.sh
@@ -1 +1 @@
-printf "basic\0" | fail invoke_bfs -files0-from - -ok echo {} \;
+! printf "basic\0" | invoke_bfs -files0-from - -ok echo {} \;
diff --git a/tests/gnu/fls.sh b/tests/gnu/fls.sh
index a86fa20..d2ff794 100644
--- a/tests/gnu/fls.sh
+++ b/tests/gnu/fls.sh
@@ -1,2 +1 @@
-clean_scratch
-invoke_bfs rainbow -fls scratch/fls.out
+invoke_bfs rainbow -fls "$OUT"
diff --git a/tests/gnu/fls_nonexistent.sh b/tests/gnu/fls_nonexistent.sh
index 4756834..2854569 100644
--- a/tests/gnu/fls_nonexistent.sh
+++ b/tests/gnu/fls_nonexistent.sh
@@ -1 +1 @@
-fail invoke_bfs rainbow -fls scratch/nonexistent/path
+! invoke_bfs rainbow -fls nonexistent/path
diff --git a/tests/gnu/fprint0_nonexistent.sh b/tests/gnu/fprint0_nonexistent.sh
index d8e0f30..4906081 100644
--- a/tests/gnu/fprint0_nonexistent.sh
+++ b/tests/gnu/fprint0_nonexistent.sh
@@ -1 +1 @@
-fail invoke_bfs basic -fprint0 scratch/nonexistent/path
+! invoke_bfs basic -fprint0 nonexistent/path
diff --git a/tests/gnu/fprint_duplicate.sh b/tests/gnu/fprint_duplicate.sh
index 5275502..8533b05 100644
--- a/tests/gnu/fprint_duplicate.sh
+++ b/tests/gnu/fprint_duplicate.sh
@@ -1,7 +1,7 @@
-"$XTOUCH" -p scratch/foo.out
-ln scratch/foo.out scratch/foo.hard
-ln -s foo.out scratch/foo.soft
+"$XTOUCH" -p "$TEST/foo.out"
+ln "$TEST/foo.out" "$TEST/foo.hard"
+ln -s foo.out "$TEST/foo.soft"
-invoke_bfs basic -fprint scratch/foo.out -fprint scratch/foo.hard -fprint scratch/foo.soft
-sort scratch/foo.out >"$OUT"
+invoke_bfs basic -fprint "$TEST/foo.out" -fprint "$TEST/foo.hard" -fprint "$TEST/foo.soft"
+sort "$TEST/foo.out" >"$OUT"
diff_output
diff --git a/tests/gnu/fprint_error.sh b/tests/gnu/fprint_error.sh
index e7f2394..7617034 100644
--- a/tests/gnu/fprint_error.sh
+++ b/tests/gnu/fprint_error.sh
@@ -1,2 +1,2 @@
-skip_unless test -e /dev/full
-fail invoke_bfs basic -maxdepth 0 -fprint /dev/full
+test -e /dev/full || skip
+! invoke_bfs basic -maxdepth 0 -fprint /dev/full
diff --git a/tests/gnu/fprint_noarg.sh b/tests/gnu/fprint_noarg.sh
index bf772f3..8511649 100644
--- a/tests/gnu/fprint_noarg.sh
+++ b/tests/gnu/fprint_noarg.sh
@@ -1 +1 @@
-fail invoke_bfs basic -fprint
+! invoke_bfs basic -fprint
diff --git a/tests/gnu/fprint_noerror.sh b/tests/gnu/fprint_noerror.sh
index 142e935..f13a62b 100644
--- a/tests/gnu/fprint_noerror.sh
+++ b/tests/gnu/fprint_noerror.sh
@@ -1,3 +1,3 @@
# Regression test: /dev/full should not fail until actually written to
-skip_unless test -e /dev/full
+test -e /dev/full || skip
invoke_bfs basic -false -fprint /dev/full
diff --git a/tests/gnu/fprint_nonexistent.sh b/tests/gnu/fprint_nonexistent.sh
index b6dac8a..2a403a2 100644
--- a/tests/gnu/fprint_nonexistent.sh
+++ b/tests/gnu/fprint_nonexistent.sh
@@ -1 +1 @@
-fail invoke_bfs basic -fprint scratch/nonexistent/path
+! invoke_bfs basic -fprint nonexistent/path
diff --git a/tests/gnu/fprintf_nofile.sh b/tests/gnu/fprintf_nofile.sh
index c2c48a5..4e79002 100644
--- a/tests/gnu/fprintf_nofile.sh
+++ b/tests/gnu/fprintf_nofile.sh
@@ -1 +1 @@
-fail invoke_bfs basic -fprintf
+! invoke_bfs basic -fprintf
diff --git a/tests/gnu/fprintf_noformat.sh b/tests/gnu/fprintf_noformat.sh
index 0d285c3..fd97f4c 100644
--- a/tests/gnu/fprintf_noformat.sh
+++ b/tests/gnu/fprintf_noformat.sh
@@ -1 +1 @@
-fail invoke_bfs basic -fprintf /dev/null
+! invoke_bfs basic -fprintf /dev/null
diff --git a/tests/gnu/fprintf_nonexistent.sh b/tests/gnu/fprintf_nonexistent.sh
index 6ed141a..b1eea10 100644
--- a/tests/gnu/fprintf_nonexistent.sh
+++ b/tests/gnu/fprintf_nonexistent.sh
@@ -1 +1 @@
-fail invoke_bfs basic -fprintf scratch/nonexistent/path '%p\n'
+! invoke_bfs basic -fprintf nonexistent/path '%p\n'
diff --git a/tests/gnu/fstype.sh b/tests/gnu/fstype.sh
index 939438e..05645c3 100644
--- a/tests/gnu/fstype.sh
+++ b/tests/gnu/fstype.sh
@@ -1,3 +1,2 @@
-fstype=$(invoke_bfs basic -maxdepth 0 -printf '%F\n')
-skip_if test $? -ne 0
+fstype=$(invoke_bfs basic -maxdepth 0 -printf '%F\n') || skip
bfs_diff basic -fstype "$fstype"
diff --git a/tests/gnu/fstype_stacked.out b/tests/gnu/fstype_stacked.out
new file mode 100644
index 0000000..c1e0e6c
--- /dev/null
+++ b/tests/gnu/fstype_stacked.out
@@ -0,0 +1 @@
+mnt
diff --git a/tests/gnu/fstype_stacked.sh b/tests/gnu/fstype_stacked.sh
new file mode 100644
index 0000000..a9739bb
--- /dev/null
+++ b/tests/gnu/fstype_stacked.sh
@@ -0,0 +1,12 @@
+test "$UNAME" = "Linux" || skip
+
+cd "$TEST"
+mkdir mnt
+
+bfs_sudo mount -t tmpfs tmpfs mnt || skip
+defer bfs_sudo umount mnt
+
+bfs_sudo mount -t ramfs ramfs mnt || skip
+defer bfs_sudo umount mnt
+
+bfs_diff mnt -fstype ramfs -print -o -printf '%p: %F\n'
diff --git a/tests/gnu/fstype_umount.out b/tests/gnu/fstype_umount.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/gnu/fstype_umount.out
diff --git a/tests/gnu/fstype_umount.sh b/tests/gnu/fstype_umount.sh
new file mode 100644
index 0000000..81c195f
--- /dev/null
+++ b/tests/gnu/fstype_umount.sh
@@ -0,0 +1,12 @@
+test "$UNAME" = "Linux" || skip
+
+cd "$TEST"
+
+mkdir tmp
+bfs_sudo mount -t tmpfs tmpfs tmp || skip
+defer bfs_sudo umount -R tmp
+
+mkdir tmp/ram
+bfs_sudo mount -t ramfs ramfs tmp/ram || skip
+
+bfs_diff tmp -path tmp -exec "${SUDO[@]}" umount tmp/ram \; , -fstype ramfs -print
diff --git a/tests/gnu/gid_plus.sh b/tests/gnu/gid_plus.sh
index 8ad493b..ccba0e6 100644
--- a/tests/gnu/gid_plus.sh
+++ b/tests/gnu/gid_plus.sh
@@ -1,2 +1,2 @@
-skip_if test "$(id -g)" -eq 0
+test "$(id -g)" -eq 0 && skip
bfs_diff basic -gid +0
diff --git a/tests/gnu/gid_plus_plus.sh b/tests/gnu/gid_plus_plus.sh
index 7982633..ec7ae86 100644
--- a/tests/gnu/gid_plus_plus.sh
+++ b/tests/gnu/gid_plus_plus.sh
@@ -1,2 +1,2 @@
-skip_if test "$(id -g)" -eq 0
+test "$(id -g)" -eq 0 && skip
bfs_diff basic -gid ++0
diff --git a/tests/gnu/ignore_readdir_race.sh b/tests/gnu/ignore_readdir_race.sh
index 6586bcc..75165f6 100644
--- a/tests/gnu/ignore_readdir_race.sh
+++ b/tests/gnu/ignore_readdir_race.sh
@@ -1,5 +1,5 @@
-clean_scratch
-"$XTOUCH" scratch/{foo,bar}
+cd "$TEST"
+"$XTOUCH" foo bar
# -links 1 forces a stat() call, which will fail for the second file
-invoke_bfs scratch -mindepth 1 -ignore_readdir_race -links 1 -exec "$TESTS/remove-sibling.sh" {} \;
+invoke_bfs . -mindepth 1 -ignore_readdir_race -links 1 -exec "$TESTS/remove-sibling.sh" {} \;
diff --git a/tests/gnu/ignore_readdir_race_notdir.sh b/tests/gnu/ignore_readdir_race_notdir.sh
index 5b8b56d..12e9fe6 100644
--- a/tests/gnu/ignore_readdir_race_notdir.sh
+++ b/tests/gnu/ignore_readdir_race_notdir.sh
@@ -1,5 +1,7 @@
# Check -ignore_readdir_race handling when a directory is replaced with a file
-clean_scratch
-"$XTOUCH" -p scratch/foo/bar
+cd "$TEST"
+mkdir foo
-invoke_bfs scratch -mindepth 1 -ignore_readdir_race -execdir rm -r {} \; -execdir "$XTOUCH" {} \;
+invoke_bfs . -mindepth 1 -ignore_readdir_race \
+ -type d -execdir rmdir {} \; \
+ -execdir "$XTOUCH" {} \;
diff --git a/tests/gnu/ignore_readdir_race_root.sh b/tests/gnu/ignore_readdir_race_root.sh
index bad7391..dc41e7f 100644
--- a/tests/gnu/ignore_readdir_race_root.sh
+++ b/tests/gnu/ignore_readdir_race_root.sh
@@ -1,2 +1,2 @@
# Make sure -ignore_readdir_race doesn't suppress ENOENT at the root
-fail invoke_bfs basic/nonexistent -ignore_readdir_race
+! invoke_bfs basic/nonexistent -ignore_readdir_race
diff --git a/tests/gnu/inum_automount.out b/tests/gnu/inum_automount.out
index 7b53ae3..3378e2d 100644
--- a/tests/gnu/inum_automount.out
+++ b/tests/gnu/inum_automount.out
@@ -1 +1 @@
-scratch/automnt
+./automnt
diff --git a/tests/gnu/inum_automount.sh b/tests/gnu/inum_automount.sh
index 648ea05..86b23e1 100644
--- a/tests/gnu/inum_automount.sh
+++ b/tests/gnu/inum_automount.sh
@@ -1,17 +1,14 @@
# bfs shouldn't trigger automounts unless it descends into them
-skip_unless test "$SUDO"
-skip_unless command -v systemd-mount &>/dev/null
+command -v systemd-mount &>/dev/null || skip
-clean_scratch
-mkdir scratch/{foo,automnt}
-skip_unless sudo systemd-mount -A -o bind basic scratch/automnt
+cd "$TEST"
+mkdir foo automnt
-before=$(inum scratch/automnt)
-bfs_diff scratch -inum "$before" -prune
-ret=$?
-after=$(inum scratch/automnt)
+bfs_sudo systemd-mount -A -o bind "$TMP/basic" automnt || skip
+defer bfs_sudo systemd-umount automnt
-sudo systemd-umount scratch/automnt
-
-((ret == 0 && before == after))
+before=$(inum automnt)
+bfs_diff . -inum "$before" -prune
+after=$(inum automnt)
+((before == after))
diff --git a/tests/gnu/iwholename.sh b/tests/gnu/iwholename.sh
index 67e9630..0b2d038 100644
--- a/tests/gnu/iwholename.sh
+++ b/tests/gnu/iwholename.sh
@@ -1,2 +1,2 @@
-skip_unless invoke_bfs -quit -iwholename PATTERN
+invoke_bfs -quit -iwholename PATTERN || skip
bfs_diff basic -iwholename 'basic/*F*'
diff --git a/tests/gnu/newer_link.out b/tests/gnu/newer_link.out
new file mode 100644
index 0000000..d2dcdd1
--- /dev/null
+++ b/tests/gnu/newer_link.out
@@ -0,0 +1 @@
+times
diff --git a/tests/gnu/newer_link.sh b/tests/gnu/newer_link.sh
new file mode 100644
index 0000000..685ac78
--- /dev/null
+++ b/tests/gnu/newer_link.sh
@@ -0,0 +1 @@
+bfs_diff times -newer times/l
diff --git a/tests/gnu/ok_nothing.sh b/tests/gnu/ok_nothing.sh
index 439687b..52c3547 100644
--- a/tests/gnu/ok_nothing.sh
+++ b/tests/gnu/ok_nothing.sh
@@ -1,2 +1,2 @@
# Regression test: don't segfault on missing command
-fail invoke_bfs basic -ok \;
+! invoke_bfs basic -ok \;
diff --git a/tests/gnu/okdir_path_dot.sh b/tests/gnu/okdir_path_dot.sh
new file mode 100644
index 0000000..5b40e27
--- /dev/null
+++ b/tests/gnu/okdir_path_dot.sh
@@ -0,0 +1 @@
+! PATH=".:$PATH" invoke_bfs basic -okdir echo {} \;
diff --git a/tests/gnu/okdir_path_empty.sh b/tests/gnu/okdir_path_empty.sh
new file mode 100644
index 0000000..2669ee8
--- /dev/null
+++ b/tests/gnu/okdir_path_empty.sh
@@ -0,0 +1 @@
+! PATH=":$PATH" invoke_bfs basic -okdir echo {} \;
diff --git a/tests/gnu/okdir_path_relative.sh b/tests/gnu/okdir_path_relative.sh
new file mode 100644
index 0000000..05100a1
--- /dev/null
+++ b/tests/gnu/okdir_path_relative.sh
@@ -0,0 +1 @@
+! PATH="foo:$PATH" invoke_bfs basic -okdir echo {} \;
diff --git a/tests/gnu/print_error.sh b/tests/gnu/print_error.sh
index 9fd5af5..bc79637 100644
--- a/tests/gnu/print_error.sh
+++ b/tests/gnu/print_error.sh
@@ -1,2 +1,2 @@
-skip_unless test -e /dev/full
-fail invoke_bfs basic -maxdepth 0 >/dev/full
+test -e /dev/full || skip
+! invoke_bfs basic -maxdepth 0 >/dev/full
diff --git a/tests/gnu/printf_Y_error.out b/tests/gnu/printf_Y_error.out
index 410a9b5..1dd554e 100644
--- a/tests/gnu/printf_Y_error.out
+++ b/tests/gnu/printf_Y_error.out
@@ -1,3 +1,3 @@
-(scratch) () d d
-(scratch/bar) (foo/bar) l ?
-(scratch/foo) () d d
+(.) () d d
+(./bar) (foo/bar) l ?
+(./foo) () d d
diff --git a/tests/gnu/printf_Y_error.sh b/tests/gnu/printf_Y_error.sh
index 6487711..d3130ce 100644
--- a/tests/gnu/printf_Y_error.sh
+++ b/tests/gnu/printf_Y_error.sh
@@ -1,12 +1,8 @@
-clean_scratch
-mkdir scratch/foo
-chmod -x scratch/foo
-ln -s foo/bar scratch/bar
+cd "$TEST"
+mkdir foo
+ln -s foo/bar bar
-bfs_diff scratch -printf '(%p) (%l) %y %Y\n'
-ret=$?
+chmod -x foo
+defer chmod +x foo
-chmod +x scratch/foo
-clean_scratch
-
-[ $ret -eq $EX_BFS ]
+! bfs_diff . -printf '(%p) (%l) %y %Y\n'
diff --git a/tests/gnu/printf_times.sh b/tests/gnu/printf_times.sh
index d952620..e4f5155 100644
--- a/tests/gnu/printf_times.sh
+++ b/tests/gnu/printf_times.sh
@@ -1 +1 @@
-bfs_diff times -type f -printf '%p | %a %AY-%Am-%Ad %AH:%AI:%AS %T@ | %t %TY-%Tm-%Td %TH:%TI:%TS %T@\n'
+bfs_diff times -type f -printf '%p | %a %AY-%Am-%Ad %AH:%AI:%AS %A@ | %t %TY-%Tm-%Td %TH:%TI:%TS %T@\n'
diff --git a/tests/gnu/printf_u_g_ulimit.sh b/tests/gnu/printf_u_g_ulimit.sh
index a84ee29..c621b9b 100644
--- a/tests/gnu/printf_u_g_ulimit.sh
+++ b/tests/gnu/printf_u_g_ulimit.sh
@@ -1,3 +1,2 @@
-closefrom 4
-ulimit -n 16
+ulimit -n $((NOPENFD + 13))
[ "$(invoke_bfs deep -printf '%u %g\n' | uniq)" = "$(id -un) $(id -gn)" ]
diff --git a/tests/gnu/regex_error.sh b/tests/gnu/regex_error.sh
index 9bd4c8d..4af933f 100644
--- a/tests/gnu/regex_error.sh
+++ b/tests/gnu/regex_error.sh
@@ -1 +1 @@
-fail invoke_bfs basic -regex '['
+! invoke_bfs basic -regex '['
diff --git a/tests/gnu/regex_invalid_utf8.out b/tests/gnu/regex_invalid_utf8.out
index 03f3f58..a133b1a 100644
--- a/tests/gnu/regex_invalid_utf8.out
+++ b/tests/gnu/regex_invalid_utf8.out
@@ -1 +1 @@
-scratch/â„
+./â„
diff --git a/tests/gnu/regex_invalid_utf8.sh b/tests/gnu/regex_invalid_utf8.sh
index edb4b1e..7006dcd 100644
--- a/tests/gnu/regex_invalid_utf8.sh
+++ b/tests/gnu/regex_invalid_utf8.sh
@@ -1,8 +1,8 @@
-clean_scratch
+cd "$TEST"
# Incomplete UTF-8 sequences
-skip_unless touch scratch/$'\xC3'
-skip_unless touch scratch/$'\xE2\x84'
-skip_unless touch scratch/$'\xF0\x9F\x92'
+touch $'\xC3' || skip
+touch $'\xE2\x84' || skip
+touch $'\xF0\x9F\x92' || skip
-bfs_diff scratch -regex 'scratch/..'
+bfs_diff . -regex '\./..'
diff --git a/tests/gnu/regextype_emacs.sh b/tests/gnu/regextype_emacs.sh
index d0f68cc..3cc388c 100644
--- a/tests/gnu/regextype_emacs.sh
+++ b/tests/gnu/regextype_emacs.sh
@@ -1,3 +1,3 @@
-skip_unless invoke_bfs -regextype emacs -quit
+invoke_bfs -regextype emacs -quit || skip
bfs_diff basic -regextype emacs -regex '.*/\(f+o?o?\|bar\)'
diff --git a/tests/gnu/regextype_grep.sh b/tests/gnu/regextype_grep.sh
index 0136700..0830667 100644
--- a/tests/gnu/regextype_grep.sh
+++ b/tests/gnu/regextype_grep.sh
@@ -1,3 +1,3 @@
-skip_unless invoke_bfs -regextype grep -quit
+invoke_bfs -regextype grep -quit || skip
bfs_diff basic -regextype grep -regex '.*/f\+o\?o\?'
diff --git a/tests/gnu/uid_plus.sh b/tests/gnu/uid_plus.sh
index fc4bce3..22b2c8e 100644
--- a/tests/gnu/uid_plus.sh
+++ b/tests/gnu/uid_plus.sh
@@ -1,2 +1,2 @@
-skip_if test "$(id -u)" -eq 0
+test "$(id -u)" -eq 0 && skip
bfs_diff basic -uid +0
diff --git a/tests/gnu/uid_plus_plus.sh b/tests/gnu/uid_plus_plus.sh
index 5d5e086..e021888 100644
--- a/tests/gnu/uid_plus_plus.sh
+++ b/tests/gnu/uid_plus_plus.sh
@@ -1,2 +1,2 @@
-skip_if test "$(id -u)" -eq 0
+test "$(id -u)" -eq 0 && skip
bfs_diff basic -uid ++0
diff --git a/tests/gnu/used.out b/tests/gnu/used.out
new file mode 100644
index 0000000..647621b
--- /dev/null
+++ b/tests/gnu/used.out
@@ -0,0 +1,4 @@
+-used +7: ./nextyear
+-used 1: ./tomorrow
+-used 2: ./dayafter
+-used 7: ./nextweek
diff --git a/tests/gnu/used.sh b/tests/gnu/used.sh
new file mode 100644
index 0000000..5e5d4e9
--- /dev/null
+++ b/tests/gnu/used.sh
@@ -0,0 +1,40 @@
+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]}))
+
+# -used is always false if atime < ctime
+yesterday=$(iso8601 $YYYY $MM $((DD - 1)) $hh $mm $ss)
+"$XTOUCH" -at "$yesterday" yesterday
+
+# -used rounds up
+tomorrow=$(iso8601 $YYYY $MM $DD $((hh + 1)) $mm $ss)
+"$XTOUCH" -at "$tomorrow" tomorrow
+
+dayafter=$(iso8601 $YYYY $MM $((DD + 1)) $((hh + 1)) $mm $ss)
+"$XTOUCH" -at "$dayafter" dayafter
+
+nextweek=$(iso8601 $YYYY $MM $((DD + 6)) $((hh + 1)) $mm $ss)
+"$XTOUCH" -at "$nextweek" nextweek
+
+nextyear=$(iso8601 $((YYYY + 1)) $MM $DD $hh $mm $ss)
+"$XTOUCH" -at "$nextyear" nextyear
+
+bfs_diff -mindepth 1 \
+ -a -used 1 -printf '-used 1: %p\n' \
+ -o -used 2 -printf '-used 2: %p\n' \
+ -o -used 7 -printf '-used 7: %p\n' \
+ -o -used +7 -printf '-used +7: %p\n'
diff --git a/tests/gnu/xtype_bind_mount.out b/tests/gnu/xtype_bind_mount.out
index 16804ea..d18d706 100644
--- a/tests/gnu/xtype_bind_mount.out
+++ b/tests/gnu/xtype_bind_mount.out
@@ -1,2 +1,2 @@
-scratch/link
-scratch/null
+./link
+./null
diff --git a/tests/gnu/xtype_bind_mount.sh b/tests/gnu/xtype_bind_mount.sh
index 264b6f8..35fb3f5 100644
--- a/tests/gnu/xtype_bind_mount.sh
+++ b/tests/gnu/xtype_bind_mount.sh
@@ -1,13 +1,10 @@
-skip_unless test "$SUDO"
-skip_unless test "$UNAME" = "Linux"
+test "$UNAME" = "Linux" || skip
-clean_scratch
-"$XTOUCH" scratch/{file,null}
-sudo mount --bind /dev/null scratch/null
-ln -s /dev/null scratch/link
+cd "$TEST"
+"$XTOUCH" file null
+ln -s /dev/null link
-bfs_diff -L scratch -type c
-ret=$?
+bfs_sudo mount --bind /dev/null null || skip
+defer bfs_sudo umount null
-sudo umount scratch/null
-return $ret
+bfs_diff . -xtype c