Module Name: src
Committed By: christos
Date: Tue Mar 8 14:26:54 UTC 2016
Modified Files:
src/tests/bin/sh: t_expand.sh t_fsplit.sh t_redir.sh
Log Message:
Added more test cases, more exhaustive testing. (from kre)
To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/tests/bin/sh/t_expand.sh
cvs rdiff -u -r1.1 -r1.2 src/tests/bin/sh/t_fsplit.sh
cvs rdiff -u -r1.3 -r1.4 src/tests/bin/sh/t_redir.sh
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/tests/bin/sh/t_expand.sh
diff -u src/tests/bin/sh/t_expand.sh:1.5 src/tests/bin/sh/t_expand.sh:1.6
--- src/tests/bin/sh/t_expand.sh:1.5 Mon Feb 22 15:02:29 2016
+++ src/tests/bin/sh/t_expand.sh Tue Mar 8 09:26:54 2016
@@ -1,4 +1,4 @@
-# $NetBSD: t_expand.sh,v 1.5 2016/02/22 20:02:29 christos Exp $
+# $NetBSD: t_expand.sh,v 1.6 2016/03/08 14:26:54 christos Exp $
#
# Copyright (c) 2007, 2009 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -24,6 +24,8 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
+# the implementation of "sh" to test
+: ${TEST_SH:="/bin/sh"}
#
# This file tests the functions in expand.c.
@@ -50,19 +52,15 @@ dollar_at_head() {
}
dollar_at_body() {
# This one should work everywhere.
- got=`echo "" "" | sed 's,$,EOL,'`
- atf_check_equal ' EOL' '$got'
+ atf_check -s exit:0 -o inline:' EOL\n' -e empty \
+ ${TEST_SH} -c 'echo "" "" | '" sed 's,\$,EOL,'"
# This code triggered the bug.
- set -- "" ""
- got=`echo "$@" | sed 's,$,EOL,'`
- atf_check_equal ' EOL' '$got'
-
- set -- -
- shift
- n_arg() { echo $#; }
- n_args=`n_arg "$@"`
- atf_check_equal '0' '$n_args'
+ atf_check -s exit:0 -o inline:' EOL\n' -e empty \
+ ${TEST_SH} -c 'set -- "" ""; echo "$@" | '" sed 's,\$,EOL,'"
+
+ atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \
+ 'set -- -; shift; n_arg() { echo $#; }; n_arg "$@"'
}
atf_test_case dollar_at_with_text
@@ -71,27 +69,91 @@ dollar_at_with_text_head() {
"within the quotes. PR bin/33956."
}
dollar_at_with_text_body() {
- set --
- atf_check_equal '' "$(delim_argv "$@")"
- atf_check_equal '>foobar<' "$(delim_argv "foo$@bar")"
- atf_check_equal '>foo bar<' "$(delim_argv "foo $@ bar")"
-
- set -- a b c
- atf_check_equal '>a< >b< >c<' "$(delim_argv "$@")"
- atf_check_equal '>fooa< >b< >cbar<' "$(delim_argv "foo$@bar")"
- atf_check_equal '>foo a< >b< >c bar<' "$(delim_argv "foo $@ bar")"
+
+ cat <<'EOF' > h-f1
+
+delim_argv() {
+ str=
+ while [ $# -gt 0 ]; do
+ if [ -z "${str}" ]; then
+ str=">$1<"
+ else
+ str="${str} >$1<"
+ fi
+ shift
+ done
+ echo "${str}"
+}
+
+EOF
+ cat <<'EOF' > h-f2
+
+delim_argv() {
+ str=
+ while [ $# -gt 0 ]; do
+
+ str="${str}${str:+ }>$1<"
+ shift
+
+ done
+ echo "${str}"
+}
+
+EOF
+
+ chmod +x h-f1 h-f2
+
+ for f in 1 2
+ do
+ atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \
+ ". ./h-f${f}; "'set -- ; delim_argv "$@"'
+ atf_check -s exit:0 -o inline:'>foobar<\n' -e empty \
+ ${TEST_SH} -c \
+ ". ./h-f${f}; "'set -- ; delim_argv "foo$@bar"'
+ atf_check -s exit:0 -o inline:'>foo bar<\n' -e empty \
+ ${TEST_SH} -c \
+ ". ./h-f${f}; "'set -- ; delim_argv "foo $@ bar"'
+
+ atf_check -s exit:0 -o inline:'>a< >b< >c<\n' -e empty \
+ ${TEST_SH} -c \
+ ". ./h-f${f}; "'set -- a b c; delim_argv "$@"'
+ atf_check -s exit:0 -o inline:'>fooa< >b< >cbar<\n' -e empty \
+ ${TEST_SH} -c \
+ ". ./h-f${f}; "'set -- a b c; delim_argv "foo$@bar"'
+ atf_check -s exit:0 -o inline:'>foo a< >b< >c bar<\n' -e empty \
+ ${TEST_SH} -c \
+ ". ./h-f${f}; "'set -- a b c; delim_argv "foo $@ bar"'
+ done
}
atf_test_case strip
strip_head() {
atf_set "descr" "Checks that the %% operator works and strips" \
"the contents of a variable from the given point" \
- "to the end (PR bin/43469)"
+ "to the end"
}
strip_body() {
line='#define bindir "/usr/bin" /* comment */'
stripped='#define bindir "/usr/bin" '
- atf_check_equal '$stripped' '${line%%/\**}'
+
+ # atf_expect_fail "PR bin/43469" -- now fixed
+ for exp in \
+ '${line%%/\**}' \
+ '${line%%"/*"*}' \
+ '${line%%'"'"'/*'"'"'*}' \
+ '"${line%%/\**}"' \
+ '"${line%%"/*"*}"' \
+ '"${line%%'"'"'/*'"'"'*}"' \
+ '${line%/\**}' \
+ '${line%"/*"*}' \
+ '${line%'"'"'/*'"'"'*}' \
+ '"${line%/\**}"' \
+ '"${line%"/*"*}"' \
+ '"${line%'"'"'/*'"'"'*}"'
+ do
+ atf_check -o inline:":$stripped:\n" -e empty ${TEST_SH} -c \
+ "line='${line}'; echo :${exp}:"
+ done
}
atf_test_case varpattern_backslashes
@@ -102,7 +164,8 @@ varpattern_backslashes_head() {
varpattern_backslashes_body() {
line='/foo/bar/*/baz'
stripped='/foo/bar/'
- atf_check_equal $stripped ${line%%\**}
+ atf_check -o inline:'/foo/bar/\n' -e empty ${TEST_SH} -c \
+ 'line="/foo/bar/*/baz"; echo ${line%%\**}'
}
atf_test_case arithmetic
@@ -113,9 +176,13 @@ arithmetic_head() {
"this is true."
}
arithmetic_body() {
- atf_check_equal '3' '$((1 + 2))'
- atf_check_equal '2147483647' '$((0x7fffffff))'
- atf_check_equal '9223372036854775807' '$(((1 << 63) - 1))'
+
+ atf_check -o inline:'3' -e empty ${TEST_SH} -c \
+ 'printf %s $((1 + 2))'
+ atf_check -o inline:'2147483647' -e empty ${TEST_SH} -c \
+ 'printf %s $((0x7fffffff))'
+ atf_check -o inline:'9223372036854775807' -e empty ${TEST_SH} -c \
+ 'printf %s $(((1 << 63) - 1))'
}
atf_test_case iteration_on_null_parameter
@@ -125,10 +192,39 @@ iteration_on_null_parameter_head() {
"PR bin/48202."
}
iteration_on_null_parameter_body() {
- s1=`/bin/sh -uc 'N=; set -- ${N}; for X; do echo "[$X]"; done' 2>&1`
- s2=`/bin/sh -uc 'N=; set -- ${N:-}; for X; do echo "[$X]"; done' 2>&1`
- atf_check_equal '' '$s1'
- atf_check_equal '[]' '$s2'
+ atf_check -o empty -e empty ${TEST_SH} -c \
+ 'N=; set -- ${N}; for X; do echo "[$X]"; done'
+}
+
+atf_test_case iteration_on_quoted_null_parameter
+iteration_on_quoted_null_parameter_head() {
+ atf_set "descr" \
+ 'Check iteration of "$@" in for loop when set to null;'
+}
+iteration_on_quoted_null_parameter_body() {
+ atf_check -o inline:'[]\n' -e empty ${TEST_SH} -c \
+ 'N=; set -- "${N}"; for X; do echo "[$X]"; done'
+}
+
+atf_test_case iteration_on_null_or_null_parameter
+iteration_on_null_or_null_parameter_head() {
+ atf_set "descr" \
+ 'Check expansion of null parameter as default for another null'
+}
+iteration_on_null_or_null_parameter_body() {
+ atf_check -o empty -e empty ${TEST_SH} -c \
+ 'N=; E=; set -- ${N:-${E}}; for X; do echo "[$X]"; done'
+}
+
+atf_test_case iteration_on_null_or_missing_parameter
+iteration_on_null_or_missing_parameter_head() {
+ atf_set "descr" \
+ 'Check expansion of missing parameter as default for another null'
+}
+iteration_on_null_or_missing_parameter_body() {
+ # atf_expect_fail 'PR bin/50834'
+ atf_check -o empty -e empty ${TEST_SH} -c \
+ 'N=; set -- ${N:-}; for X; do echo "[$X]"; done'
}
atf_init_test_cases() {
@@ -138,4 +234,7 @@ atf_init_test_cases() {
atf_add_test_case varpattern_backslashes
atf_add_test_case arithmetic
atf_add_test_case iteration_on_null_parameter
+ atf_add_test_case iteration_on_quoted_null_parameter
+ atf_add_test_case iteration_on_null_or_null_parameter
+ atf_add_test_case iteration_on_null_or_missing_parameter
}
Index: src/tests/bin/sh/t_fsplit.sh
diff -u src/tests/bin/sh/t_fsplit.sh:1.1 src/tests/bin/sh/t_fsplit.sh:1.2
--- src/tests/bin/sh/t_fsplit.sh:1.1 Sat Mar 17 12:33:11 2012
+++ src/tests/bin/sh/t_fsplit.sh Tue Mar 8 09:26:54 2016
@@ -1,6 +1,6 @@
-# $NetBSD: t_fsplit.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $
+# $NetBSD: t_fsplit.sh,v 1.2 2016/03/08 14:26:54 christos Exp $
#
-# Copyright (c) 2007 The NetBSD Foundation, Inc.
+# Copyright (c) 2007-2016 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
# the "${x-" and "}" were absent from the input line.
#
# So: sh -c 'set ${x-a b c}; echo $#' should give 3.
+# and: sh -c 'set -- ${x-}' echo $#' shold give 0
#
nl='
@@ -40,15 +41,40 @@ nl='
check()
{
- result="$(eval $1)"
+ TEST=$((${TEST} + 1))
+
+ case "$#" in
+ (2) ;;
+ (*) atf_fail "Internal test error, $# args to check test ${TEST}";;
+ esac
+
+ result=$( ${TEST_SH} -c "unset x; $1" )
+ STATUS="$?"
+
# Remove newlines
oifs="$IFS"
IFS="$nl"
result="$(echo $result)"
IFS="$oifs"
+
+ # trim the test text in case we use it in a message below
+ case "$1" in
+ ????????????????*)
+ set -- "$(expr "$1" : '\(............\).*')..." "$2" ;;
+ esac
+
if [ "$2" != "$result" ]
then
- atf_fail "expected [$2], found [$result]"
+ if [ "${STATUS}" = "0" ]
+ then
+ atf_fail "Test ${TEST} '$1': expected [$2], found [$result]"
+ else
+ atf_fail \
+ "TEST ${TEST} '$1' failed ($STATUS): expected [$2], found [$result]"
+ fi
+ elif [ "${STATUS}" != 0 ]
+ then
+ atf_fail "TEST ${TEST} '$1' failed ($STATUS)"
fi
}
@@ -59,6 +85,7 @@ for_head() {
for_body() {
unset x
+ TEST=0
# Since I managed to break this, leave the test in
check 'for f in $x; do echo x${f}y; done' ''
}
@@ -68,17 +95,121 @@ default_val_head() {
atf_set "descr" "Checks field splitting in variable default values"
}
default_val_body() {
- unset x
-
+ TEST=0
# Check that IFS is applied to text from ${x-...} unless it is inside
# any set of "..."
- check 'set ${x-a b c}; echo $#' 3
- check 'for i in ${x-a b c}; do echo "z${i}z"; done' 'zaz zbz zcz'
- check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' 'za bz zcz'
- check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' 'za b cz zdz'
- check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' 'za b cz zdz'
- check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' 'zaz zb cz zdz'
- check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' 'zaz zbz zcz zdz'
+ check 'set -- ${x-a b c}; echo $#' 3
+
+ check 'set -- ${x-"a b" c}; echo $#' 2
+ check 'set -- ${x-a "b c"}; echo $#' 2
+ check 'set -- ${x-"a b c"}; echo $#' 1
+
+ check "set -- \${x-'a b' c}; echo \$#" 2
+ check "set -- \${x-a 'b c'}; echo \$#" 2
+ check "set -- \${x-'a b c'}; echo \$#" 1
+
+ check 'set -- ${x-a\ b c}; echo $#' 2
+ check 'set -- ${x-a b\ c}; echo $#' 2
+ check 'set -- ${x-a\ b\ c}; echo $#' 1
+
+ check 'set -- ${x}; echo $#' 0
+ check 'set -- ${x-}; echo $#' 0
+ check 'set -- ${x-""}; echo $#' 1
+ check 'set -- ""${x}; echo $#' 1
+ check 'set -- ""${x-}; echo $#' 1
+ check 'set -- ""${x-""}; echo $#' 1
+ check 'set -- ${x}""; echo $#' 1
+ check 'set -- ${x-}""; echo $#' 1
+ check 'set -- ${x-""}""; echo $#' 1
+ check 'set -- ""${x}""; echo $#' 1
+ check 'set -- ""${x-}""; echo $#' 1
+ check 'set -- ""${x-""}""; echo $#' 1
+
+ check 'for i in ${x-a b c}; do echo "z${i}z"; done' \
+ 'zaz zbz zcz'
+ check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' \
+ 'za bz zcz'
+ check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' \
+ 'za b cz zdz'
+ check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' \
+ 'zaz zbz zcz zdz'
+
+ # I am not sure these two are correct, the rules on quoting word
+ # in ${var-word} are peculiar, and hard to fathom...
+ # They are what the NetBSD shell does, and bash, not the freebsd shell
+ # (as of Mar 1, 2016)
+
+ check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' \
+ 'za b cz zdz'
+ check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' \
+ 'zaz zb cz zdz'
+}
+
+atf_test_case replacement_val
+replacement_val_head() {
+ atf_set "descr" "Checks field splitting in variable replacement values"
+}
+replacement_val_body() {
+ TEST=0
+
+ # Check that IFS is applied to text from ${x+...} unless it is inside
+ # any set of "...", or whole expansion is quoted, or both...
+
+ check 'x=BOGUS; set -- ${x+a b c}; echo $#' 3
+
+ check 'x=BOGUS; set -- ${x+"a b" c}; echo $#' 2
+ check 'x=BOGUS; set -- ${x+a "b c"}; echo $#' 2
+ check 'x=BOGUS; set -- ${x+"a b c"}; echo $#' 1
+
+ check "x=BOGUS; set -- \${x+'a b' c}; echo \$#" 2
+ check "x=BOGUS; set -- \${x+a 'b c'}; echo \$#" 2
+ check "x=BOGUS; set -- \${x+'a b c'}; echo \$#" 1
+
+ check 'x=BOGUS; set -- ${x+a\ b c}; echo $#' 2
+ check 'x=BOGUS; set -- ${x+a b\ c}; echo $#' 2
+ check 'x=BOGUS; set -- ${x+a\ b\ c}; echo $#' 1
+
+ check 'x=BOGUS; set -- ${x+}; echo $#' 0
+ check 'x=BOGUS; set -- ${x+""}; echo $#' 1
+ check 'x=BOGUS; set -- ""${x+}; echo $#' 1
+ check 'x=BOGUS; set -- ""${x+""}; echo $#' 1
+ check 'x=BOGUS; set -- ${x+}""; echo $#' 1
+ check 'x=BOGUS; set -- ${x+""}""; echo $#' 1
+ check 'x=BOGUS; set -- ""${x+}""; echo $#' 1
+ check 'x=BOGUS; set -- ""${x+""}""; echo $#' 1
+
+ # verify that the value of $x does not affecty the value of ${x+...}
+ check 'x=BOGUS; set -- ${x+}; echo X$1' X
+ check 'x=BOGUS; set -- ${x+""}; echo X$1' X
+ check 'x=BOGUS; set -- ""${x+}; echo X$1' X
+ check 'x=BOGUS; set -- ""${x+""}; echo X$1' X
+ check 'x=BOGUS; set -- ${x+}""; echo X$1' X
+ check 'x=BOGUS; set -- ${x+""}""; echo X$1' X
+ check 'x=BOGUS; set -- ""${x+}""; echo X$1' X
+ check 'x=BOGUS; set -- ""${x+""}""; echo X$1' X
+
+ check 'x=BOGUS; set -- ${x+}; echo X${1-:}X' X:X
+ check 'x=BOGUS; set -- ${x+""}; echo X${1-:}X' XX
+ check 'x=BOGUS; set -- ""${x+}; echo X${1-:}X' XX
+ check 'x=BOGUS; set -- ""${x+""}; echo X${1-:}X' XX
+ check 'x=BOGUS; set -- ${x+}""; echo X${1-:}X' XX
+ check 'x=BOGUS; set -- ${x+""}""; echo X${1-:}X' XX
+ check 'x=BOGUS; set -- ""${x+}""; echo X${1-:}X' XX
+ check 'x=BOGUS; set -- ""${x+""}""; echo X${1-:}X' XX
+
+ # and validate that the replacement can be used as expected
+ check 'x=BOGUS; for i in ${x+a b c}; do echo "z${i}z"; done'\
+ 'zaz zbz zcz'
+ check 'x=BOGUS; for i in ${x+"a b" c}; do echo "z${i}z"; done'\
+ 'za bz zcz'
+ check 'x=BOGUS; for i in ${x+"a ${x+b c}" d}; do echo "z${i}z"; done'\
+ 'za b cz zdz'
+ check 'x=BOGUS; for i in ${x+"a ${x+"b c"}" d}; do echo "z${i}z"; done'\
+ 'za b cz zdz'
+ check 'x=BOGUS; for i in ${x+a ${x+"b c"} d}; do echo "z${i}z"; done'\
+ 'zaz zb cz zdz'
+ check 'x=BOGUS; for i in ${x+a ${x+b c} d}; do echo "z${i}z"; done'\
+ 'zaz zbz zcz zdz'
}
atf_test_case ifs_alpha
@@ -89,13 +220,19 @@ ifs_alpha_head() {
ifs_alpha_body() {
unset x
+ TEST=0
# repeat with an alphabetic in IFS
check 'IFS=q; set ${x-aqbqc}; echo $#' 3
- check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' 'zaz zbz zcz'
- check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' 'zaqbz zcz'
- check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' 'zaqbqcz zdz'
- check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' 'zaqbqcz zdz'
- check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' 'zaz zbqcz zdz'
+ check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' \
+ 'zaz zbz zcz'
+ check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' \
+ 'zaqbz zcz'
+ check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' \
+ 'zaqbqcz zdz'
+ check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' \
+ 'zaqbqcz zdz'
+ check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' \
+ 'zaz zbqcz zdz'
}
atf_test_case quote
@@ -106,6 +243,7 @@ quote_head() {
quote_body() {
unset x
+ TEST=0
# Some quote propagation checks
check 'set "${x-a b c}"; echo $#' 1
check 'set "${x-"a b" c}"; echo $1' 'a b c'
@@ -120,19 +258,39 @@ dollar_at_head() {
dollar_at_body() {
unset x
+ TEST=0
# Check we get "$@" right
- check 'set ""; for i; do echo "z${i}z"; done' 'zz'
- check 'set ""; for i in "$@"; do echo "z${i}z"; done' 'zz'
- check 'set "" ""; for i; do echo "z${i}z"; done' 'zz zz'
- check 'set "" ""; for i in "$@"; do echo "z${i}z"; done' 'zz zz'
- check 'set "" ""; for i in $@; do echo "z${i}z"; done' ''
- check 'set "a b" c; for i; do echo "z${i}z"; done' 'za bz zcz'
- check 'set "a b" c; for i in "$@"; do echo "z${i}z"; done' 'za bz zcz'
- check 'set "a b" c; for i in $@; do echo "z${i}z"; done' 'zaz zbz zcz'
- check 'set " a b " c; for i in "$@"; do echo "z${i}z"; done' 'z a b z zcz'
- check 'set --; for i in x"$@"x; do echo "z${i}z"; done' 'zxxz'
- check 'set a; for i in x"$@"x; do echo "z${i}z"; done' 'zxaxz'
- check 'set a b; for i in x"$@"x; do echo "z${i}z"; done' 'zxaz zbxz'
+
+ check 'set --; for i in x"$@"x; do echo "z${i}z"; done' 'zxxz'
+ check 'set a; for i in x"$@"x; do echo "z${i}z"; done' 'zxaxz'
+ check 'set a b; for i in x"$@"x; do echo "z${i}z"; done' 'zxaz zbxz'
+
+ check 'set --; for i; do echo "z${i}z"; done' ''
+ check 'set --; for i in $@; do echo "z${i}z"; done' ''
+ check 'set --; for i in "$@"; do echo "z${i}z"; done' ''
+ # atf_expect_fail "PR bin/50834"
+ check 'set --; for i in ""$@; do echo "z${i}z"; done' 'zz'
+ # atf_expect_pass
+ check 'set --; for i in $@""; do echo "z${i}z"; done' 'zz'
+ check 'set --; for i in ""$@""; do echo "z${i}z"; done' 'zz'
+ check 'set --; for i in """$@"; do echo "z${i}z"; done' 'zz'
+ check 'set --; for i in "$@"""; do echo "z${i}z"; done' 'zz'
+ check 'set --; for i in """$@""";do echo "z${i}z"; done' 'zz'
+
+ check 'set ""; for i; do echo "z${i}z"; done' 'zz'
+ check 'set ""; for i in "$@"; do echo "z${i}z"; done' 'zz'
+ check 'set "" ""; for i; do echo "z${i}z"; done' 'zz zz'
+ check 'set "" ""; for i in "$@"; do echo "z${i}z"; done' 'zz zz'
+ check 'set "" ""; for i in $@; do echo "z${i}z"; done' ''
+
+ check 'set "a b" c; for i; do echo "z${i}z"; done' \
+ 'za bz zcz'
+ check 'set "a b" c; for i in "$@"; do echo "z${i}z"; done' \
+ 'za bz zcz'
+ check 'set "a b" c; for i in $@; do echo "z${i}z"; done' \
+ 'zaz zbz zcz'
+ check 'set " a b " c; for i in "$@"; do echo "z${i}z"; done' \
+ 'z a b z zcz'
}
atf_test_case ifs
@@ -143,6 +301,7 @@ ifs_head() {
ifs_body() {
unset x
+ TEST=0
# Some IFS tests
check 't="-- "; IFS=" "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '0'
check 't=" x"; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1'
@@ -165,19 +324,26 @@ var_length_head() {
"a variable's length"
}
var_length_body() {
- unset x
+ TEST=0
- # Check that we apply IFS to ${#var}
long=12345678123456781234567812345678
long=$long$long$long$long
- check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' '128 1 8 3'
- check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2'
- check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1'
+ export long
+
+ # first test that the test method works...
+ check 'set -u; : ${long}; echo ${#long}' '128'
+
+ # Check that we apply IFS to ${#var}
+ check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' \
+ '128 1 8 3'
+ check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2'
+ check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1'
}
atf_init_test_cases() {
atf_add_test_case for
atf_add_test_case default_val
+ atf_add_test_case replacement_val
atf_add_test_case ifs_alpha
atf_add_test_case quote
atf_add_test_case dollar_at
Index: src/tests/bin/sh/t_redir.sh
diff -u src/tests/bin/sh/t_redir.sh:1.3 src/tests/bin/sh/t_redir.sh:1.4
--- src/tests/bin/sh/t_redir.sh:1.3 Tue Mar 1 07:39:35 2016
+++ src/tests/bin/sh/t_redir.sh Tue Mar 8 09:26:54 2016
@@ -1,4 +1,4 @@
-# $NetBSD: t_redir.sh,v 1.3 2016/03/01 12:39:35 christos Exp $
+# $NetBSD: t_redir.sh,v 1.4 2016/03/08 14:26:54 christos Exp $
#
# Copyright (c) 2016 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -27,32 +27,440 @@
# the implementation of "sh" to test
: ${TEST_SH:="/bin/sh"}
+# Any failures in this first test means it is not worth bothering looking
+# for causes of failures in any other tests, make this one work first.
+
+# Problems with this test usually mean inadequate ATF_SHELL used for testing.
+# (though if all pass but the last, it might be a TEST_SH problem.)
+
+atf_test_case basic_test_method_test
+basic_test_method_test_head()
+{
+ atf_set "descr" "Tests that test method works as expected"
+}
+basic_test_method_test_body()
+{
+ cat <<- 'DONE' |
+ DONE
+ atf_check -s exit:0 -o empty -e empty ${TEST_SH}
+ cat <<- 'DONE' |
+ DONE
+ atf_check -s exit:0 -o match:0 -e empty ${TEST_SH} -c 'wc -l'
+
+ cat <<- 'DONE' |
+ echo hello
+ DONE
+ atf_check -s exit:0 -o match:hello -e empty ${TEST_SH}
+ cat <<- 'DONE' |
+ echo hello
+ DONE
+ atf_check -s exit:0 -o match:1 -e empty ${TEST_SH} -c 'wc -l'
+
+ cat <<- 'DONE' |
+ echo hello\
+ world
+ DONE
+ atf_check -s exit:0 -o match:helloworld -e empty ${TEST_SH}
+ cat <<- 'DONE' |
+ echo hello\
+ world
+ DONE
+ atf_check -s exit:0 -o match:2 -e empty ${TEST_SH} -c 'wc -l'
+
+ printf '%s\n%s\n%s\n' Line1 Line2 Line3 > File
+ atf_check -s exit:0 -o inline:'Line1\nLine2\nLine3\n' -e empty \
+ ${TEST_SH} -c 'cat File'
+
+ cat <<- 'DONE' |
+ set -- X "" '' Y
+ echo ARGS="${#}"
+ echo '' -$1- -$2- -$3- -$4-
+ cat <<EOF
+ X=$1
+ EOF
+ cat <<\EOF
+ Y=$4
+ EOF
+ DONE
+ atf_check -s exit:0 -o match:ARGS=4 -o match:'-X- -- -- -Y-' \
+ -o match:X=X -o match:'Y=\$4' -e empty ${TEST_SH}
+}
+
+atf_test_case do_input_redirections
+do_input_redirections_head()
+{
+ atf_set "descr" "Tests that simple input redirection works"
+}
+do_input_redirections_body()
+{
+ printf '%s\n%s\n%s\nEND\n' 'First Line' 'Second Line' 'Line 3' >File
+
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH} -c 'cat < File'
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH} -c 'cat <File'
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH} -c 'cat< File'
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH} -c 'cat < "File"'
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH} -c '< File cat'
+
+ ln File wc
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH} -c '< wc cat'
+
+ mv wc cat
+ atf_check -s exit:0 -e empty -o match:4 \
+ ${TEST_SH} -c '< cat wc'
+
+
+ cat <<- 'EOF' |
+ i=0
+ while [ "$i" -lt 3 ]; do
+ i=$((i + 1))
+ read line < File
+ echo "$line"
+ done
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nFirst Line\nFirst Line\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ i=0
+ while [ "$i" -lt 3 ]; do
+ i=$((i + 1))
+ read line
+ echo "$line"
+ done <File
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ i=0
+ while [ "$i" -lt 3 ]; do
+ i=$((i + 1))
+ read line < File
+ echo "$line"
+ done <File
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nFirst Line\nFirst Line\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ line=
+ while [ "$line" != END ]; do
+ read line || exit 1
+ echo "$line"
+ done <File
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ while :; do
+ read line || exit 0
+ echo "$line"
+ done <File
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ i=0
+ while read line < File
+ do
+ echo "$line"
+ i=$((i + 1))
+ [ ${i} -ge 3 ] && break
+ done
+ echo DONE
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nFirst Line\nFirst Line\nDONE\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ i=0
+ while read line
+ do
+ echo "$line"
+ done <File
+ echo DONE
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nEND\nDONE\n' \
+ ${TEST_SH}
+
+ cat <<- 'EOF' |
+ i=0
+ while read line
+ do
+ echo "$line"
+ i=$((i + 1))
+ [ ${i} -ge 3 ] && break
+ done <File
+ echo DONE
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line\nSecond Line\nLine 3\nDONE\n' ${TEST_SH}
+
+ cat <<- 'EOF' |
+ i=0
+ while read line1 <File
+ do
+ read line2
+ echo "$line1":"$line2"
+ i=$((i + 1))
+ [ ${i} -ge 2 ] && break
+ done <File
+ echo DONE
+ EOF
+ atf_check -s exit:0 -e empty \
+ -o inline:'First Line:First Line\nFirst Line:Second Line\nDONE\n' \
+ ${TEST_SH}
+}
+
+atf_test_case do_output_redirections
+do_output_redirections_head()
+{
+ atf_set "descr" "Test Output redirections"
+}
+do_output_redirections_body()
+{
+nl='
+'
+ T=0
+ i() { T=$(($T + 1)); }
+
+ rm -f Output 2>/dev/null || :
+ test -f Output && atf_fail "Unable to remove Output file"
+#1
+ i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '> Output'
+ test -f Output || atf_fail "#$T: Did not make Output file"
+#2
+ rm -f Output 2>/dev/null || :
+ i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>> Output'
+ test -f Output || atf_fail "#$T: Did not make Output file"
+#3
+ rm -f Output 2>/dev/null || :
+ i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>| Output'
+ test -f Output || atf_fail "#$T: Did not make Output file"
+
+#4
+ rm -f Output 2>/dev/null || :
+ i
+ atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello >Output'
+ test -s Output || atf_fail "#$T: Did not make non-empty Output file"
+ test "$(cat Output)" = "Hello" ||
+ atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
+#5
+ i
+ atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello>!Output'
+ test -s Output || atf_fail "#$T: Did not make non-empty Output file"
+ test "$(cat Output)" = "Hello" ||
+ atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'"
+#6
+ i
+ atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Bye >>Output'
+ test -s Output || atf_fail "#$T: Removed Output file"
+ test "$(cat Output)" = "Hello${nl}Bye" || atf_fail \
+ "#$T: Incorrect Output: Should be 'Hello\\nBye' is '$(cat Output)'"
+#7
+ i; atf_check -s exit:0 -o inline:'line 1\nline 2\n' -e empty \
+ ${TEST_SH} -c \
+ 'echo line 1 > Output; echo line 2 >> Output; cat Output'
+ test "$(cat Output)" = "line 1${nl}line 2" || atf_fail \
+ "#$T: Incorrect Output: Should be 'line 1\\nline 2' is '$(cat Output)'"
+#8
+ i; atf_check -s exit:0 -o inline:'line 2\n' -e empty \
+ ${TEST_SH} -c 'echo line 1 > Output; echo line 2'
+ test "$(cat Output)" = "line 1" || atf_fail \
+ "#$T: Incorrect Output: Should be 'line 1' is '$(cat Output)'"
+#9
+ i; atf_check -s exit:0 -o empty -e empty \
+ ${TEST_SH} -c '(echo line 1; echo line 2 > Out2) > Out1'
+ test "$(cat Out1)" = "line 1" || atf_fail \
+ "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
+ test "$(cat Out2)" = "line 2" || atf_fail \
+ "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
+#10
+ i; atf_check -s exit:0 -o empty -e empty \
+ ${TEST_SH} -c '{ echo line 1; echo line 2 > Out2;} > Out1'
+ test "$(cat Out1)" = "line 1" || atf_fail \
+ "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'"
+ test "$(cat Out2)" = "line 2" || atf_fail \
+ "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'"
+#11
+ i; rm -f Out1 Out2 2>/dev/null || :
+ cat <<- 'EOF' |
+ for arg in 'line 1' 'line 2' 'line 3'
+ do
+ echo "$arg"
+ echo "$arg" > Out1
+ done > Out2
+ EOF
+ atf_check -s exit:0 -o empty -e empty ${TEST_SH}
+ test "$(cat Out1)" = "line 3" || atf_fail \
+ "#$T: Incorrect Out1: Should be 'line 3' is '$(cat Out1)'"
+ test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
+ "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
+#12
+ i; rm -f Out1 Out2 2>/dev/null || :
+ cat <<- 'EOF' |
+ for arg in 'line 1' 'line 2' 'line 3'
+ do
+ echo "$arg"
+ echo "$arg" >> Out1
+ done > Out2
+ EOF
+ atf_check -s exit:0 -o empty -e empty ${TEST_SH}
+ test "$(cat Out1)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
+ "#$T: Incorrect Out1: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out1)'"
+ test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \
+ "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'"
+}
+
+atf_test_case fd_redirections
+fd_redirections_head()
+{
+ atf_set "descr" "Tests redirections to/from specific descriptors"
+}
+fd_redirections_body()
+{
+ # Or it will one day...
+}
+
+atf_test_case local_redirections
+local_redirections_head()
+{
+ atf_set "descr" \
+ "Tests that exec can reassign file descriptors in the shell itself"
+}
+local_redirections_body()
+{
+ # Or it will one day...
+}
+
atf_test_case redir_in_case
-redir_in_case_head() {
- atf_set "descr" "Tests that sh(1) allows plain redirections " \
+redir_in_case_head()
+{
+ atf_set "descr" "Tests that sh(1) allows just redirections " \
"in case statements. (PR bin/48631)"
}
-redir_in_case_body() {
+redir_in_case_body()
+{
atf_check -s exit:0 -o empty -e empty \
${TEST_SH} -c 'case x in (whatever) >foo;; esac'
+
+ atf_check -s exit:0 -o empty -e empty \
+ ${TEST_SH} -c 'case x in (whatever) >foo 2>&1;; esac'
+
+ atf_check -s exit:0 -o empty -e empty \
+ ${TEST_SH} -c 'case x in (whatever) >foo 2>&1 </dev/null;; esac'
+
+ atf_check -s exit:0 -o empty -e empty \
+ ${TEST_SH} -c 'case x in (whatever) >${somewhere};; esac'
}
+atf_test_case incorrect_redirections
+incorrect_redirections_head()
+{
+ atf_set "descr" "Tests that sh(1) correctly ignores non-redirections"
+}
+incorrect_redirections_body() {
+
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo>'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'read foo<'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo<>'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'echo x > '"$nl"
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'read x < '"$nl"
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'echo x <> '"$nl"
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'echo x >< anything'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'echo x >>< anything'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'echo x >|< anything'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'echo x > ; read x < /dev/null || echo bad'
+ atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
+ 'read x < & echo y > /dev/null; wait && echo bad'
+
+ rm -f Output 2>/dev/null || :
+ atf_check -s exit:0 -e empty -o inline:'A Line > Output\n' \
+ ${TEST_SH} -c 'echo A Line \> Output'
+ test -f Output && atf_file "File 'Output' appeared and should not have"
+
+ rm -f Output 2>/dev/null || :
+ atf_check -s exit:0 -e empty -o empty \
+ ${TEST_SH} -c 'echo A Line \>> Output'
+ test -f Output || atf_file "File 'Output' not created when it should"
+ test "$(cat Output)" = 'A Line >' || atf_fail \
+ "Output file contains '$(cat Output)' instead of '"'A Line >'\'
+
+ rm -f Output \> 2>/dev/null || :
+ atf_check -s exit:0 -e empty -o empty \
+ ${TEST_SH} -c 'echo A Line >\> Output'
+ test -f Output && atf_file "File 'Output' appeared and should not have"
+ test -f '>' || atf_file "File '>' not created when it should"
+ test "$(cat '>')" = 'A Line Output' || atf_fail \
+ "Output file ('>') contains '$(cat '>')' instead of 'A Line Output'"
+}
+
+# Many more tests in t_here, so here we have just rudimentary checks
atf_test_case redir_here_doc
-redir_here_doc_head() {
+redir_here_doc_head()
+{
atf_set "descr" "Tests that sh(1) correctly processes 'here' doc " \
"input redirections"
}
-redir_here_doc_body() {
-
+redir_here_doc_body()
+{
+ # nb: the printf is not executed, it is data
cat <<- 'DONE' |
cat <<EOF
printf '%s\n' 'hello\n'
EOF
DONE
- atf_check -s exit:0 -o match:'hello\\n' -e empty ${TEST_SH}
+ atf_check -s exit:0 -o match:printf -o match:'hello\\n' \
+ -e empty ${TEST_SH}
+}
+
+atf_test_case subshell_redirections
+subshell_redirections_head()
+{
+ atf_set "descr" "Tests redirection interactions between shell and " \
+ "its sub-shell(s)"
+}
+subshell_redirections_body()
+{
+ # Or will, one day
}
atf_init_test_cases() {
- atf_add_test_case redir_in_case
+ atf_add_test_case basic_test_method_test
+ atf_add_test_case do_input_redirections
+ atf_add_test_case do_output_redirections
+ atf_add_test_case fd_redirections
+ atf_add_test_case local_redirections
+ atf_add_test_case incorrect_redirections
atf_add_test_case redir_here_doc
+ atf_add_test_case redir_in_case
+ atf_add_test_case subshell_redirections
}