t_redir.sh revision 1.4 1 # $NetBSD: t_redir.sh,v 1.4 2016/03/08 14:26:54 christos Exp $
2 #
3 # Copyright (c) 2016 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
30 # Any failures in this first test means it is not worth bothering looking
31 # for causes of failures in any other tests, make this one work first.
32
33 # Problems with this test usually mean inadequate ATF_SHELL used for testing.
34 # (though if all pass but the last, it might be a TEST_SH problem.)
35
36 atf_test_case basic_test_method_test
37 basic_test_method_test_head()
38 {
39 atf_set "descr" "Tests that test method works as expected"
40 }
41 basic_test_method_test_body()
42 {
43 cat <<- 'DONE' |
44 DONE
45 atf_check -s exit:0 -o empty -e empty ${TEST_SH}
46 cat <<- 'DONE' |
47 DONE
48 atf_check -s exit:0 -o match:0 -e empty ${TEST_SH} -c 'wc -l'
49
50 cat <<- 'DONE' |
51 echo hello
52 DONE
53 atf_check -s exit:0 -o match:hello -e empty ${TEST_SH}
54 cat <<- 'DONE' |
55 echo hello
56 DONE
57 atf_check -s exit:0 -o match:1 -e empty ${TEST_SH} -c 'wc -l'
58
59 cat <<- 'DONE' |
60 echo hello\
61 world
62 DONE
63 atf_check -s exit:0 -o match:helloworld -e empty ${TEST_SH}
64 cat <<- 'DONE' |
65 echo hello\
66 world
67 DONE
68 atf_check -s exit:0 -o match:2 -e empty ${TEST_SH} -c 'wc -l'
69
70 printf '%s\n%s\n%s\n' Line1 Line2 Line3 > File
71 atf_check -s exit:0 -o inline:'Line1\nLine2\nLine3\n' -e empty \
72 ${TEST_SH} -c 'cat File'
73
74 cat <<- 'DONE' |
75 set -- X "" '' Y
76 echo ARGS="${#}"
77 echo '' -$1- -$2- -$3- -$4-
78 cat <<EOF
79 X=$1
80 EOF
81 cat <<\EOF
82 Y=$4
83 EOF
84 DONE
85 atf_check -s exit:0 -o match:ARGS=4 -o match:'-X- -- -- -Y-' \
86 -o match:X=X -o match:'Y=\$4' -e empty ${TEST_SH}
87 }
88
89 atf_test_case do_input_redirections
90 do_input_redirections_head()
91 {
92 atf_set "descr" "Tests that simple input redirection works"
93 }
94 do_input_redirections_body()
95 {
96 printf '%s\n%s\n%s\nEND\n' 'First Line' 'Second Line' 'Line 3' >File
97
98 atf_check -s exit:0 -e empty \
99 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
100 ${TEST_SH} -c 'cat < File'
101 atf_check -s exit:0 -e empty \
102 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
103 ${TEST_SH} -c 'cat <File'
104 atf_check -s exit:0 -e empty \
105 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
106 ${TEST_SH} -c 'cat< File'
107 atf_check -s exit:0 -e empty \
108 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
109 ${TEST_SH} -c 'cat < "File"'
110 atf_check -s exit:0 -e empty \
111 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
112 ${TEST_SH} -c '< File cat'
113
114 ln File wc
115 atf_check -s exit:0 -e empty \
116 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
117 ${TEST_SH} -c '< wc cat'
118
119 mv wc cat
120 atf_check -s exit:0 -e empty -o match:4 \
121 ${TEST_SH} -c '< cat wc'
122
123
124 cat <<- 'EOF' |
125 i=0
126 while [ "$i" -lt 3 ]; do
127 i=$((i + 1))
128 read line < File
129 echo "$line"
130 done
131 EOF
132 atf_check -s exit:0 -e empty \
133 -o inline:'First Line\nFirst Line\nFirst Line\n' \
134 ${TEST_SH}
135
136 cat <<- 'EOF' |
137 i=0
138 while [ "$i" -lt 3 ]; do
139 i=$((i + 1))
140 read line
141 echo "$line"
142 done <File
143 EOF
144 atf_check -s exit:0 -e empty \
145 -o inline:'First Line\nSecond Line\nLine 3\n' \
146 ${TEST_SH}
147
148 cat <<- 'EOF' |
149 i=0
150 while [ "$i" -lt 3 ]; do
151 i=$((i + 1))
152 read line < File
153 echo "$line"
154 done <File
155 EOF
156 atf_check -s exit:0 -e empty \
157 -o inline:'First Line\nFirst Line\nFirst Line\n' \
158 ${TEST_SH}
159
160 cat <<- 'EOF' |
161 line=
162 while [ "$line" != END ]; do
163 read line || exit 1
164 echo "$line"
165 done <File
166 EOF
167 atf_check -s exit:0 -e empty \
168 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
169 ${TEST_SH}
170
171 cat <<- 'EOF' |
172 while :; do
173 read line || exit 0
174 echo "$line"
175 done <File
176 EOF
177 atf_check -s exit:0 -e empty \
178 -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
179 ${TEST_SH}
180
181 cat <<- 'EOF' |
182 i=0
183 while read line < File
184 do
185 echo "$line"
186 i=$((i + 1))
187 [ ${i} -ge 3 ] && break
188 done
189 echo DONE
190 EOF
191 atf_check -s exit:0 -e empty \
192 -o inline:'First Line\nFirst Line\nFirst Line\nDONE\n' \
193 ${TEST_SH}
194
195 cat <<- 'EOF' |
196 i=0
197 while read line
198 do
199 echo "$line"
200 done <File
201 echo DONE
202 EOF
203 atf_check -s exit:0 -e empty \
204 -o inline:'First Line\nSecond Line\nLine 3\nEND\nDONE\n' \
205 ${TEST_SH}
206
207 cat <<- 'EOF' |
208 i=0
209 while read line
210 do
211 echo "$line"
212 i=$((i + 1))
213 [ ${i} -ge 3 ] && break
214 done <File
215 echo DONE
216 EOF
217 atf_check -s exit:0 -e empty \
218 -o inline:'First Line\nSecond Line\nLine 3\nDONE\n' ${TEST_SH}
219
220 cat <<- 'EOF' |
221 i=0
222 while read line1 <File
223 do
224 read line2
225 echo "$line1":"$line2"
226 i=$((i + 1))
227 [ ${i} -ge 2 ] && break
228 done <File
229 echo DONE
230 EOF
231 atf_check -s exit:0 -e empty \
232 -o inline:'First Line:First Line\nFirst Line:Second Line\nDONE\n' \
233 ${TEST_SH}
234 }
235
236 atf_test_case do_output_redirections
237 do_output_redirections_head()
238 {
239 atf_set "descr" "Test Output redirections"
240 }
241 do_output_redirections_body()
242 {
243 nl='
244 '
245 T=0
246 i() { T=$(($T + 1)); }
247
248 rm -f Output 2>/dev/null || :
249 test -f Output && atf_fail "Unable to remove Output file"
250 #1
251 i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '> Output'
252 test -f Output || atf_fail "#$T: Did not make Output file"
253 #2
254 rm -f Output 2>/dev/null || :
255 i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>> Output'
256 test -f Output || atf_fail "#$T: Did not make Output file"
257 #3
258 rm -f Output 2>/dev/null || :
259 i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>| Output'
260 test -f Output || atf_fail "#$T: Did not make Output file"
261
262 #4
263 rm -f Output 2>/dev/null || :
264 i
265 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello >Output'
266 test -s Output || atf_fail "#$T: Did not make non-empty Output file"
267 test "$(cat Output)" = "Hello" ||
268 atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
269 #5
270 i
271 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello>!Output'
272 test -s Output || atf_fail "#$T: Did not make non-empty Output file"
273 test "$(cat Output)" = "Hello" ||
274 atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
275 #6
276 i
277 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Bye >>Output'
278 test -s Output || atf_fail "#$T: Removed Output file"
279 test "$(cat Output)" = "Hello${nl}Bye" || atf_fail \
280 "#$T: Incorrect Output: Should be 'Hello\\nBye' is '$(cat Output)'"
281 #7
282 i; atf_check -s exit:0 -o inline:'line 1\nline 2\n' -e empty \
283 ${TEST_SH} -c \
284 'echo line 1 > Output; echo line 2 >> Output; cat Output'
285 test "$(cat Output)" = "line 1${nl}line 2" || atf_fail \
286 "#$T: Incorrect Output: Should be 'line 1\\nline 2' is '$(cat Output)'"
287 #8
288 i; atf_check -s exit:0 -o inline:'line 2\n' -e empty \
289 ${TEST_SH} -c 'echo line 1 > Output; echo line 2'
290 test "$(cat Output)" = "line 1" || atf_fail \
291 "#$T: Incorrect Output: Should be 'line 1' is '$(cat Output)'"
292 #9
293 i; atf_check -s exit:0 -o empty -e empty \
294 ${TEST_SH} -c '(echo line 1; echo line 2 > Out2) > Out1'
295 test "$(cat Out1)" = "line 1" || atf_fail \
296 "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
297 test "$(cat Out2)" = "line 2" || atf_fail \
298 "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
299 #10
300 i; atf_check -s exit:0 -o empty -e empty \
301 ${TEST_SH} -c '{ echo line 1; echo line 2 > Out2;} > Out1'
302 test "$(cat Out1)" = "line 1" || atf_fail \
303 "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
304 test "$(cat Out2)" = "line 2" || atf_fail \
305 "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
306 #11
307 i; rm -f Out1 Out2 2>/dev/null || :
308 cat <<- 'EOF' |
309 for arg in 'line 1' 'line 2' 'line 3'
310 do
311 echo "$arg"
312 echo "$arg" > Out1
313 done > Out2
314 EOF
315 atf_check -s exit:0 -o empty -e empty ${TEST_SH}
316 test "$(cat Out1)" = "line 3" || atf_fail \
317 "#$T: Incorrect Out1: Should be 'line 3' is '$(cat Out1)'"
318 test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
319 "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
320 #12
321 i; rm -f Out1 Out2 2>/dev/null || :
322 cat <<- 'EOF' |
323 for arg in 'line 1' 'line 2' 'line 3'
324 do
325 echo "$arg"
326 echo "$arg" >> Out1
327 done > Out2
328 EOF
329 atf_check -s exit:0 -o empty -e empty ${TEST_SH}
330 test "$(cat Out1)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
331 "#$T: Incorrect Out1: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out1)'"
332 test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
333 "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
334 }
335
336 atf_test_case fd_redirections
337 fd_redirections_head()
338 {
339 atf_set "descr" "Tests redirections to/from specific descriptors"
340 }
341 fd_redirections_body()
342 {
343 # Or it will one day...
344 }
345
346 atf_test_case local_redirections
347 local_redirections_head()
348 {
349 atf_set "descr" \
350 "Tests that exec can reassign file descriptors in the shell itself"
351 }
352 local_redirections_body()
353 {
354 # Or it will one day...
355 }
356
357 atf_test_case redir_in_case
358 redir_in_case_head()
359 {
360 atf_set "descr" "Tests that sh(1) allows just redirections " \
361 "in case statements. (PR bin/48631)"
362 }
363 redir_in_case_body()
364 {
365 atf_check -s exit:0 -o empty -e empty \
366 ${TEST_SH} -c 'case x in (whatever) >foo;; esac'
367
368 atf_check -s exit:0 -o empty -e empty \
369 ${TEST_SH} -c 'case x in (whatever) >foo 2>&1;; esac'
370
371 atf_check -s exit:0 -o empty -e empty \
372 ${TEST_SH} -c 'case x in (whatever) >foo 2>&1 </dev/null;; esac'
373
374 atf_check -s exit:0 -o empty -e empty \
375 ${TEST_SH} -c 'case x in (whatever) >${somewhere};; esac'
376 }
377
378 atf_test_case incorrect_redirections
379 incorrect_redirections_head()
380 {
381 atf_set "descr" "Tests that sh(1) correctly ignores non-redirections"
382 }
383 incorrect_redirections_body() {
384
385 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo>'
386 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'read foo<'
387 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo<>'
388 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
389 'echo x > '"$nl"
390 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
391 'read x < '"$nl"
392 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
393 'echo x <> '"$nl"
394 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
395 'echo x >< anything'
396 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
397 'echo x >>< anything'
398 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
399 'echo x >|< anything'
400 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
401 'echo x > ; read x < /dev/null || echo bad'
402 atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
403 'read x < & echo y > /dev/null; wait && echo bad'
404
405 rm -f Output 2>/dev/null || :
406 atf_check -s exit:0 -e empty -o inline:'A Line > Output\n' \
407 ${TEST_SH} -c 'echo A Line \> Output'
408 test -f Output && atf_file "File 'Output' appeared and should not have"
409
410 rm -f Output 2>/dev/null || :
411 atf_check -s exit:0 -e empty -o empty \
412 ${TEST_SH} -c 'echo A Line \>> Output'
413 test -f Output || atf_file "File 'Output' not created when it should"
414 test "$(cat Output)" = 'A Line >' || atf_fail \
415 "Output file contains '$(cat Output)' instead of '"'A Line >'\'
416
417 rm -f Output \> 2>/dev/null || :
418 atf_check -s exit:0 -e empty -o empty \
419 ${TEST_SH} -c 'echo A Line >\> Output'
420 test -f Output && atf_file "File 'Output' appeared and should not have"
421 test -f '>' || atf_file "File '>' not created when it should"
422 test "$(cat '>')" = 'A Line Output' || atf_fail \
423 "Output file ('>') contains '$(cat '>')' instead of 'A Line Output'"
424 }
425
426 # Many more tests in t_here, so here we have just rudimentary checks
427 atf_test_case redir_here_doc
428 redir_here_doc_head()
429 {
430 atf_set "descr" "Tests that sh(1) correctly processes 'here' doc " \
431 "input redirections"
432 }
433 redir_here_doc_body()
434 {
435 # nb: the printf is not executed, it is data
436 cat <<- 'DONE' |
437 cat <<EOF
438 printf '%s\n' 'hello\n'
439 EOF
440 DONE
441 atf_check -s exit:0 -o match:printf -o match:'hello\\n' \
442 -e empty ${TEST_SH}
443 }
444
445 atf_test_case subshell_redirections
446 subshell_redirections_head()
447 {
448 atf_set "descr" "Tests redirection interactions between shell and " \
449 "its sub-shell(s)"
450 }
451 subshell_redirections_body()
452 {
453 # Or will, one day
454 }
455
456 atf_init_test_cases() {
457 atf_add_test_case basic_test_method_test
458 atf_add_test_case do_input_redirections
459 atf_add_test_case do_output_redirections
460 atf_add_test_case fd_redirections
461 atf_add_test_case local_redirections
462 atf_add_test_case incorrect_redirections
463 atf_add_test_case redir_here_doc
464 atf_add_test_case redir_in_case
465 atf_add_test_case subshell_redirections
466 }
467