@matheusbsbs / matheus-bagliano / commits / b6b0afdc30
Fork 0

test-lib: some shells do not let $? propagate into an eval

In 3bf7886 (test-lib: Let tests specify commands to be run at end of test, 2010-05-02), the git test harness learned to run cleanup commands unconditionally at the end of a test. During each test, the intended cleanup actions are collected in the test_cleanup variable and evaluated. That variable looks something like this: eval_ret=$?; clean_something && (exit "$eval_ret") eval_ret=$?; clean_something_else && (exit "$eval_ret") eval_ret=$?; final_cleanup && (exit "$eval_ret") eval_ret=$? All cleanup actions are run unconditionally but if one of them fails it is properly reported through $eval_ret. On FreeBSD, unfortunately, $? is set at the beginning of an ‘eval’ to 0 instead of the exit status of the previous command. This results in tests using test_expect_code appearing to fail and all others appearing to pass, unless their cleanup fails. Avoid the problem by setting eval_ret before the ‘eval’ begins. Thanks to Jeff King for the explanation. Cc: Jeff King <peff@peff.net> Cc: Johannes Sixt <j6t@kdbg.org> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Nieder committed May 6, 2010 at 03:41 UTC b6b0afdc30e066788592ca07c9a6c6936c68cc11
2 files changed +25 -3
t/t0000-basic.sh
+21
@@ -73,6 +73,27 @@ then
73 exit 1
74 fi
75
76 +clean=no
77 +test_expect_success 'tests clean up after themselves' '
78 + test_when_finished clean=yes
79 +'
80 +
81 +cleaner=no
82 +test_expect_code 1 'tests clean up even after a failure' '
83 + test_when_finished cleaner=yes &&
84 + (exit 1)
85 +'
86 +
87 +if test $clean$cleaner != yesyes
88 +then
89 + say "bug in test framework: cleanup commands do not work reliably"
90 + exit 1
91 +fi
92 +
93 +test_expect_code 2 'failure to clean up causes the test to fail' '
94 + test_when_finished "(exit 2)"
95 +'
96 +
97 ################################################################
98 # Basics of the basics
99
t/test-lib.sh
+4 -3
@@ -366,8 +366,9 @@ test_debug () {
366 }
367
368 test_run_ () {
369 - test_cleanup='eval_ret=$?'
369 + test_cleanup=:
370 eval >&3 2>&4 "$1"
371 + eval_ret=$?
372 eval >&3 2>&4 "$test_cleanup"
373 return 0
374 }
@@ -567,8 +568,8 @@ test_cmp() {
568 # the test to pass.
569
570 test_when_finished () {
570 - test_cleanup="eval_ret=\$?; { $*
571 - } && (exit \"\$eval_ret\"); $test_cleanup"
571 + test_cleanup="{ $*
572 + } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
573 }
574
575 # Most tests can use the created repository, but some may need to create more.