Also, check the block count.
* tests/find/ls-format-file.sh: where possible, set the test file up
such that its group owner is a group whose name is not the same as the
username of the current process. Check the block count also.
---
tests/find/ls-format-file.sh | 104 ++++++++++++++++++++++++++++-------
1 file changed, 84 insertions(+), 20 deletions(-)
diff --git a/tests/find/ls-format-file.sh b/tests/find/ls-format-file.sh
index 9a9989d0..ec9f2331 100755
--- a/tests/find/ls-format-file.sh
+++ b/tests/find/ls-format-file.sh
@@ -28,11 +28,28 @@ LC_ALL=C
export LC_ALL
unset LANG
-# Create a test file with some known properties.
+user_owner="$( id -u -n )"
+if [ -z "${user_owner}" ]
+then
+ # This could mean that there is no entry in the password database.
+ skip_ "unable to determine username of the current user"
+fi
+
+# Create a test file with some known properties. Because of
+# differences we cannot set a specific expectation for the number of
+# blocks occupied by a file, but we should be able to expect it to be
+# consistent with "ls -s".
umask 077
+# If you change the value of testfile here to include any characters
+# special in either glob patterns or regular expressions, you will
+# need to re-check the tests in this file to ensure that they still do
+# what you want.
testfile='lsme'
filesize=765
rm -f -- "${testfile}"
+# We get the data for the body from "yes" rather than /dev/zero just in case
+# the file system has some kind of optimization for files containing only
+# zero bytes (e.g. converting it to a hole).
if ! ( yes non-empty | dd bs=1 count="${filesize}" of="${testfile}" )
2>/dev/null
then
framework_failure_ "failed to create test file ${testfile}"
@@ -46,27 +63,62 @@ then
framework_failure_ "failed to set mtime of ${testfile}"
fi
-# Check the actual properties of the file (to verify that the setup
-# was successful).
-check_prop() {
- printf_fmt="${1}"
- expected="${2}"
- got="$( find "${testfile}" -printf "${printf_fmt}" )"
-
- if [ "${expected}" != "${got}" ]
+# The script may be running with an effective group id which has the
+# same name as the user's username. This is inconvenient as we would
+# not detect cases where the user and group name are swapped, either
+# by find or by this test, or where the test checks against the wrong
+# value (as in 9d50e9964449fb5e9f3da84a7c19c29dbf001bb5).
+#
+# So, find a group of which the current user is a member and which, if
+# possible is not the same as the user's username.
+choose_distinct_group() {
+ chosen=N
+ unset group_name
+ for group_name in $(groups)
+ do
+ if [ "${group_name}" != "${user_owner}" ]
+ then
+ printf '%s\n' "${group_name}"
+ chosen=Y
+ break
+ fi
+ done
+ if [ "${chosen}" = N ]
then
- framework_failure_ "expected test file ${testfile} to have -printf
'${printf_fmt}\n' result '${expected}' but we got '${got}'"
+ # The user's only group is the same as their username.
+ # Default to the last (and only unless two groups have the
+ # same name) group name in the output of groups.
+ echo "${group_name:-}"
fi
}
+group_owner="$(choose_distinct_group)"
+if [ -z "${group_owner}" ]
+then
+ # This is very unusual, because even if /etc/group has been
+ # deleted, id should have printed the numeric value of the user's
+ # primary group. However, there are situations in which this
+ # could happen. For example, getgid() can fail on GNU Hurd.
+ skip_ "unable to find a group of which the current user is a member"
+fi
-check_prop '%M' "-rw-------" # file mode
-check_prop '%n' 1 # link count
-check_prop '%s' "${filesize}" # size in bytes
-check_prop '%TF' "1992-03-14" # modification date
-check_prop '%TH:%TM' "19:00" # modification time (without seconds)
+if ! chgrp "${group_owner}" "${testfile}"
+then
+ # There are some circumstances in which we cannot use a group in
+ # the filesystem even though getgroups(2) returns it. An example
+ # is NFS version 2, on which the protocol limits the total number
+ # of group IDs that a process can use. If I recall correctly the
+ # limit is 16. Anyway, in this situation we will not claim that
+ # the test framework failed, because it is generally not going to
+ # be useful for the findutils maintainers to investigate these
+ # cases. We also will not continue with a fallback value as these
+ # situations would be difficult to reproduce in the event of a bug
+ # report.
+ skip_ "failed to change group of ${testfile} to ${group_owner}"
+fi
# Remember the file's inode number and block count.
-inum="$( find "${testfile}" -printf '%i\n')"
+inum="$( find "${testfile}" -printf '%i\n' )"
+blocks_expected="$( ls -s "${testfile}" | sed -e "s/${testfile}//g" )"
# The system's value of BLOCKSIZE is implementation-dependent
# ("ls -k" forces ls to use 1KiB blocks, but -ls is intended
# to look like the output of ls -dils, without -k)
@@ -89,7 +141,13 @@ then
fail_ "find -ls output does not end in newline"
fi
-grep -e ' lsme$' < output.txt >/dev/null || fail_ "find -ls output should end
with the file name"
+###############################################################################
+# Checks on the output fields generated by -ls, ignoring differences in the
+# number of spaces between fields. If these tests break, this likely indicates
+# a bug in find.
+###############################################################################
+
+grep -e " ${testfile}"'$' < output.txt >/dev/null || fail_ "find -ls output
should end with the file name"
# The output is supposed to look like this:
@@ -108,9 +166,10 @@ awk < output.txt \
-v ME="${ME_}" \
-v filename_expected="${testfile}" \
-v inodenum="${inum}" \
+ -v blocks_expected="${blocks_expected}" \
-v filesize="${filesize}" \
-v uowner="$(id -un)" \
- -v gowner="$(id -gn)" '
+ -v gowner="${group_owner}" '
BEGIN {
rv=2
}
@@ -146,8 +205,13 @@ NR == 1 {
printf("%s: failed test: expected inode number %d, got %s\n", ME,
inodenum, $1);
}
- # field 2: size in blocks is ignored as we probably cannot assume
- # any particular value for BLOCKSIZE.
+ # field 2: size in blocks
+ if (st_blocks != blocks_expected) {
+ rv=1
+ printf("%s: failed test: expected block count %d got %d\n", ME,
blocks_expected, st_blocks);
+ } else {
+ printf("%s: block count %d looks OK\n", ME, st_blocks);
+ }
# field 3 is the symbolic mode; we allow a final +
# in case there is somehow a non-default ACL on the file.
--
2.47.3