t_here.sh revision 1.3
1# $NetBSD: t_here.sh,v 1.3 2016/03/01 12:39:35 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 42 rm -f trace.* 43 result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )" 44 STATUS=$? 45 46 if [ -s "${O_FILE}" ]; then 47 echo >&2 "unexpected shell output noise on stdout" 48 cat "${O_FILE}" >&2 49 fail=true 50 fi 51 52 if [ "${STATUS}" -ne "$3" ]; then 53 echo >&2 "expected exit code $3, got ${STATUS}" 54 55 # don't actually fail just because of wrong exit code 56 # unless we either expected, or received "good" 57 case "$3/${STATUS}" in 58 (*/0|0/*) fail=true;; 59 esac 60 fi 61 62 if [ "$3" -eq 0 ]; then 63 if [ -s "${TEMP_FILE}" ]; then 64 echo >&2 "Messages produced on stderr unexpected..." 65 cat "${TEMP_FILE}" >&2 66 fail=true 67 fi 68 else 69 if ! [ -s "${TEMP_FILE}" ]; then 70 echo >&2 "Expected messages on stderr, nothing produced" 71 fail=true 72 fi 73 fi 74 rm -f "${TEMP_FILE}" 75 76 # Remove newlines (use local shell for this) 77 oifs="$IFS" 78 IFS="$nl" 79 result="$(echo $result)" 80 IFS="$oifs" 81 if [ "$2" != "$result" ] 82 then 83 echo >&2 "Expected output '$2', received '$result'" 84 fail=true 85 fi 86 87 $fail && atf_fail "test of '$1' failed" 88 return 0 89} 90 91atf_test_case do_simple 92do_simple_head() { 93 atf_set "descr" "Basic tests for here documents" 94} 95do_simple_body() { 96 y=x 97 98 IFS= 99 check 'x=`cat <<EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0 100 check 'x=`cat <<\EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0 101 102 check "y=${y};"'x=`cat <<EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 103 'text' 0 104 check "y=${y};"'x=`cat <<\EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 105 'te${y}t' 0 106 check "y=${y};"'x=`cat <<"EOF"'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 107 'te${y}t' 0 108 check "y=${y};"'x=`cat <<'"'EOF'"$nl'te${y}t'${nl}EOF$nl'`; echo $x' \ 109 'te${y}t' 0 110 111 # check that quotes in the here doc survive and cause no problems 112 check "cat <<EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0 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 <<'EO'F${nl}te\"xt${nl}EOF$nl" 'te"xt' 0 119 120 check "y=${y};"'x=`cat <<EOF'$nl'te'"'"'${y}t'${nl}EOF$nl'`; echo $x' \ 121 'te'"'"'xt' 0 122 check "y=${y};"'x=`cat <<EOF'$nl'te'"''"'${y}t'${nl}EOF$nl'`; echo $x' \ 123 'te'"''"'xt' 0 124 125 # note that the blocks of empty space in the following must 126 # be entirely tab characters, no spaces. 127 128 check 'x=`cat <<EOF'"$nl text${nl}EOF$nl"'`; echo "$x"' \ 129 ' text' 0 130 check 'x=`cat <<-EOF'"$nl text${nl}EOF$nl"'`; echo $x' \ 131 'text' 0 132 check 'x=`cat <<-EOF'"${nl}text${nl} EOF$nl"'`; echo $x' \ 133 'text' 0 134 check 'x=`cat <<-\EOF'"$nl text${nl} EOF$nl"'`; echo $x' \ 135 'text' 0 136 check 'x=`cat <<- "EOF"'"$nl text${nl}EOF$nl"'`; echo $x' \ 137 'text' 0 138 check 'x=`cat <<- '"'EOF'${nl}text${nl} EOF$nl"'`; echo $x' \ 139 'text' 0 140} 141 142atf_test_case incomplete 143incomplete_head() { 144 atf_set "descr" "Basic tests for incomplete here documents" 145} 146incomplete_body() { 147 check 'cat <<EOF' '' 2 148 check 'cat <<- EOF' '' 2 149 check 'cat <<\EOF' '' 2 150 check 'cat <<- \EOF' '' 2 151 152 check 'cat <<EOF'"${nl}" '' 2 153 check 'cat <<- EOF'"${nl}" '' 2 154 check 'cat <<'"'EOF'${nl}" '' 2 155 check 'cat <<- "EOF"'"${nl}" '' 2 156 157 check 'cat << EOF'"${nl}${nl}" '' 2 158 check 'cat <<-EOF'"${nl}${nl}" '' 2 159 check 'cat << '"'EOF'${nl}${nl}" '' 2 160 check 'cat <<-"EOF"'"${nl}${nl}" '' 2 161 162 check 'cat << EOF'"${nl}"'line 1'"${nl}" '' 2 163 check 'cat <<-EOF'"${nl}"' line 1'"${nl}" '' 2 164 check 'cat << EOF'"${nl}"'line 1'"${nl}"' line 2'"${nl}" '' 2 165 check 'cat <<-EOF'"${nl}"' line 1'"${nl}"'line 2'"${nl}" '' 2 166 167 check 'cat << EOF'"${nl}line 1${nl}${nl}line3${nl}${nl}5!${nl}" '' 2 168} 169 170atf_test_case multiple 171multiple_head() { 172 atf_set "descr" "Tests for multiple here documents for one cmd" 173} 174multiple_body() { 175 check \ 176 "(cat ; cat <&3) <<EOF0 3<<EOF3${nl}STDIN${nl}EOF0${nl}-3-${nl}EOF3${nl}" \ 177 'STDIN -3-' 0 178 179 check "(read line; echo \"\$line\"; cat <<EOF1; echo \"\$line\") <<EOF2 180The File 181EOF1 182The Line 183EOF2 184" 'The Line The File The Line' 0 185 186 check "(read line; echo \"\$line\"; cat <<EOF; echo \"\$line\") <<EOF 187The File 188EOF 189The Line 190EOF 191" 'The Line The File The Line' 0 192 193} 194 195atf_test_case vicious 196vicious_head() { 197 atf_set "descr" "Tests for obscure and obnoxious uses of here docs" 198} 199vicious_body() { 200 201 cat <<- \END_SCRIPT > script 202 cat <<ONE && cat \ 203 <<TWO 204 a 205 ONE 206 b 207 TWO 208 END_SCRIPT 209 210 atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} script 211 212 # This next one is causing discussion currently (late Feb 2016) 213 # amongst stds writers & implementors. Consequently we 214 # will not check what it produces. The eventual result 215 # seems unlikely to be what we currently output, which 216 # is: 217 # A:echo line 1 218 # B:echo line 2)" && prefix DASH_CODE <<DASH_CODE 219 # B:echo line 3 220 # line 4 221 # line 5 222 # 223 # The likely intended output is ... 224 # 225 # A:echo line 3 226 # B:echo line 1 227 # line 2 228 # DASH_CODE:echo line 4)" 229 # DASH_CODE:echo line 5 230 # 231 # The difference is explained by differeng opinions on just 232 # when processing of a here doc should start 233 234 cat <<- \END_SCRIPT > script 235 prefix() { sed -e "s/^/$1:/"; } 236 DASH_CODE() { :; } 237 238 prefix A <<XXX && echo "$(prefix B <<XXX 239 echo line 1 240 XXX 241 echo line 2)" && prefix DASH_CODE <<DASH_CODE 242 echo line 3 243 XXX 244 echo line 4)" 245 echo line 5 246 DASH_CODE 247 END_SCRIPT 248 249 # we will just verify that the shell can parse the 250 # script somehow, and doesn't fall over completely... 251 252 atf_check -s exit:0 -o ignore -e empty ${TEST+SH} script 253} 254 255atf_init_test_cases() { 256 atf_add_test_case do_simple 257 atf_add_test_case incomplete 258 atf_add_test_case multiple # multiple << operators on one cmd 259 atf_add_test_case vicious # evil test from the austin-l list... 260} 261