# $NetBSD: t_realpath.sh,v 1.1 2022/07/21 09:52:49 kre Exp $
#
# Copyright (c) 2022 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# ===========================================================
#
# Test data and expected results
# Note that the empty line calls realpath with no file arg
existing='.
case "${GOT}" in
'') ;; # nothing printed, deal with that below
/*) # Full Path (what we want)
# Remove the unpredictable ATF dir prefix (if present)
GOT=${GOT#"${DIR}/"}
# Now it might be a relative path, that's OK
# at least it can be compared (its prefix is known)
;;
*) # a relative path was printed
FAILURES=$(($FAILURES + 1))
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}'"
FAILS="${FAILS}: output relative path '${GOT}'"
FAILS="${FAILS}, and exit($STATUS)"
continue
;;
esac
if [ $STATUS -ne 0 ] || [ "${EXP}" != "${GOT}" ]
then
FAILURES=$(($FAILURES + 1))
if [ $STATUS -ne 0 ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}'"
FAILS="${FAILS} failed: status ${STATUS}"
else
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}'"
FAILS="${FAILS} expected '${EXP}' received '${GOT}'"
fi
fi
done
if test -n "${results}"
then
FAILURES=$(( $FAILURES + 1 ))
N=$(( $(printf '%s\n' "${results}" | wc -l) ))
s=s; if [ $N -eq 1 ]; then s=; fi
FAILS=${FAILS:+"${FAILS}"$'\n'}"After $T tests"
FAILS="still $N more result$s (test botch)"
fi
if [ $FAILURES -gt 0 ]
then
s=s
if [ $FAILURES -eq 1 ]; then s=; fi
printf >&2 '%d path%s resolved incorrectly:\n%s\n' \
"$FAILURES" "$s" "${FAILS}"
atf_fail "$FAILURES path$s resolved incorrectly; see stderr"
fi
return 0
}
run_tests_fail()
{
opt=$1
tests=$2
FAILS=
FAILURES=0
T=0
while [ "${#tests}" -gt 0 ]
do
FILE=${tests%%$'\n'*}
if [ $STATUS -eq 0 ] || [ "${GOT}" ] || ! [ "${ERR}" ]
then
FAILURES=$(($FAILURES + 1))
if [ "${STATUS}" -eq 0 ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T: "
FAILS="${FAILS}${opt:+ $opt} '${FILE}' worked;"
FAILS="${FAILS} received: '${GOT}'}"
if [ "${ERR}" ]; then
FAILS="${FAILS} and on stderr '${ERR}'"
fi
elif [ "${GOT}" ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed,"
FAILS="${FAILS} but with '${GOT}' on stdout"
if [ "${ERR}" ]; then
FAILS="${FAILS}, and on stderr '${ERR}'"
else
FAILS="${FAILS}, and empty stderr"
fi
else
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed,"
FAILS="${FAILS} but with no error message"
fi
fi
done
if [ $FAILURES -gt 0 ]
then
S=s
if [ $FAILURES -eq 1 ]; then s=; fi
printf >&2 '%d path%s resolved incorrectly:\n%s\n' \
"$FAILURES" "$s" "${FAILS}"
atf_fail "$FAILURES path$s resolved incorrectly; see stderr"
fi
return 0
}
# ===================================================================
# Test cases setup follows (but almost all the work is earlier)
if [ -x "${ID}" ] && [ "$("$ID" -u)" = 0 ]
then
run_tests_pass -e "${exist_root_only}" "${exist_root_results}"
fi
}
a__e_ok_cleanup()
{
cleanup
}
atf_test_case b__E_ok cleanup
b__E_ok_head()
{
atf_set descr "Test realpath (with -E) cases which should work"
}
b__E_ok_body() {
setup
# everything which works with -e should also work with -E
run_tests_pass -E "${existing}" "${exist_results}"
run_tests_pass -E "${nofile}" "${nofile_results}"
if [ -x "${ID}" ] && [ "$("${ID}" -u)" = 0 ]
then
run_tests_pass -E "${exist_root_only}" "${exist_root_results}"
fi
}
b__E_ok_cleanup()
{
cleanup
}
atf_test_case c__ok cleanup
c__ok_head()
{
atf_set descr "Test realpath (without -e or -E) cases which should work"
}
c__ok_body() {
setup
# Our default for realpath is -E, so the -E tests should work
run_tests_pass '' "${existing}" "${exist_results}"
# but more should work as well
run_tests_pass '' "${nofile}" "${nofile_results}"
if [ -x "${ID}" ] && [ "$("${ID}" -u)" = 0 ]
then
run_tests_pass '' "${exist_root_only}" "${exist_root_results}"
fi
}
c__ok_cleanup()
{
cleanup
}
atf_test_case d__E_fail
d__E_fail_head()
{
atf_set descr "Test realpath -e cases which should not work"
}
d__E_fail_body()
{
setup
run_tests_fail -E "${always_fail}"
if [ -x "${ID}" ] && [ "$("${ID}" -u)" != 0 ]
then
run_tests_fail -E "${exist_root_only}"
fi
}
d__E_fail_cleanup()
{
cleanup
}
atf_test_case e__e_fail
e__e_fail_head()
{
atf_set descr "Test realpath -e cases which should not work"
}
e__e_fail_body()
{
setup
# Some -E tests that work should fail with -e
run_tests_fail -e "${nofile}"
run_tests_fail -e "${always_fail}"
if [ -x "${ID}" ] && [ "$("${ID}" -u)" != 0 ]
then
run_tests_fail -e "${exist_root_only}"
fi
}
e__e_fail_cleanup()
{
cleanup
}
atf_test_case f__fail
f__fail_head()
{
atf_set descr "Test realpath cases which should not work (w/o -[eE])"
}
f__fail_body()
{
setup
run_tests_fail '' "${always_fail}"
if [ -x "${ID}" ] && [ "$("${ID}" -u)" != 0 ]
then
run_tests_fail '' "${exist_root_only}"
fi
}
f__fail_cleanup()
{
cleanup
}
atf_test_case g__q cleanup
g__q_head()
{
atf_set descr "Test realpath's -q option; also test usage message"
}
g__q_body()
{
setup
# Just run these tests here, the paths have been tested
# already, all we care about is that -q suppresses err messages
# about the ones that fail, so just test those. Since those
# always fail, it is irrlevant which of -e or -E we would use,
# so simply use neither.
if [ $STATUS -eq 0 ] || [ "${GOT}" ] || [ "${ERR}" ]
then
FAILURES=$(($FAILURES + 1))
if [ "${STATUS}" -eq 0 ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T: "
FAILS="${FAILS}${opt:+ $opt} '${FILE}' worked;"
FAILS="${FAILS} received: '${GOT}'}"
if [ "${ERR}" ]; then
FAILS="${FAILS} and on stderr '${ERR}'"
fi
elif [ "${GOT}" ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed,"
FAILS="${FAILS} but with '${GOT}' on stdout"
if [ "${ERR}" ]; then
FAILS="${FAILS}, and on stderr '${ERR}'"
else
FAILS="${FAILS}, and empty stderr"
fi
else
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed,"
FAILS="${FAILS} stderr: '${ERR}'"
fi
fi
done
# There are a couple of cases where -q does not suppress stderr
for FILE in '' -wObBl@ --
do
T=$(( $T + 1 ))
unset XTRA
case "${FILE}" in
'') ;;
--) XTRA=;;
-*) XTRA=/junk;;
esac
# Note lack of -- in the following, so $FILE can be either
# a file name (well, kind of...), or options.
if [ $STATUS -eq 0 ] || [ "${GOT}" ] || ! [ "${ERR}" ]
then
FAILURES=$(($FAILURES + 1))
if [ "${STATUS}" -eq 0 ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T: "
FAILS="${FAILS}${opt:+ $opt} ${FILE:-''}"
FAILS="${FAILS}${XTRA:+ $XTRA} worked;"
FAILS="${FAILS} received: '${GOT}'}"
if [ "${ERR}" ]; then
FAILS="${FAILS} and on stderr '${ERR}'"
fi
elif [ "${GOT}" ]
then
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} ${FILE:-''}"
FAILS="${FAILS}${XTRA:+ ${XTRA}} failed,"
FAILS="${FAILS} but with '${GOT}' on stdout"
if [ "${ERR}" ]; then
FAILS="${FAILS}, and on stderr '${ERR}'"
else
FAILS="${FAILS}, and empty stderr"
fi
else
FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:"
FAILS="${FAILS}${opt:+ $opt} ${FILE:-''}"
FAILS="${FAILS}${XTRA:+ ${XTRA}} failed,"
FAILS="${FAILS} with stderr empty"
fi
fi
done
if [ $FAILURES -gt 0 ]
then
s=s
if [ $FAILURES -eq 1 ]; then s=; fi
printf >&2 '%d path%s resolved incorrectly:\n%s\n' \
"$FAILURES" "$s" "${FAILS}"
atf_fail "$FAILURES path$s resolved incorrectly; see stderr"
fi
return 0
}
g__q_cleanup()
{
cleanup
}