1313498Sngie# $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#
27313498Sngie# the implementation of "sh" to test
28313498Sngie: ${TEST_SH:="/bin/sh"}
29272343Sngie
30272343Sngie
31272343Sngieatf_test_case background
32272343Sngiebackground_head() {
33272343Sngie	atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \
34313498Sngie			"a command in the background (PR bin/46327)"
35272343Sngie}
36272343Sngiebackground_body() {
37313498Sngie	atf_check -o match:0 -e empty ${TEST_SH} -c 'true; true & echo $?'
38313498Sngie	# atf_expect_fail "PR bin/46327" (now fixed?)
39313498Sngie	atf_check -o match:0 -e empty ${TEST_SH} -c 'false; true & echo $?'
40272343Sngie}
41272343Sngie
42272343Sngieatf_test_case function
43272343Sngiefunction_head() {
44313498Sngie	atf_set "descr" "Tests that \$? is correctly updated inside " \
45313498Sngie			"a function"
46272343Sngie}
47272343Sngiefunction_body() {
48313498Sngie	atf_check -s exit:0 -o match:STATUS=1-0 -e empty \
49313498Sngie		${TEST_SH} -c '
50313498Sngie			crud() {
51313498Sngie				test yes = no
52313498Sngie
53313498Sngie				cat <<-EOF
54313498Sngie				STATUS=$?
55313498Sngie				EOF
56313498Sngie			}
57313498Sngie			foo=$(crud)
58313498Sngie			echo "${foo}-$?"
59313498Sngie		'
60272343Sngie}
61272343Sngie
62272343Sngieatf_test_case readout
63272343Sngiereadout_head() {
64313498Sngie	atf_set "descr" "Tests that \$? is correctly updated in a " \
65313498Sngie			"compound expression"
66272343Sngie}
67272343Sngiereadout_body() {
68313498Sngie	atf_check -s exit:0 -o match:0 -e empty \
69313498Sngie		${TEST_SH} -c 'true && ! true | false; echo $?'
70272343Sngie}
71272343Sngie
72272343Sngieatf_test_case trap_subshell
73272343Sngietrap_subshell_head() {
74313498Sngie	atf_set "descr" "Tests that the trap statement in a subshell " \
75313498Sngie			"works when the subshell exits"
76272343Sngie}
77272343Sngietrap_subshell_body() {
78313498Sngie	atf_check -s exit:0 -o inline:'exiting\n' -e empty \
79313498Sngie	    ${TEST_SH} -c '( trap "echo exiting" EXIT; /usr/bin/true )'
80272343Sngie}
81272343Sngie
82272343Sngieatf_test_case trap_zero__implicit_exit
83313498Sngietrap_zero__implicit_exit_head() {
84313498Sngie	atf_set "descr" "Tests that the trap statement in a subshell in a " \
85313498Sngie		"script works when the subshell simply runs out of commands"
86313498Sngie}
87272343Sngietrap_zero__implicit_exit_body() {
88313498Sngie	# PR bin/6764: sh works but ksh does not
89272343Sngie	echo '( trap "echo exiting" 0 )' >helper.sh
90313498Sngie	atf_check -s exit:0 -o match:exiting -e empty ${TEST_SH} helper.sh
91313498Sngie	# test ksh by setting TEST_SH to /bin/ksh and run the entire set...
92313498Sngie	# atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh
93272343Sngie}
94272343Sngie
95272343Sngieatf_test_case trap_zero__explicit_exit
96313498Sngietrap_zero__explicit_exit_head() {
97313498Sngie	atf_set "descr" "Tests that the trap statement in a subshell in a " \
98313498Sngie		"script works when the subshell executes an explicit exit"
99313498Sngie}
100272343Sngietrap_zero__explicit_exit_body() {
101313498Sngie	echo '( trap "echo exiting" 0; exit; echo NO_NO_NO )' >helper.sh
102313498Sngie	atf_check -s exit:0 -o match:exiting -o not-match:NO_NO -e empty \
103313498Sngie		${TEST_SH} helper.sh
104313498Sngie	# test ksh by setting TEST_SH to /bin/ksh and run the entire set...
105313498Sngie	# atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh
106272343Sngie}
107272343Sngie
108313498Sngieatf_test_case simple_exit
109313498Sngiesimple_exit_head() {
110313498Sngie	atf_set "descr" "Tests that various values for exit status work"
111272343Sngie}
112313498Sngie# Note: ATF will not allow tests of exit values > 255, even if they would work
113313498Sngiesimple_exit_body() {
114313498Sngie	for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255
115313498Sngie	do
116313498Sngie		atf_check -s exit:$N -o empty -e empty \
117313498Sngie			${TEST_SH} -c "exit $N; echo FOO; echo BAR >&2"
118313498Sngie	done
119313498Sngie}
120272343Sngie
121313498Sngieatf_test_case subshell_exit
122313498Sngiesubshell_exit_head() {
123313498Sngie	atf_set "descr" "Tests that subshell exit status works and \$? gets it"
124313498Sngie}
125313498Sngie# Note: ATF will not allow tests of exit values > 255, even if they would work
126313498Sngiesubshell_exit_body() {
127313498Sngie	for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255
128313498Sngie	do
129313498Sngie		atf_check -s exit:0 -o empty -e empty \
130313498Sngie			${TEST_SH} -c "(exit $N); test \$? -eq $N"
131313498Sngie	done
132313498Sngie}
133313498Sngie
134313498Sngieatf_test_case subshell_background
135313498Sngiesubshell_background_head() {
136313498Sngie	atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \
137313498Sngie			"a subshell in the background"
138313498Sngie}
139313498Sngiesubshell_background_body() {
140313498Sngie	atf_check -o match:0 -e empty \
141313498Sngie		${TEST_SH} -c 'true; (false || true) & echo $?'
142313498Sngie	# atf_expect_fail "PR bin/46327" (now fixed?)
143313498Sngie	atf_check -o match:0 -e empty \
144313498Sngie		${TEST_SH} -c 'false; (false || true) & echo $?'
145313498Sngie}
146313498Sngie
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
154313498Sngie	atf_add_test_case simple_exit
155313498Sngie	atf_add_test_case subshell_exit
156313498Sngie	atf_add_test_case subshell_background
157272343Sngie}
158