Bash · 4295 bytes Raw Blame History
1 #!/bin/sh
2 TEST_PREFIX="[int-error-handling]"
3 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
4 SHELL_BIN="${SHELL_BIN:?ERROR: SHELL_BIN must be set}"
5 export SHELL_BIN
6 . "$SCRIPT_DIR/../test_harness.sh"
7
8 # Integration tests: error handling with set -e, pipefail, and error propagation
9
10 section "1. set -e (errexit) basics"
11 compare_output "no error continues" 'set -e; true; echo reached'
12 compare_exit "error exits" 'set -e; false; echo unreachable'
13 compare_output "OR suppresses errexit" 'set -e; false || true; echo reached'
14 compare_output "if condition doesnt trigger" 'set -e; if false; then :; fi; echo reached'
15 compare_output "while condition doesnt trigger" 'set -e; while false; do :; done; echo reached'
16 compare_output "negation doesnt trigger" 'set -e; ! false; echo reached'
17 compare_output "AND left fail doesnt exit alone" 'set -e; false && true; echo reached'
18 compare_output "set +e disables" 'set -e; set +e; false; echo reached'
19 compare_output "errexit with command sub" 'set -e; echo $(true); echo reached'
20
21 section "2. set -e in subshells"
22 compare_output "subshell error exits subshell" 'set -e; (false) || echo recovered'
23 compare_exit "errexit in subshell" '(set -e; false; echo unreachable)'
24 compare_output "errexit subshell status" '(set -e; false; echo unreachable); echo $?'
25 compare_output "parent errexit child fails" 'set -e; (false) || true; echo reached'
26
27 section "3. set -e in functions"
28 compare_exit "errexit function fails" 'set -e; f() { false; echo unreachable; }; f; echo after'
29 compare_exit "errexit inside function" 'f() { set -e; false; echo unreachable; }; f'
30 compare_output "errexit function in conditional" 'set -e; f() { false; }; if f; then echo yes; else echo no; fi; echo after'
31 compare_output "errexit with return" 'set -e; f() { return 1; }; f || echo caught; echo after'
32
33 section "4. pipefail"
34 compare_output "pipefail first fails" 'set -o pipefail; false | true; echo $?'
35 compare_output "pipefail middle fails" 'set -o pipefail; true | false | true; echo $?'
36 compare_output "pipefail all succeed" 'set -o pipefail; true | true; echo $?'
37 compare_output "pipefail all fail" 'set -o pipefail; false | false; echo $?'
38 compare_exit "errexit plus pipefail" 'set -eo pipefail; false | true; echo unreachable'
39 compare_output "pipefail disabled by default" 'false | true; echo $?'
40 compare_output "pipefail with echo" 'set -o pipefail; echo hello | true; echo $?'
41
42 section "5. error propagation"
43 compare_output "function return status" 'f() { return 1; }; f; echo $?'
44 compare_output "subshell exit status" '(exit 2); echo $?'
45 compare_output "eval preserves status" 'eval "false"; echo $?'
46 compare_output "eval true status" 'eval "true"; echo $?'
47 compare_output "source preserves status" "echo 'false' > $TEST_TMPDIR/efalse.sh; source $TEST_TMPDIR/efalse.sh; echo \$?"
48 compare_output "cmd sub status" 'X=$(false); echo $?'
49 compare_output "cmd sub true status" 'X=$(true); echo $?'
50 compare_output "last in pipeline" 'true | false; echo $?'
51 compare_output "negated status" '! true; echo $?'
52 compare_output "negated false status" '! false; echo $?'
53
54 section "6. builtin error handling"
55 compare_output "cd failure" 'cd /nonexistent_xyz 2>/dev/null; echo $?'
56 compare_output "source failure" 'source /nonexistent_file.sh 2>/dev/null; echo $?'
57 compare_exit "readonly violation" 'readonly ERX=1; ERX=2 2>/dev/null'
58 compare_output "unset readonly" 'readonly ERY=1; unset ERY 2>/dev/null; echo $?'
59 compare_output "command not found" 'nonexistent_cmd_xyz 2>/dev/null; echo $?'
60 compare_output "read with no input" 'read VAR < /dev/null; echo $?'
61 compare_output "test failure" 'test 1 -eq 2; echo $?'
62 compare_output "false builtin" 'false; echo $?'
63 compare_output "true builtin" 'true; echo $?'
64
65 section "7. set -e with conditionals (should NOT exit)"
66 compare_output "set -e if false" 'set -e; if false; then echo yes; fi; echo reached'
67 compare_output "set -e while false" 'set -e; while false; do echo no; done; echo reached'
68 compare_output "set -e until true" 'set -e; until true; do echo no; done; echo reached'
69 compare_output "set -e test in if" 'set -e; if test 1 -eq 2; then echo no; fi; echo reached'
70 compare_output "set -e bracket in if" 'set -e; if [ 1 -eq 2 ]; then echo no; fi; echo reached'
71 compare_output "set -e negation" 'set -e; ! false; echo reached'
72
73 print_summary