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