1309466Sngie# $NetBSD: t_exit.sh,v 1.6 2016/05/07 23:51:30 kre Exp $
2272343Sngie#
3272343Sngie# Copyright (c) 2007 The NetBSD Foundation, Inc.
4272343Sngie# All rights reserved.
5272343Sngie#
6272343Sngie# Redistribution and use in source and binary forms, with or without
7272343Sngie# modification, are permitted provided that the following conditions
8272343Sngie# are met:
9272343Sngie# 1. Redistributions of source code must retain the above copyright
10272343Sngie#    notice, this list of conditions and the following disclaimer.
11272343Sngie# 2. Redistributions in binary form must reproduce the above copyright
12272343Sngie#    notice, this list of conditions and the following disclaimer in the
13272343Sngie#    documentation and/or other materials provided with the distribution.
14272343Sngie#
15272343Sngie# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16272343Sngie# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17272343Sngie# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18272343Sngie# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19272343Sngie# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20272343Sngie# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21272343Sngie# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22272343Sngie# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23272343Sngie# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24272343Sngie# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25272343Sngie# POSSIBILITY OF SUCH DAMAGE.
26272343Sngie#
27309466Sngie# the implementation of "sh" to test
28309466Sngie: ${TEST_SH:="/bin/sh"}
29272343Sngie
30272343Sngie
31272343Sngieatf_test_case background
32272343Sngiebackground_head() {
33272343Sngie	atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \
34309466Sngie			"a command in the background (PR bin/46327)"
35272343Sngie}
36272343Sngiebackground_body() {
37309466Sngie	atf_check -o match:0 -e empty ${TEST_SH} -c 'true; true & echo $?'
38309466Sngie	# atf_expect_fail "PR bin/46327" (now fixed?)
39309466Sngie	atf_check -o match:0 -e empty ${TEST_SH} -c 'false; true & echo $?'
40272343Sngie}
41272343Sngie
42272343Sngieatf_test_case function
43272343Sngiefunction_head() {
44309466Sngie	atf_set "descr" "Tests that \$? is correctly updated inside " \
45309466Sngie			"a function"
46272343Sngie}
47272343Sngiefunction_body() {
48309466Sngie	atf_check -s exit:0 -o match:STATUS=1-0 -e empty \
49309466Sngie		${TEST_SH} -c '
50309466Sngie			crud() {
51309466Sngie				test yes = no
52309466Sngie
53309466Sngie				cat <<-EOF
54309466Sngie				STATUS=$?
55309466Sngie				EOF
56309466Sngie			}
57309466Sngie			foo=$(crud)
58309466Sngie			echo "${foo}-$?"
59309466Sngie		'
60272343Sngie}
61272343Sngie
62272343Sngieatf_test_case readout
63272343Sngiereadout_head() {
64309466Sngie	atf_set "descr" "Tests that \$? is correctly updated in a " \
65309466Sngie			"compound expression"
66272343Sngie}
67272343Sngiereadout_body() {
68309466Sngie	atf_check -s exit:0 -o match:0 -e empty \
69309466Sngie		${TEST_SH} -c 'true && ! true | false; echo $?'
70272343Sngie}
71272343Sngie
72272343Sngieatf_test_case trap_subshell
73272343Sngietrap_subshell_head() {
74309466Sngie	atf_set "descr" "Tests that the trap statement in a subshell " \
75309466Sngie			"works when the subshell exits"
76272343Sngie}
77272343Sngietrap_subshell_body() {
78309466Sngie	atf_check -s exit:0 -o inline:'exiting\n' -e empty \
79309466Sngie	    ${TEST_SH} -c '( trap "echo exiting" EXIT; /usr/bin/true )'
80272343Sngie}
81272343Sngie
82272343Sngieatf_test_case trap_zero__implicit_exit
83309466Sngietrap_zero__implicit_exit_head() {
84309466Sngie	atf_set "descr" "Tests that the trap statement in a subshell in a " \
85309466Sngie		"script works when the subshell simply runs out of commands"
86309466Sngie}
87272343Sngietrap_zero__implicit_exit_body() {
88309466Sngie	# PR bin/6764: sh works but ksh does not
89272343Sngie	echo '( trap "echo exiting" 0 )' >helper.sh
90309466Sngie	atf_check -s exit:0 -o match:exiting -e empty ${TEST_SH} helper.sh
91309466Sngie	# test ksh by setting TEST_SH to /bin/ksh and run the entire set...
92309466Sngie	# atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh
93272343Sngie}
94272343Sngie
95272343Sngieatf_test_case trap_zero__explicit_exit
96309466Sngietrap_zero__explicit_exit_head() {
97309466Sngie	atf_set "descr" "Tests that the trap statement in a subshell in a " \
98309466Sngie		"script works when the subshell executes an explicit exit"
99309466Sngie}
100272343Sngietrap_zero__explicit_exit_body() {
101309466Sngie	echo '( trap "echo exiting" 0; exit; echo NO_NO_NO )' >helper.sh
102309466Sngie	atf_check -s exit:0 -o match:exiting -o not-match:NO_NO -e empty \
103309466Sngie		${TEST_SH} helper.sh
104309466Sngie	# test ksh by setting TEST_SH to /bin/ksh and run the entire set...
105309466Sngie	# atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh
106272343Sngie}
107272343Sngie
108309466Sngieatf_test_case simple_exit
109309466Sngiesimple_exit_head() {
110309466Sngie	atf_set "descr" "Tests that various values for exit status work"
111272343Sngie}
112309466Sngie# Note: ATF will not allow tests of exit values > 255, even if they would work
113309466Sngiesimple_exit_body() {
114309466Sngie	for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255
115309466Sngie	do
116309466Sngie		atf_check -s exit:$N -o empty -e empty \
117309466Sngie			${TEST_SH} -c "exit $N; echo FOO; echo BAR >&2"
118309466Sngie	done
119309466Sngie}
120272343Sngie
121309466Sngieatf_test_case subshell_exit
122309466Sngiesubshell_exit_head() {
123309466Sngie	atf_set "descr" "Tests that subshell exit status works and \$? gets it"
124309466Sngie}
125309466Sngie# Note: ATF will not allow tests of exit values > 255, even if they would work
126309466Sngiesubshell_exit_body() {
127309466Sngie	for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255
128309466Sngie	do
129309466Sngie		atf_check -s exit:0 -o empty -e empty \
130309466Sngie			${TEST_SH} -c "(exit $N); test \$? -eq $N"
131309466Sngie	done
132309466Sngie}
133309466Sngie
134309466Sngieatf_test_case subshell_background
135309466Sngiesubshell_background_head() {
136309466Sngie	atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \
137309466Sngie			"a subshell in the background"
138309466Sngie}
139309466Sngiesubshell_background_body() {
140309466Sngie	atf_check -o match:0 -e empty \
141309466Sngie		${TEST_SH} -c 'true; (false || true) & echo $?'
142309466Sngie	# atf_expect_fail "PR bin/46327" (now fixed?)
143309466Sngie	atf_check -o match:0 -e empty \
144309466Sngie		${TEST_SH} -c 'false; (false || true) & echo $?'
145309466Sngie}
146309466Sngie
147272343Sngieatf_init_test_cases() {
148272343Sngie	atf_add_test_case background
149272343Sngie	atf_add_test_case function
150272343Sngie	atf_add_test_case readout
151272343Sngie	atf_add_test_case trap_subshell
152272343Sngie	atf_add_test_case trap_zero__implicit_exit
153272343Sngie	atf_add_test_case trap_zero__explicit_exit
154309466Sngie	atf_add_test_case simple_exit
155309466Sngie	atf_add_test_case subshell_exit
156309466Sngie	atf_add_test_case subshell_background
157272343Sngie}
158