t_here.sh revision 1.2
1# $NetBSD: t_here.sh,v 1.2 2016/02/29 23:52:53 christos Exp $ 2# 3# Copyright (c) 2007 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27# the implementation of "sh" to test 28: ${TEST_SH:="/bin/sh"} 29 30nl=' 31' 32 33check() 34{ 35 fail=false 36 TEMP_FILE=$( mktemp OUT.XXXXXX ) 37 38 # our local shell (ATF_SHELL) better do quoting correctly... 39 # some of the tests expect us to expand $nl internally... 40 CMD="nl='${nl}'; $1" 41 42echo "${CMD}" >/tmp/CMD 43 rm -f trace.* 44 result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )" 45 STATUS=$? 46 47 if [ -s "${O_FILE}" ]; then 48 echo >&2 "unexpected shell output noise on stdout" 49 cat "${O_FILE}" >&2 50 fail=true 51 fi 52 53 if [ "${STATUS}" -ne "$3" ]; then 54 echo >&2 "expected exit code $3, got ${STATUS}" 55 56 # don't actually fail just because of wrong exit code 57 # unless we either expected, or received "good" 58 case "$3/${STATUS}" in 59 (*/0|0/*) fail=true;; 60 esac 61 fi 62 63 if [ "$3" -eq 0 ]; then 64 if [ -s "${TEMP_FILE}" ]; then 65 echo >&2 "Messages produced on stderr unexpected..." 66 cat "${TEMP_FILE}" >&2 67 fail=true 68 fi 69 else 70 if ! [ -s "${TEMP_FILE}" ]; then 71 echo >&2 "Expected messages on stderr, nothing produced" 72 fail=true 73 fi 74 fi 75 rm -f "${TEMP_FILE}" 76 77 # Remove newlines (use local shell for this) 78 oifs="$IFS" 79 IFS="$nl" 80 result="$(echo $result)" 81 IFS="$oifs" 82 if [ "$2" != "$result" ] 83 then 84 echo >&2 "Expected output '$2', received '$result'" 85 fail=true 86 fi 87 88 $fail && atf_fail "test of '$1' failed" 89 return 0 90} 91 92atf_test_case do_simple 93do_simple_head() { 94 atf_set "descr" "Basic tests for here documents" 95} 96do_simple_body() { 97 y=x 98 99 IFS= 100 check 'x=`cat <<EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0 101 check 'x=`cat <<\EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0 102 103 check "y=${y};"'x=`cat <<EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 104 'text' 0 105 check "y=${y};"'x=`cat <<\EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 106 'te${y}t' 0 107 check "y=${y};"'x=`cat <<"EOF"'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 108 'te${y}t' 0 109 check "y=${y};"'x=`cat <<'"'EOF'"$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 110 'te${y}t' 0 111 112 # check that quotes in the here doc survive and cause no problems 113 check "cat <<EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0 114 check "cat <<\EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0 115 check "cat <<'EOF'${nl}te'xt${nl}EOF$nl" "te'xt" 0 116 check "cat <<EOF${nl}te\"xt${nl}EOF$nl" 'te"xt' 0 117 check "cat <<\EOF${nl}te\"xt${nl}EOF$nl" 'te"xt' 0 118 check "cat <<'EOF'${nl}te\"xt${nl}EOF$nl" 'te"xt' 0 119 check "cat <<'EO'F${nl}te\"xt${nl}EOF$nl" 'te"xt' 0 120 121 check "y=${y};"'x=`cat <<EOF'$nl'te'"'"'${y}t'${nl}EOF$nl'`; echo $x' \ 122 'te'"'"'xt' 0 123 check "y=${y};"'x=`cat <<EOF'$nl'te'"''"'${y}t'${nl}EOF$nl'`; echo $x' \ 124 'te'"''"'xt' 0 125 126 # note that the blocks of empty space in the following must 127 # be entirely tab characters, no spaces. 128 129 check 'x=`cat <<EOF'"$nl text${nl}EOF$nl"'`; echo "$x"' \ 130 ' text' 0 131 check 'x=`cat <<-EOF'"$nl text${nl}EOF$nl"'`; echo $x' \ 132 'text' 0 133 check 'x=`cat <<-EOF'"${nl}text${nl} EOF$nl"'`; echo $x' \ 134 'text' 0 135 check 'x=`cat <<-\EOF'"$nl text${nl} EOF$nl"'`; echo $x' \ 136 'text' 0 137 check 'x=`cat <<- "EOF"'"$nl text${nl}EOF$nl"'`; echo $x' \ 138 'text' 0 139 check 'x=`cat <<- '"'EOF'${nl}text${nl} EOF$nl"'`; echo $x' \ 140 'text' 0 141} 142 143atf_test_case incomplete 144incomplete_head() { 145 atf_set "descr" "Basic tests for incomplete here documents" 146} 147incomplete_body() { 148 check 'cat <<EOF' '' 2 149 check 'cat <<- EOF' '' 2 150 check 'cat <<\EOF' '' 2 151 check 'cat <<- \EOF' '' 2 152 153 check 'cat <<EOF'"${nl}" '' 2 154 check 'cat <<- EOF'"${nl}" '' 2 155 check 'cat <<'"'EOF'${nl}" '' 2 156 check 'cat <<- "EOF"'"${nl}" '' 2 157 158 check 'cat << EOF'"${nl}${nl}" '' 2 159 check 'cat <<-EOF'"${nl}${nl}" '' 2 160 check 'cat << '"'EOF'${nl}${nl}" '' 2 161 check 'cat <<-"EOF"'"${nl}${nl}" '' 2 162 163 check 'cat << EOF'"${nl}"'line 1'"${nl}" '' 2 164 check 'cat <<-EOF'"${nl}"' line 1'"${nl}" '' 2 165 check 'cat << EOF'"${nl}"'line 1'"${nl}"' line 2'"${nl}" '' 2 166 check 'cat <<-EOF'"${nl}"' line 1'"${nl}"'line 2'"${nl}" '' 2 167 168 check 'cat << EOF'"${nl}line 1${nl}${nl}line3${nl}${nl}5!${nl}" '' 2 169} 170 171atf_test_case multiple 172multiple_head() { 173 atf_set "descr" "Tests for multiple here documents for one cmd" 174} 175multiple_body() { 176 check \ 177 "(cat ; cat <&3) <<EOF0 3<<EOF3${nl}STDIN${nl}EOF0${nl}-3-${nl}EOF3${nl}" \ 178 'STDIN -3-' 0 179 180 check "(read line; echo \"\$line\"; cat <<EOF1; echo \"\$line\") <<EOF2 181The File 182EOF1 183The Line 184EOF2 185" 'The Line The File The Line' 0 186 187 check "(read line; echo \"\$line\"; cat <<EOF; echo \"\$line\") <<EOF 188The File 189EOF 190The Line 191EOF 192" 'The Line The File The Line' 0 193 194} 195 196atf_test_case viscious 197viscious_head() { 198 atf_set "descr" "Tests for obscure and obnoxious uses of here docs" 199} 200viscious_body() { 201 202 cat <<- \END_SCRIPT > script 203 cat <<ONE && cat \ 204 <<TWO 205 a 206 ONE 207 b 208 TWO 209 END_SCRIPT 210 211 atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} script 212 213 # This next one is causing discussion currently (late Feb 2016) 214 # amongst stds writers & implementors. Consequently we 215 # will not check what it produces. The eventual result 216 # seems unlikely to be what we currently output, which 217 # is: 218 # :echo line 1 219 # B:echo line 2)" && prefix DASH_CODE <<DASH_CODE 220 # B:echo line 3 221 # line 4 222 # line 5 223 # 224 # The likely intended output is ... 225 # 226 # A:echo line 3 227 # B:echo line 1 228 # line 2 229 # DASH_CODE:echo line 4)" 230 # DASH_CODE:echo line 5 231 # 232 # The difference is explained by differeng opinions on just 233 # when processing of a here doc should start 234 235 cat <<- \END_SCRIPT > script 236 prefix() { sed -e "s/^/$1:/"; } 237 DASH_CODE() { :; } 238 239 prefix A <<XXX && echo "$(prefix B <<XXX 240 echo line 1 241 XXX 242 echo line 2)" && prefix DASH_CODE <<DASH_CODE 243 echo line 3 244 XXX 245 echo line 4)" 246 echo line 5 247 DASH_CODE 248 END_SCRIPT 249 250 # we will just verify that the shell can parse the 251 # script somehow, and doesn't fall over completely... 252 253 atf_check -s exit:0 -o ignore -e empty ${TEST+SH} script 254} 255 256atf_init_test_cases() { 257 atf_add_test_case do_simple 258 atf_add_test_case incomplete 259 atf_add_test_case multiple # multiple << operators on one cmd 260 atf_add_test_case viscious # evil test from the austin-l list... 261} 262