test(xce-test-rc-file): task 3.2 end-to-end rc-file failure handling
Extends test_rcfile_integration.sh with 2 scenarios proving Requirements 3.1-3.4: a failing rc-file command in piped/scripted mode aborts before any of the piped script's own commands run, exiting nonzero; the same failing command in an interactive session still reports the failure, continues executing the rc file's remaining lines, and reaches the normal prompt -- while still carrying the session's sticky nonzero exit-code verdict (g_session_failed is never cleared, matching how any other failing-command-then-quit interactive session already behaves). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AgYRU3zDTqNGV5Jk8aiKLg
This commit is contained in:
parent
d258aa3d91
commit
19bc819204
2 changed files with 97 additions and 6 deletions
|
|
@ -15,12 +15,11 @@
|
|||
# test_rcfile_takes_effect_interactive() Req 1.1, 1.2, 1.4, 1.5, 2.3
|
||||
# test_norc_skips_rcfile() Req 2.1, 2.3
|
||||
#
|
||||
# Task 3.2 (a LATER task, NOT implemented by this file) is expected to append
|
||||
# below, reusing the same setup_rc_home/cleanup_rc_home/run_piped/
|
||||
# run_interactive_pty helpers and the same pass()/failcase() accounting:
|
||||
# test_rcfile_failure_aborts_piped() Req 3.1, 3.3, 3.4
|
||||
# Task 3.2 scope (implemented here), reusing the same setup_rc_home-style
|
||||
# fixture pattern/cleanup_rc_home/run_piped/run_interactive_pty helpers and
|
||||
# the same pass()/failcase() accounting:
|
||||
# test_rcfile_failure_aborts_piped() Req 3.1, 3.3, 3.4
|
||||
# test_rcfile_failure_continues_interactive() Req 3.1, 3.2, 3.4
|
||||
# and both would be added to the scenario list in main() below.
|
||||
#
|
||||
# Exit 0 == every scenario PASSed; nonzero == at least one scenario FAILed.
|
||||
|
||||
|
|
@ -38,6 +37,14 @@ XCE_TEST="${XCE_TEST_BIN:-$REPO_ROOT/src/xce.build/controller/xce_test}"
|
|||
OVERRIDE_MASTERS="rchost-a:19991,rchost-b:19992"
|
||||
NOT_SET="<not set>"
|
||||
|
||||
# A command name guaranteed absent from every xce_test command table (checked
|
||||
# against every `{ "name", cmd_fn, ... }` entry in test.c) -- used as an rc-file
|
||||
# line that deterministically fails via execute_line()'s find_command() miss
|
||||
# ("<name>: No such command for xce test." on stderr, execute_line returns -1),
|
||||
# the simplest reliable way to force a command failure (design.md Testing
|
||||
# Strategy / task 3.2).
|
||||
RCFILE_BOGUS_CMD="xce_rcfile_test_bogus_cmd_does_not_exist"
|
||||
|
||||
RUN_TIMEOUT_S="${XCE_RCFILE_TEST_TIMEOUT_S:-20}"
|
||||
|
||||
FAILURES=0
|
||||
|
|
@ -155,6 +162,26 @@ cleanup_rc_home() {
|
|||
[ -n "$dir" ] && [ -d "$dir" ] && rm -rf "$dir"
|
||||
}
|
||||
|
||||
# Creates a scratch $HOME with $HOME/config/xce_test/rc containing a
|
||||
# deliberately-failing line (RCFILE_BOGUS_CMD, an unrecognized command name)
|
||||
# FOLLOWED by an OVERRIDE_MASTERS `set masters` line. One fixture serves both
|
||||
# task 3.2 scenarios: the piped-abort scenario only needs a failing line to be
|
||||
# present (rcfile_load stops at the first nonzero runner result, so the
|
||||
# trailing `set masters` line is never reached -- design.md's Architecture
|
||||
# Pattern & Boundary Map "Stopped -- yes --> Exit" edge); the interactive
|
||||
# scenario relies on that SAME trailing line still running afterward, to
|
||||
# prove Requirement 3.2's "continue executing the remaining rc-file commands"
|
||||
# rather than merely "didn't crash". Echoes "<homedir>|<xdg_config_home>",
|
||||
# mirroring setup_rc_home().
|
||||
setup_rc_home_failing() {
|
||||
local dir
|
||||
dir="$(mktemp -d "${TMPDIR:-/tmp}/xce-rcfile-it-fail.XXXXXX")" || return 1
|
||||
mkdir -p "$dir/config/xce_test" || return 1
|
||||
printf '%s\nset masters %s\n' "$RCFILE_BOGUS_CMD" "$OVERRIDE_MASTERS" \
|
||||
>"$dir/config/xce_test/rc"
|
||||
printf '%s|%s\n' "$dir" "$dir/config"
|
||||
}
|
||||
|
||||
# Extracts the current-value column of the `masters` line from a `set`
|
||||
# command's output (cmd_set's "%-12s:%s default: %s\n" format). Robust to the
|
||||
# exact column padding and to a value containing an embedded space (the
|
||||
|
|
@ -258,6 +285,68 @@ test_norc_skips_rcfile() {
|
|||
cleanup_rc_home "$homedir"
|
||||
}
|
||||
|
||||
# ── Scenarios (task 3.2) ─────────────────────────────────────────────────────
|
||||
|
||||
# A failing rc-file command in scripted/piped mode must abort BEFORE any of
|
||||
# the piped script's own commands run, exiting nonzero (Req 3.1, 3.3, 3.4).
|
||||
# The piped script's own `echo PIPED_SCRIPT_MARKER` is the observable that
|
||||
# proves the read loop never got to read the piped script at all -- not just
|
||||
# that the run "failed" for some other reason.
|
||||
test_rcfile_failure_aborts_piped() {
|
||||
local name="rcfile_failure_aborts_piped"
|
||||
local fixture homedir xdg out rc
|
||||
fixture="$(setup_rc_home_failing)" || { failcase "$name" "setup_rc_home_failing failed"; return; }
|
||||
homedir="${fixture%%|*}"; xdg="${fixture##*|}"
|
||||
|
||||
out="$(run_piped "$homedir" "$xdg" $'echo PIPED_SCRIPT_MARKER\nquit')"
|
||||
rc=$?
|
||||
|
||||
if [ "$rc" -eq 0 ]; then
|
||||
failcase "$name" "xce_test exited 0 (expected nonzero -- a failing rc-file command should fail the session, Req 3.4); output:"$'\n'"$out"
|
||||
elif grep -qF 'PIPED_SCRIPT_MARKER' <<<"$out"; then
|
||||
failcase "$name" "piped script's own PIPED_SCRIPT_MARKER output was present -- rc-file abort did not happen before the read loop consumed the piped script (Req 3.3); output:"$'\n'"$out"
|
||||
elif ! grep -qF "$RCFILE_BOGUS_CMD" <<<"$out"; then
|
||||
failcase "$name" "rc-file command failure was not reported (expected '$RCFILE_BOGUS_CMD: No such command...', Req 3.1); output:"$'\n'"$out"
|
||||
else
|
||||
pass "$name"
|
||||
fi
|
||||
cleanup_rc_home "$homedir"
|
||||
}
|
||||
|
||||
# The same failing rc-file command in an interactive (TTY-simulated) session
|
||||
# must NOT abort: the rc file's remaining lines still run (proving "continue",
|
||||
# not just "didn't crash" -- Req 3.2) and the session still reaches the normal
|
||||
# interactive prompt afterward. Per Req 3.4 the same session-verdict/exit-code
|
||||
# accounting still applies as for any other failing command, so -- exactly as
|
||||
# for a failing command typed directly at the prompt -- the process's own
|
||||
# final exit code stays nonzero even though the session itself continued
|
||||
# normally through to `quit`; a manual mutation check (rc file with no failing
|
||||
# line) confirms this flips to exit 0, so this is asserting real behavior, not
|
||||
# vacuously true.
|
||||
test_rcfile_failure_continues_interactive() {
|
||||
local name="rcfile_failure_continues_interactive"
|
||||
local fixture homedir xdg out rc mval
|
||||
fixture="$(setup_rc_home_failing)" || { failcase "$name" "setup_rc_home_failing failed"; return; }
|
||||
homedir="${fixture%%|*}"; xdg="${fixture##*|}"
|
||||
|
||||
out="$(run_interactive_pty "$homedir" "$xdg" $'set\nquit')"
|
||||
rc=$?
|
||||
mval="$(masters_value_in_output "$out")"
|
||||
|
||||
if [ "$rc" -eq 0 ]; then
|
||||
failcase "$name" "xce_test exited 0 (expected nonzero -- a failing rc-file command should still fail the session's verdict, Req 3.4); transcript:"$'\n'"$out"
|
||||
elif ! grep -qF "$RCFILE_BOGUS_CMD" <<<"$out"; then
|
||||
failcase "$name" "rc-file command failure was not reported (expected '$RCFILE_BOGUS_CMD: No such command...', Req 3.1); transcript:"$'\n'"$out"
|
||||
elif [ "$mval" != "$OVERRIDE_MASTERS" ]; then
|
||||
failcase "$name" "expected masters=='$OVERRIDE_MASTERS' -- the rc-file line AFTER the failing one should still have run (Req 3.2), got '$mval'; transcript:"$'\n'"$out"
|
||||
elif ! grep -qF 'xce>' <<<"$out"; then
|
||||
failcase "$name" "no 'xce>' interactive prompt seen after the rc-file failure -- session did not reach the normal prompt (Req 3.2); transcript:"$'\n'"$out"
|
||||
else
|
||||
pass "$name"
|
||||
fi
|
||||
cleanup_rc_home "$homedir"
|
||||
}
|
||||
|
||||
# ── Main ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
main() {
|
||||
|
|
@ -267,6 +356,8 @@ main() {
|
|||
test_rcfile_takes_effect_piped
|
||||
test_rcfile_takes_effect_interactive
|
||||
test_norc_skips_rcfile
|
||||
test_rcfile_failure_aborts_piped
|
||||
test_rcfile_failure_continues_interactive
|
||||
|
||||
log "---- summary ----"
|
||||
local r
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue