1 1.1 kre # $NetBSD: t_realpath.sh,v 1.1 2022/07/21 09:52:49 kre Exp $ 2 1.1 kre # 3 1.1 kre # Copyright (c) 2022 The NetBSD Foundation, Inc. 4 1.1 kre # All rights reserved. 5 1.1 kre # 6 1.1 kre # Redistribution and use in source and binary forms, with or without 7 1.1 kre # modification, are permitted provided that the following conditions 8 1.1 kre # are met: 9 1.1 kre # 1. Redistributions of source code must retain the above copyright 10 1.1 kre # notice, this list of conditions and the following disclaimer. 11 1.1 kre # 2. Redistributions in binary form must reproduce the above copyright 12 1.1 kre # notice, this list of conditions and the following disclaimer in the 13 1.1 kre # documentation and/or other materials provided with the distribution. 14 1.1 kre # 15 1.1 kre # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 1.1 kre # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 1.1 kre # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 1.1 kre # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 1.1 kre # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 1.1 kre # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 1.1 kre # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 1.1 kre # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 1.1 kre # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 1.1 kre # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 1.1 kre # POSSIBILITY OF SUCH DAMAGE. 26 1.1 kre # 27 1.1 kre 28 1.1 kre # =========================================================== 29 1.1 kre # 30 1.1 kre # Test data and expected results 31 1.1 kre 32 1.1 kre # Note that the empty line calls realpath with no file arg 33 1.1 kre existing='. 34 1.1 kre 35 1.1 kre ../Dir/StdOut 36 1.1 kre ./S1 37 1.1 kre ./S1/../S4 38 1.1 kre ./Snr/../S4 39 1.1 kre S1/S2/File 40 1.1 kre S1/S3/Link 41 1.1 kre Snr/HoHo 42 1.1 kre Snr/Link 43 1.1 kre L 44 1.1 kre / 45 1.1 kre /bin 46 1.1 kre Self 47 1.1 kre Self/ 48 1.1 kre S4/S1/' 49 1.1 kre 50 1.1 kre exist_results='Dir 51 1.1 kre Dir 52 1.1 kre Dir/StdOut 53 1.1 kre Dir/S1 54 1.1 kre Dir/S4 55 1.1 kre Dir/S4 56 1.1 kre Dir/S1/S2/File 57 1.1 kre Dir/S1/S2/File 58 1.1 kre Dir/Snr/HoHo 59 1.1 kre Dir/S1 60 1.1 kre Dir/StdOut 61 1.1 kre / 62 1.1 kre /bin 63 1.1 kre Dir 64 1.1 kre Dir 65 1.1 kre Dir/S1' 66 1.1 kre 67 1.1 kre exist_root_only='Snx/HaHa 68 1.1 kre Snx/Link' 69 1.1 kre 70 1.1 kre exist_root_results='Dir/Snx/HaHa 71 1.1 kre Dir/S1/S2/File' 72 1.1 kre 73 1.1 kre nofile='- 74 1.1 kre trash 75 1.1 kre Snr/Haha 76 1.1 kre T1 77 1.1 kre T2 78 1.1 kre T3 79 1.1 kre T4 80 1.1 kre T5 81 1.1 kre ../Dir/T2 82 1.1 kre ../Dir/T3 83 1.1 kre /nonsense 84 1.1 kre /bin/../nonsense 85 1.1 kre ./Self/Self/Self/Self/S1/../Self/../Dir/Self/T1 86 1.1 kre Self/nonsense' 87 1.1 kre 88 1.1 kre nofile_results='Dir/- 89 1.1 kre Dir/trash 90 1.1 kre Dir/Snr/Haha 91 1.1 kre Dir/NoSuchFile 92 1.1 kre Dir/S1/NoSuchFile 93 1.1 kre Dir/S1/NoSuchFile 94 1.1 kre Dir/S1/S2/NoSuchFile 95 1.1 kre Dir/S1/S2/NoSuchFile 96 1.1 kre Dir/S1/NoSuchFile 97 1.1 kre Dir/S1/NoSuchFile 98 1.1 kre /nonsense 99 1.1 kre /nonsense 100 1.1 kre Dir/NoSuchFile 101 1.1 kre Dir/nonsense' 102 1.1 kre 103 1.1 kre always_fail='StdOut/ 104 1.1 kre StdOut/../StdErr 105 1.1 kre Loop 106 1.1 kre S1/S5/Link 107 1.1 kre Loop/../StdOut 108 1.1 kre BigLoop 109 1.1 kre U1 110 1.1 kre U2 111 1.1 kre U3 112 1.1 kre U4 113 1.1 kre U5 114 1.1 kre U6 115 1.1 kre U7 116 1.1 kre U8 117 1.1 kre U9 118 1.1 kre T1/NoSuchFile 119 1.1 kre T1/../NoSuchFile 120 1.1 kre U9/../NoSuchFile 121 1.1 kre U9/../StdOut' 122 1.1 kre 123 1.1 kre 124 1.1 kre # =========================================================== 125 1.1 kre # Helper functions 126 1.1 kre # 127 1.1 kre 128 1.1 kre # Create the test environment 129 1.1 kre setup() 130 1.1 kre { 131 1.1 kre atf_require_prog /usr/bin/mktemp 132 1.1 kre atf_require_prog /bin/ln 133 1.1 kre atf_require_prog /bin/cp 134 1.1 kre atf_require_prog /bin/mkdir 135 1.1 kre atf_require_prog /bin/chmod 136 1.1 kre 137 1.1 kre DIR=${PWD}/$(mktemp -d Dir.XXXXX) || 138 1.1 kre atf_fail "Did not make test directory" 139 1.1 kre cd "${DIR}" || atf_fail "Unable to cd $DIR" 140 1.1 kre 141 1.1 kre ID=$( set -- $( type id ) && test "$1" = id && test "$2" = is && 142 1.1 kre test $# -eq 3 && printf %s "$3" || printf no-id-program) 143 1.1 kre 144 1.1 kre mkdir Dir && cd Dir || atf_fail "enter Dir" 145 1.1 kre 146 1.1 kre >StdOut || atf_fail "setup StdOut" 147 1.1 kre >StdErr || atf_fail "setup StdErr" 148 1.1 kre ln -s ../Dir Dir || atf_fail "setup Dir" 149 1.1 kre ln -s Loop Loop || atf_fail "setup Loop" 150 1.1 kre ln -s . Self || atf_fail "setup Self" 151 1.1 kre mkdir S1 S1/S2 S1/S3 S4 S4/S5 || atf_fail "setup subdirs" 152 1.1 kre echo S1/S2/File > S1/S2/File || atf_fail "setup File" 153 1.1 kre ln -s ../S2/File S1/S3/Link || atf_fail "setup S3/Link" 154 1.1 kre ln -s ../S1 S4/S1 || atf_fail "setup S4/S1" 155 1.1 kre ln -s StdOut L1 || atf_fail "setup L1" 156 1.1 kre ln -s L1 L2 || atf_fail "setup L2" 157 1.1 kre ln -s ../L2 S1/L3 || atf_fail "setup L3" 158 1.1 kre ln -s ../L3 S1/S2/L4 || atf_fail "setup L4" 159 1.1 kre ln -s ../S2/L4 S1/S3/L5 || atf_fail "setup L5" 160 1.1 kre ln -s S1/S3/L5 L || atf_fail "setup L" 161 1.1 kre ln -s ${PWD}/S1 S4/PWDS1 || atf_fail "setup PWDS1" 162 1.1 kre ln -s ${PWD}/S9 S4/PWDS9 || atf_fail "setup PWDS9" 163 1.1 kre ln -s ${PWD}/S9/File S4/PWDS9F || atf_fail "setup PWDS9F" 164 1.1 kre ln -s ../S4/BigLoop S1/BigLoop || atf_fail "setup S1/BigLoop" 165 1.1 kre ln -s ../BigLoop S4/BigLoop || atf_fail "setup S4/BigLoop" 166 1.1 kre ln -s "${DIR}"/Dir/S1/BigLoop BigLoop || atf_fail "setup BigLoop" 167 1.1 kre mkdir Snx || atf_fail "setup Snx" 168 1.1 kre cp /dev/null Snx/HaHa || atf_fail "setup Snx/HaHa" 169 1.1 kre ln -s "${DIR}"/Dir/S1/S2/File Snx/Link || atf_fail "setup Snx/Link" 170 1.1 kre mkdir Snr || atf_fail "setup Snr" 171 1.1 kre cp /dev/null Snr/HoHo || atf_fail "setup Snr/HoHo" 172 1.1 kre ln -s "${DIR}"/Dir/S4/PWDS1 Snr/Link || atf_fail "setup Snr/Link" 173 1.1 kre ln -s ../Snx/HaHa Snr/HaHa || atf_fail "setup HaHa" 174 1.1 kre ln -s "${DIR}"/Dir/NoSuchFile T1 || atf_fail "setup T1" 175 1.1 kre ln -s "${DIR}"/Dir/S1/NoSuchFile T2 || atf_fail "setup T2" 176 1.1 kre ln -s S1/NoSuchFile T3 || atf_fail "setup T3" 177 1.1 kre ln -s "${DIR}"/Dir/S1/S2/NoSuchFile T4 || atf_fail "setup T4" 178 1.1 kre ln -s S1/S2/NoSuchFile T5 || atf_fail "setup T5" 179 1.1 kre ln -s "${DIR}"/Dir/StdOut/CannotExist T6 || atf_fail "setup T6" 180 1.1 kre ln -s "${DIR}"/Dir/NoDir/WhoKnows U1 || atf_fail "setup U1" 181 1.1 kre ln -s "${DIR}"/Dir/S1/NoDir/WhoKnows U2 || atf_fail "setup U2" 182 1.1 kre ln -s "${DIR}"/Dir/S1/S2/NoDir/WhoKnows U3 || atf_fail "setup U3" 183 1.1 kre ln -s "${DIR}"/Dir/S1/../NoDir/WhoKnows U4 || atf_fail "setup U4" 184 1.1 kre ln -s "${DIR}"/Dir/NoDir/../StdOut U5 || atf_fail "setup U5" 185 1.1 kre ln -s NoDir/../StdOut U6 || atf_fail "setup U6" 186 1.1 kre ln -s S1/NoDir/../../StdOut U7 || atf_fail "setup U7" 187 1.1 kre ln -s "${DIR}"/Dir/Missing/NoDir/WhoKnows U8 || atf_fail "setup U8" 188 1.1 kre ln -s "${DIR}"/Dir/Missing/NoDir/../../StdOut U9 || atf_fail "setup U9" 189 1.1 kre chmod a+r,a-x Snx || atf_fail "setup a-x " 190 1.1 kre chmod a+x,a-r Snr || atf_fail "setup a-r" 191 1.1 kre } 192 1.1 kre 193 1.1 kre # ATF will remove all the files we made, just ensure perms are OK 194 1.1 kre cleanup() 195 1.1 kre { 196 1.1 kre chmod -R u+rwx . 197 1.1 kre return 0 198 1.1 kre } 199 1.1 kre 200 1.1 kre run_tests_pass() 201 1.1 kre { 202 1.1 kre opt=$1 203 1.1 kre tests=$2 204 1.1 kre results=$3 205 1.1 kre 206 1.1 kre FAILS= 207 1.1 kre FAILURES=0 208 1.1 kre T=0 209 1.1 kre 210 1.1 kre while [ "${#tests}" -gt 0 ] 211 1.1 kre do 212 1.1 kre FILE=${tests%%$'\n'*} 213 1.1 kre EXP=${results%%$'\n'*} 214 1.1 kre 215 1.1 kre tests=${tests#"${FILE}"}; tests=${tests#$'\n'} 216 1.1 kre results=${results#"${EXP}"}; results=${results#$'\n'} 217 1.1 kre 218 1.1 kre test -z "${EXP}" && atf_fail "Too few results (test botch)" 219 1.1 kre 220 1.1 kre T=$(( $T + 1 )) 221 1.1 kre 222 1.1 kre GOT=$(realpath $opt -- ${FILE:+"${FILE}"}) 223 1.1 kre STATUS=$? 224 1.1 kre 225 1.1 kre case "${GOT}" in 226 1.1 kre '') ;; # nothing printed, deal with that below 227 1.1 kre 228 1.1 kre /*) # Full Path (what we want) 229 1.1 kre # Remove the unpredictable ATF dir prefix (if present) 230 1.1 kre GOT=${GOT#"${DIR}/"} 231 1.1 kre # Now it might be a relative path, that's OK 232 1.1 kre # at least it can be compared (its prefix is known) 233 1.1 kre ;; 234 1.1 kre 235 1.1 kre *) # a relative path was printed 236 1.1 kre FAILURES=$(($FAILURES + 1)) 237 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 238 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}'" 239 1.1 kre FAILS="${FAILS}: output relative path '${GOT}'" 240 1.1 kre FAILS="${FAILS}, and exit($STATUS)" 241 1.1 kre continue 242 1.1 kre ;; 243 1.1 kre esac 244 1.1 kre 245 1.1 kre 246 1.1 kre if [ $STATUS -ne 0 ] || [ "${EXP}" != "${GOT}" ] 247 1.1 kre then 248 1.1 kre FAILURES=$(($FAILURES + 1)) 249 1.1 kre if [ $STATUS -ne 0 ] 250 1.1 kre then 251 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 252 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}'" 253 1.1 kre FAILS="${FAILS} failed: status ${STATUS}" 254 1.1 kre else 255 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 256 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}'" 257 1.1 kre FAILS="${FAILS} expected '${EXP}' received '${GOT}'" 258 1.1 kre fi 259 1.1 kre fi 260 1.1 kre done 261 1.1 kre 262 1.1 kre if test -n "${results}" 263 1.1 kre then 264 1.1 kre FAILURES=$(( $FAILURES + 1 )) 265 1.1 kre 266 1.1 kre N=$(( $(printf '%s\n' "${results}" | wc -l) )) 267 1.1 kre s=s; if [ $N -eq 1 ]; then s=; fi 268 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"After $T tests" 269 1.1 kre FAILS="still $N more result$s (test botch)" 270 1.1 kre fi 271 1.1 kre 272 1.1 kre if [ $FAILURES -gt 0 ] 273 1.1 kre then 274 1.1 kre s=s 275 1.1 kre if [ $FAILURES -eq 1 ]; then s=; fi 276 1.1 kre printf >&2 '%d path%s resolved incorrectly:\n%s\n' \ 277 1.1 kre "$FAILURES" "$s" "${FAILS}" 278 1.1 kre atf_fail "$FAILURES path$s resolved incorrectly; see stderr" 279 1.1 kre fi 280 1.1 kre return 0 281 1.1 kre } 282 1.1 kre 283 1.1 kre run_tests_fail() 284 1.1 kre { 285 1.1 kre opt=$1 286 1.1 kre tests=$2 287 1.1 kre 288 1.1 kre FAILS= 289 1.1 kre FAILURES=0 290 1.1 kre T=0 291 1.1 kre 292 1.1 kre while [ "${#tests}" -gt 0 ] 293 1.1 kre do 294 1.1 kre FILE=${tests%%$'\n'*} 295 1.1 kre 296 1.1 kre tests=${tests#"${FILE}"}; tests=${tests#$'\n'} 297 1.1 kre 298 1.1 kre test -z "${FILE}" && continue 299 1.1 kre 300 1.1 kre T=$(( $T + 1 )) 301 1.1 kre 302 1.1 kre GOT=$(realpath $opt -- "${FILE}" 2>StdErr) 303 1.1 kre STATUS=$? 304 1.1 kre 305 1.1 kre ERR=$(cat StdErr) 306 1.1 kre 307 1.1 kre if [ $STATUS -eq 0 ] || [ "${GOT}" ] || ! [ "${ERR}" ] 308 1.1 kre then 309 1.1 kre FAILURES=$(($FAILURES + 1)) 310 1.1 kre if [ "${STATUS}" -eq 0 ] 311 1.1 kre then 312 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T: " 313 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}' worked;" 314 1.1 kre FAILS="${FAILS} received: '${GOT}'}" 315 1.1 kre 316 1.1 kre if [ "${ERR}" ]; then 317 1.1 kre FAILS="${FAILS} and on stderr '${ERR}'" 318 1.1 kre fi 319 1.1 kre elif [ "${GOT}" ] 320 1.1 kre then 321 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 322 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed," 323 1.1 kre FAILS="${FAILS} but with '${GOT}' on stdout" 324 1.1 kre 325 1.1 kre if [ "${ERR}" ]; then 326 1.1 kre FAILS="${FAILS}, and on stderr '${ERR}'" 327 1.1 kre else 328 1.1 kre FAILS="${FAILS}, and empty stderr" 329 1.1 kre fi 330 1.1 kre else 331 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 332 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed," 333 1.1 kre FAILS="${FAILS} but with no error message" 334 1.1 kre fi 335 1.1 kre fi 336 1.1 kre done 337 1.1 kre if [ $FAILURES -gt 0 ] 338 1.1 kre then 339 1.1 kre S=s 340 1.1 kre if [ $FAILURES -eq 1 ]; then s=; fi 341 1.1 kre printf >&2 '%d path%s resolved incorrectly:\n%s\n' \ 342 1.1 kre "$FAILURES" "$s" "${FAILS}" 343 1.1 kre atf_fail "$FAILURES path$s resolved incorrectly; see stderr" 344 1.1 kre fi 345 1.1 kre return 0 346 1.1 kre } 347 1.1 kre 348 1.1 kre # =================================================================== 349 1.1 kre # Test cases setup follows (but almost all the work is earlier) 350 1.1 kre 351 1.1 kre atf_test_case a__e_ok cleanup 352 1.1 kre realpath_e_ok_head() 353 1.1 kre { 354 1.1 kre atf_set descr "Test realpath (with -e) cases which should work" 355 1.1 kre } 356 1.1 kre a__e_ok_body() 357 1.1 kre { 358 1.1 kre setup 359 1.1 kre run_tests_pass -e "${existing}" "${exist_results}" 360 1.1 kre 361 1.1 kre if [ -x "${ID}" ] && [ "$("$ID" -u)" = 0 ] 362 1.1 kre then 363 1.1 kre run_tests_pass -e "${exist_root_only}" "${exist_root_results}" 364 1.1 kre fi 365 1.1 kre } 366 1.1 kre a__e_ok_cleanup() 367 1.1 kre { 368 1.1 kre cleanup 369 1.1 kre } 370 1.1 kre 371 1.1 kre atf_test_case b__E_ok cleanup 372 1.1 kre b__E_ok_head() 373 1.1 kre { 374 1.1 kre atf_set descr "Test realpath (with -E) cases which should work" 375 1.1 kre } 376 1.1 kre b__E_ok_body() { 377 1.1 kre setup 378 1.1 kre # everything which works with -e should also work with -E 379 1.1 kre run_tests_pass -E "${existing}" "${exist_results}" 380 1.1 kre run_tests_pass -E "${nofile}" "${nofile_results}" 381 1.1 kre 382 1.1 kre if [ -x "${ID}" ] && [ "$("${ID}" -u)" = 0 ] 383 1.1 kre then 384 1.1 kre run_tests_pass -E "${exist_root_only}" "${exist_root_results}" 385 1.1 kre fi 386 1.1 kre } 387 1.1 kre b__E_ok_cleanup() 388 1.1 kre { 389 1.1 kre cleanup 390 1.1 kre } 391 1.1 kre 392 1.1 kre atf_test_case c__ok cleanup 393 1.1 kre c__ok_head() 394 1.1 kre { 395 1.1 kre atf_set descr "Test realpath (without -e or -E) cases which should work" 396 1.1 kre } 397 1.1 kre c__ok_body() { 398 1.1 kre setup 399 1.1 kre # Our default for realpath is -E, so the -E tests should work 400 1.1 kre run_tests_pass '' "${existing}" "${exist_results}" 401 1.1 kre # but more should work as well 402 1.1 kre run_tests_pass '' "${nofile}" "${nofile_results}" 403 1.1 kre 404 1.1 kre if [ -x "${ID}" ] && [ "$("${ID}" -u)" = 0 ] 405 1.1 kre then 406 1.1 kre run_tests_pass '' "${exist_root_only}" "${exist_root_results}" 407 1.1 kre fi 408 1.1 kre } 409 1.1 kre c__ok_cleanup() 410 1.1 kre { 411 1.1 kre cleanup 412 1.1 kre } 413 1.1 kre 414 1.1 kre atf_test_case d__E_fail 415 1.1 kre d__E_fail_head() 416 1.1 kre { 417 1.1 kre atf_set descr "Test realpath -e cases which should not work" 418 1.1 kre } 419 1.1 kre d__E_fail_body() 420 1.1 kre { 421 1.1 kre setup 422 1.1 kre run_tests_fail -E "${always_fail}" 423 1.1 kre if [ -x "${ID}" ] && [ "$("${ID}" -u)" != 0 ] 424 1.1 kre then 425 1.1 kre run_tests_fail -E "${exist_root_only}" 426 1.1 kre fi 427 1.1 kre } 428 1.1 kre d__E_fail_cleanup() 429 1.1 kre { 430 1.1 kre cleanup 431 1.1 kre } 432 1.1 kre 433 1.1 kre atf_test_case e__e_fail 434 1.1 kre e__e_fail_head() 435 1.1 kre { 436 1.1 kre atf_set descr "Test realpath -e cases which should not work" 437 1.1 kre } 438 1.1 kre e__e_fail_body() 439 1.1 kre { 440 1.1 kre setup 441 1.1 kre # Some -E tests that work should fail with -e 442 1.1 kre run_tests_fail -e "${nofile}" 443 1.1 kre run_tests_fail -e "${always_fail}" 444 1.1 kre if [ -x "${ID}" ] && [ "$("${ID}" -u)" != 0 ] 445 1.1 kre then 446 1.1 kre run_tests_fail -e "${exist_root_only}" 447 1.1 kre fi 448 1.1 kre } 449 1.1 kre e__e_fail_cleanup() 450 1.1 kre { 451 1.1 kre cleanup 452 1.1 kre } 453 1.1 kre 454 1.1 kre atf_test_case f__fail 455 1.1 kre f__fail_head() 456 1.1 kre { 457 1.1 kre atf_set descr "Test realpath cases which should not work (w/o -[eE])" 458 1.1 kre } 459 1.1 kre f__fail_body() 460 1.1 kre { 461 1.1 kre setup 462 1.1 kre run_tests_fail '' "${always_fail}" 463 1.1 kre if [ -x "${ID}" ] && [ "$("${ID}" -u)" != 0 ] 464 1.1 kre then 465 1.1 kre run_tests_fail '' "${exist_root_only}" 466 1.1 kre fi 467 1.1 kre } 468 1.1 kre f__fail_cleanup() 469 1.1 kre { 470 1.1 kre cleanup 471 1.1 kre } 472 1.1 kre 473 1.1 kre atf_test_case g__q cleanup 474 1.1 kre g__q_head() 475 1.1 kre { 476 1.1 kre atf_set descr "Test realpath's -q option; also test usage message" 477 1.1 kre } 478 1.1 kre g__q_body() 479 1.1 kre { 480 1.1 kre setup 481 1.1 kre 482 1.1 kre # Just run these tests here, the paths have been tested 483 1.1 kre # already, all we care about is that -q suppresses err messages 484 1.1 kre # about the ones that fail, so just test those. Since those 485 1.1 kre # always fail, it is irrlevant which of -e or -E we would use, 486 1.1 kre # so simply use neither. 487 1.1 kre 488 1.1 kre # This is adapted from run_tests_fail 489 1.1 kre 490 1.1 kre FAILURES=0 491 1.1 kre FAILS= 492 1.1 kre 493 1.1 kre opt=-q 494 1.1 kre 495 1.1 kre T=0 496 1.1 kre for FILE in ${always_fail} 497 1.1 kre do 498 1.1 kre 499 1.1 kre test -z "${FILE}" && continue 500 1.1 kre 501 1.1 kre T=$(( $T + 1 )) 502 1.1 kre 503 1.1 kre GOT=$(realpath $opt -- "${FILE}" 2>StdErr) 504 1.1 kre STATUS=$? 505 1.1 kre 506 1.1 kre ERR=$(cat StdErr) 507 1.1 kre 508 1.1 kre if [ $STATUS -eq 0 ] || [ "${GOT}" ] || [ "${ERR}" ] 509 1.1 kre then 510 1.1 kre FAILURES=$(($FAILURES + 1)) 511 1.1 kre if [ "${STATUS}" -eq 0 ] 512 1.1 kre then 513 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T: " 514 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}' worked;" 515 1.1 kre FAILS="${FAILS} received: '${GOT}'}" 516 1.1 kre 517 1.1 kre if [ "${ERR}" ]; then 518 1.1 kre FAILS="${FAILS} and on stderr '${ERR}'" 519 1.1 kre fi 520 1.1 kre elif [ "${GOT}" ] 521 1.1 kre then 522 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 523 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed," 524 1.1 kre FAILS="${FAILS} but with '${GOT}' on stdout" 525 1.1 kre 526 1.1 kre if [ "${ERR}" ]; then 527 1.1 kre FAILS="${FAILS}, and on stderr '${ERR}'" 528 1.1 kre else 529 1.1 kre FAILS="${FAILS}, and empty stderr" 530 1.1 kre fi 531 1.1 kre else 532 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 533 1.1 kre FAILS="${FAILS}${opt:+ $opt} '${FILE}' failed," 534 1.1 kre FAILS="${FAILS} stderr: '${ERR}'" 535 1.1 kre fi 536 1.1 kre fi 537 1.1 kre done 538 1.1 kre 539 1.1 kre # There are a couple of cases where -q does not suppress stderr 540 1.1 kre 541 1.1 kre for FILE in '' -wObBl@ -- 542 1.1 kre do 543 1.1 kre 544 1.1 kre T=$(( $T + 1 )) 545 1.1 kre 546 1.1 kre unset XTRA 547 1.1 kre case "${FILE}" in 548 1.1 kre '') ;; 549 1.1 kre --) XTRA=;; 550 1.1 kre -*) XTRA=/junk;; 551 1.1 kre esac 552 1.1 kre 553 1.1 kre # Note lack of -- in the following, so $FILE can be either 554 1.1 kre # a file name (well, kind of...), or options. 555 1.1 kre 556 1.1 kre GOT=$(realpath $opt "${FILE}" ${XTRA+"${XTRA}"} 2>StdErr) 557 1.1 kre STATUS=$? 558 1.1 kre 559 1.1 kre ERR=$(cat StdErr) 560 1.1 kre 561 1.1 kre if [ $STATUS -eq 0 ] || [ "${GOT}" ] || ! [ "${ERR}" ] 562 1.1 kre then 563 1.1 kre FAILURES=$(($FAILURES + 1)) 564 1.1 kre if [ "${STATUS}" -eq 0 ] 565 1.1 kre then 566 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T: " 567 1.1 kre FAILS="${FAILS}${opt:+ $opt} ${FILE:-''}" 568 1.1 kre FAILS="${FAILS}${XTRA:+ $XTRA} worked;" 569 1.1 kre FAILS="${FAILS} received: '${GOT}'}" 570 1.1 kre 571 1.1 kre if [ "${ERR}" ]; then 572 1.1 kre FAILS="${FAILS} and on stderr '${ERR}'" 573 1.1 kre fi 574 1.1 kre elif [ "${GOT}" ] 575 1.1 kre then 576 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 577 1.1 kre FAILS="${FAILS}${opt:+ $opt} ${FILE:-''}" 578 1.1 kre FAILS="${FAILS}${XTRA:+ ${XTRA}} failed," 579 1.1 kre FAILS="${FAILS} but with '${GOT}' on stdout" 580 1.1 kre 581 1.1 kre if [ "${ERR}" ]; then 582 1.1 kre FAILS="${FAILS}, and on stderr '${ERR}'" 583 1.1 kre else 584 1.1 kre FAILS="${FAILS}, and empty stderr" 585 1.1 kre fi 586 1.1 kre else 587 1.1 kre FAILS=${FAILS:+"${FAILS}"$'\n'}"Path $T:" 588 1.1 kre FAILS="${FAILS}${opt:+ $opt} ${FILE:-''}" 589 1.1 kre FAILS="${FAILS}${XTRA:+ ${XTRA}} failed," 590 1.1 kre FAILS="${FAILS} with stderr empty" 591 1.1 kre fi 592 1.1 kre fi 593 1.1 kre done 594 1.1 kre 595 1.1 kre if [ $FAILURES -gt 0 ] 596 1.1 kre then 597 1.1 kre s=s 598 1.1 kre if [ $FAILURES -eq 1 ]; then s=; fi 599 1.1 kre printf >&2 '%d path%s resolved incorrectly:\n%s\n' \ 600 1.1 kre "$FAILURES" "$s" "${FAILS}" 601 1.1 kre atf_fail "$FAILURES path$s resolved incorrectly; see stderr" 602 1.1 kre fi 603 1.1 kre return 0 604 1.1 kre } 605 1.1 kre g__q_cleanup() 606 1.1 kre { 607 1.1 kre cleanup 608 1.1 kre } 609 1.1 kre 610 1.1 kre atf_test_case h__n_args 611 1.1 kre h__n_args_head() 612 1.1 kre { 613 1.1 kre atf_set descr "Test realpath with multiple file args" 614 1.1 kre } 615 1.1 kre h__n_args_body() 616 1.1 kre { 617 1.1 kre setup 618 1.1 kre 619 1.1 kre # Since these paths have already (hopefully) tested and work 620 1.1 kre # (if a__e_ok had any failures, fix those before even looking 621 1.1 kre # at any failure here) 622 1.1 kre 623 1.1 kre # Since we are assuming that the test cases all work, simply 624 1.1 kre # Count how many there are, and then expect the same number 625 1.1 kre # of answers 626 1.1 kre 627 1.1 kre unset IFS 628 1.1 kre set -- ${existing} 629 1.1 kre # Note that any empty line (no args) case just vanished... 630 1.1 kre # That would be meaningless here, removing it is correct. 631 1.1 kre 632 1.1 kre GOT=$(realpath -e -- "$@" 2>StdErr) 633 1.1 kre STATUS=$? 634 1.1 kre 635 1.1 kre ERR=$(cat StdErr; printf X) 636 1.1 kre ERR=${ERR%X} 637 1.1 kre 638 1.1 kre NR=$(( $(printf '%s\n' "${GOT}" | wc -l) )) 639 1.1 kre 640 1.1 kre if [ $NR -ne $# ] || [ $STATUS -ne 0 ] || [ -s StdErr ] 641 1.1 kre then 642 1.1 kre printf >&2 'Stderr from test:\n%s\n' "${ERR}" 643 1.1 kre if [ $STATUS -eq 0 ]; then S="OK"; else S="FAIL($STATUS)"; fi 644 1.1 kre if [ ${#ERR} -ne 0 ] 645 1.1 kre then 646 1.1 kre E="${#ERR} bytes on stderr" 647 1.1 kre else 648 1.1 kre E="nothing on stderr" 649 1.1 kre fi 650 1.1 kre atf_fail 'Given %d args, got %d results; Status:%s; %s\n' \ 651 1.1 kre "$#" "${NR}" "${S}" "${E}" 652 1.1 kre fi 653 1.1 kre return 0 654 1.1 kre } 655 1.1 kre h__n_args_cleanup() 656 1.1 kre { 657 1.1 kre cleanup 658 1.1 kre } 659 1.1 kre 660 1.1 kre atf_init_test_cases() 661 1.1 kre { 662 1.1 kre atf_add_test_case a__e_ok 663 1.1 kre atf_add_test_case b__E_ok 664 1.1 kre atf_add_test_case c__ok 665 1.1 kre atf_add_test_case d__E_fail 666 1.1 kre atf_add_test_case e__e_fail 667 1.1 kre atf_add_test_case f__fail 668 1.1 kre atf_add_test_case g__q 669 1.1 kre atf_add_test_case h__n_args 670 1.1 kre } 671