Home | History | Annotate | Line # | Download | only in sh
t_shift.sh revision 1.2
      1  1.2       kre # $NetBSD: t_shift.sh,v 1.2 2016/05/17 09:05:14 kre Exp $
      2  1.1  christos #
      3  1.1  christos # Copyright (c) 2016 The NetBSD Foundation, Inc.
      4  1.1  christos # All rights reserved.
      5  1.1  christos #
      6  1.1  christos # Redistribution and use in source and binary forms, with or without
      7  1.1  christos # modification, are permitted provided that the following conditions
      8  1.1  christos # are met:
      9  1.1  christos # 1. Redistributions of source code must retain the above copyright
     10  1.1  christos #    notice, this list of conditions and the following disclaimer.
     11  1.1  christos # 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  christos #    notice, this list of conditions and the following disclaimer in the
     13  1.1  christos #    documentation and/or other materials provided with the distribution.
     14  1.1  christos #
     15  1.1  christos # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     16  1.1  christos # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17  1.1  christos # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  1.1  christos # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     19  1.1  christos # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  1.1  christos # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  1.1  christos # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  1.1  christos # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  1.1  christos # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  1.1  christos # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  christos # POSSIBILITY OF SUCH DAMAGE.
     26  1.1  christos #
     27  1.1  christos # the implementation of "sh" to test
     28  1.1  christos : ${TEST_SH:="/bin/sh"}
     29  1.1  christos 
     30  1.1  christos atf_test_case basic_shift_test
     31  1.1  christos basic_shift_test_head() {
     32  1.1  christos 	atf_set "descr" "Test correct operation of valid shifts"
     33  1.1  christos }
     34  1.1  christos basic_shift_test_body() {
     35  1.1  christos 
     36  1.1  christos 	for a in			\
     37  1.1  christos 	  "one-arg::0:one-arg"		\
     38  1.1  christos 	  "one-arg:1:0:one-arg"		\
     39  1.1  christos 	  "one-arg:0:1 one-arg"		\
     40  1.1  christos 	  "a b c::2 b c:a"		\
     41  1.1  christos 	  "a b c:1:2 b c:a"		\
     42  1.1  christos 	  "a b c:2:1 c:a:b"		\
     43  1.1  christos 	  "a b c:3:0:a:b:c"		\
     44  1.1  christos 	  "a b c:0:3 a b c"		\
     45  1.1  christos 	  "a b c d e f g h i j k l m n o p:1:15 b c d e f g h i j k l m n o p"\
     46  1.1  christos 	  "a b c d e f g h i j k l m n o p:9:7 j k l m n o p:a:b:c:g:h:i"     \
     47  1.1  christos 	  "a b c d e f g h i j k l m n o p:13:3 n o p:a:b:c:d:k:l:m"	      \
     48  1.1  christos 	  "a b c d e f g h i j k l m n o p:16:0:a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p"
     49  1.1  christos 	do
     50  1.1  christos 		oIFS="${IFS}"
     51  1.1  christos 		IFS=:; set -- $a
     52  1.1  christos 		IFS="${oIFS}"
     53  1.1  christos 
     54  1.1  christos 		init="$1"; n="$2"; res="$3"; shift 3
     55  1.1  christos 
     56  1.1  christos 		not=
     57  1.1  christos 		for b
     58  1.1  christos 		do
     59  1.1  christos 			not="${not} -o not-match:$b"
     60  1.1  christos 		done
     61  1.1  christos 
     62  1.1  christos 		atf_check -s exit:0 -o "match:${res}" ${not} -e empty \
     63  1.1  christos 			${TEST_SH} -c "set -- ${init}; shift $n;"' echo "$# $*"'
     64  1.1  christos 	done
     65  1.1  christos 
     66  1.1  christos 	atf_check -s exit:0 -o match:complete -o not-match:ERR -e empty \
     67  1.1  christos 		${TEST_SH} -c \
     68  1.1  christos     'set -- a b c d e;while [ $# -gt 0 ];do shift||echo ERR;done;echo complete'
     69  1.1  christos }
     70  1.1  christos 
     71  1.1  christos atf_test_case excessive_shift
     72  1.1  christos excessive_shift_head() {
     73  1.1  christos 	atf_set "descr" "Test acceptable operation of shift too many"
     74  1.1  christos }
     75  1.1  christos # In:
     76  1.1  christos #
     77  1.1  christos #	http://pubs.opengroup.org/onlinepubs/9699919799
     78  1.1  christos #		/utilities/V3_chap02.html#tag_18_26_01
     79  1.1  christos #
     80  1.1  christos # (that URL should be one line, with the /util... immediately after ...9799)
     81  1.1  christos #
     82  1.1  christos # POSIX says of shift (in the "EXIT STATUS" paragraph):
     83  1.1  christos #
     84  1.1  christos #  If the n operand is invalid or is greater than "$#", this may be considered
     85  1.1  christos #  a syntax error and a non-interactive shell may exit; if the shell does not
     86  1.1  christos #  exit in this case, a non-zero exit status shall be returned.
     87  1.1  christos #  Otherwise, zero shall be returned.
     88  1.1  christos #
     89  1.1  christos # NetBSD's sh treats it as an error and exits (if non-interactive, as here),
     90  1.1  christos # other shells do not.
     91  1.1  christos #
     92  1.1  christos # Either behaviour is acceptable - so the test allows for both
     93  1.1  christos # (and checks that if the shell does not exit, "shift" returns status != 0)
     94  1.1  christos 
     95  1.1  christos excessive_shift_body() {
     96  1.1  christos 	for a in				\
     97  1.1  christos 		"one-arg:2"			\
     98  1.1  christos 		"one-arg:4"			\
     99  1.1  christos 		"one-arg:13"			\
    100  1.1  christos 		"one two:3"			\
    101  1.1  christos 		"one two:7"			\
    102  1.1  christos 		"one two three four five:6"	\
    103  1.1  christos 		"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:16"	\
    104  1.1  christos 		"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:17"	\
    105  1.1  christos 		"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:30"	\
    106  1.1  christos 		"I II III IV V VI VII VIII IX X XI XII XIII XIV XV:9999"
    107  1.1  christos 	do
    108  1.1  christos 		oIFS="${IFS}"
    109  1.1  christos 		IFS=:; set -- $a
    110  1.1  christos 		IFS="${oIFS}"
    111  1.1  christos 
    112  1.1  christos 		atf_check -s not-exit:0 -o match:OK -o not-match:ERR \
    113  1.1  christos 			-e ignore ${TEST_SH} -c \
    114  1.1  christos 			"set -- $1 ;"'echo OK:$#-'"$2;shift $2 && echo ERR"
    115  1.1  christos 	done
    116  1.1  christos }
    117  1.1  christos 
    118  1.1  christos atf_test_case function_shift
    119  1.1  christos function_shift_head() {
    120  1.1  christos 	atf_set "descr" "Test that shift in a function does not affect outside"
    121  1.1  christos }
    122  1.1  christos function_shift_body() {
    123  1.2       kre 	: # later...
    124  1.1  christos }
    125  1.1  christos 
    126  1.1  christos atf_test_case non_numeric_shift
    127  1.1  christos non_numeric_shift_head() {
    128  1.1  christos 	atf_set "descr" "Test that non-numeric args to shift are detected"
    129  1.1  christos }
    130  1.1  christos 
    131  1.1  christos # from the DESCRIPTION section at the URL mentioned with the excessive_shift
    132  1.1  christos # test:
    133  1.1  christos #
    134  1.1  christos #	The value n shall be an unsigned decimal integer ...
    135  1.1  christos #
    136  1.1  christos # That is not hex (octal will be treated as if it were decimal, a leading 0
    137  1.1  christos # will simply be ignored - we test for this by giving an "octal" value that
    138  1.1  christos # would be OK if parsed as octal, but not if parsed (correctly) as decimal)
    139  1.1  christos #
    140  1.1  christos # Obviously total trash like roman numerals or alphabetic strings are out.
    141  1.1  christos #
    142  1.1  christos # Also no signed values (no + or -) and not a string that looks kind of like
    143  1.1  christos # a number,  but only if you're generous
    144  1.1  christos #
    145  1.1  christos # But as the EXIT STATUS section quoted above says, with an invalid 'n'
    146  1.1  christos # the shell has the option of exiting, or returning status != 0, so
    147  1.1  christos # again this test allows both.
    148  1.1  christos 
    149  1.1  christos non_numeric_shift_body() {
    150  1.1  christos 
    151  1.1  christos 	# there are 9 args set, 010 is 8 if parsed octal, 10 decimal
    152  1.1  christos 	for a in a I 0x12 010 5V -1 ' ' '' +1 ' 1'
    153  1.1  christos 	do
    154  1.1  christos 		atf_check -s not-exit:0 -o empty -e ignore ${TEST_SH} -c \
    155  1.1  christos 			"set -- a b c d e f g h i; shift '$a' && echo ERROR"
    156  1.1  christos 	done
    157  1.1  christos }
    158  1.1  christos 
    159  1.1  christos atf_test_case too_many_args
    160  1.1  christos too_many_args_head() {
    161  1.1  christos 	# See PR bin/50896
    162  1.1  christos 	atf_set "descr" "Test that sh detects invalid extraneous args to shift"
    163  1.1  christos }
    164  1.1  christos # This is a syntax error, a non-interactive shell (us) must exit $? != 0
    165  1.1  christos too_many_args_body() {
    166  1.1  christos 	# This tests the bug in PR bin/50896 is fixed
    167  1.1  christos 
    168  1.1  christos 	for a in "1 1" "1 0" "1 2 3" "1 foo" "1 --" "-- 1"
    169  1.1  christos 	do
    170  1.1  christos 		atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    171  1.1  christos 			" set -- a b c d; shift ${a} ; echo FAILED "
    172  1.1  christos 	done
    173  1.1  christos }
    174  1.1  christos 
    175  1.1  christos atf_init_test_cases() {
    176  1.1  christos 	atf_add_test_case basic_shift_test
    177  1.1  christos 	atf_add_test_case excessive_shift
    178  1.1  christos 	atf_add_test_case function_shift
    179  1.1  christos 	atf_add_test_case non_numeric_shift
    180  1.1  christos 	atf_add_test_case too_many_args
    181  1.1  christos }
    182