feat(xce-test-cli-ux): build destructive-command confirmation gate
confirm_destructive() prompts on stderr and blocking-reads a y/n answer via a single, non-looping fgets() call (not libedit) -- the mechanism that makes a real Ctrl-C during the prompt return EINTR and be treated as a decline (Requirement 9.9), same as an explicit "n" or EOF. confirm_set_skip()/confirm_is_skip_set() add a session-scoped toggle mirroring cmd_set's existing -e/+e style. Auto-skips when input is not interactive, via a new xcetest_is_interactive() accessor over the existing g_interactive global. Destructive-command enumeration and per-command wiring (Requirement 9.5) is task 3.3, not this task. Proven with a real fork+SIGINT test. 1297/1297 controller suite passing (+7). Task 2.1 of .kiro/specs/xce-test-cli-ux/tasks.md. Requirements: 9.1, 9.2, 9.3, 9.4, 9.6, 9.7, 9.8, 9.9 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019jaMf9QEwpugH2W9KAuc7f
This commit is contained in:
parent
7d0ac6f6eb
commit
a2686516f7
7 changed files with 580 additions and 2 deletions
|
|
@ -52,7 +52,7 @@
|
|||
- _Boundary: Testing Infrastructure_
|
||||
|
||||
- [ ] 2. Core: independent new capabilities and standalone fixes
|
||||
- [ ] 2.1 (P) Build the destructive-command confirmation gate and its session-scoped toggle
|
||||
- [x] 2.1 (P) Build the destructive-command confirmation gate and its session-scoped toggle
|
||||
- Implement a confirmation check that prompts the operator on stderr before proceeding, returns a distinct "not run" outcome on decline, and treats an interrupt during the prompt the same as a decline
|
||||
- Add a bypass flag usable per invocation and a session-scoped toggle (mirroring the existing continue-on-error toggle's style) that both default to requiring confirmation and both reset at process start
|
||||
- Ensure the confirmation check is skipped automatically when input is not from an interactive session
|
||||
|
|
@ -178,6 +178,7 @@
|
|||
## Implementation Notes
|
||||
- `src/tools/xce-build.sh controller asan xce.build --incremental` writes its build dir at `src/xce.build/` (relative to the script's own location), not a repo-root `xce.build/` — meson logs are at `src/xce.build/meson-logs/testlog.txt`. (task 1.1)
|
||||
- New Unity test files need two wiring points, not just meson.build's source list: also register an `extern void test_<module>(void);` + `TEST(test_<module>);` in `src/controller/testsuite/controller_test.c`, mirroring the existing `test_rcfile` registration, or the suite silently never runs. (task 1.1)
|
||||
- `confirm_destructive()`'s EINTR-as-decline (9.9) works because it's a single, non-looping `fgets()` call — a naive "robust I/O" retry-on-EINTR wrapper would silently defeat this requirement. `g_interactive` is exposed via a new `xcetest_is_interactive()` accessor (declared in `confirm.h`, mirroring `xcetest_interrupted()`'s pattern) for task 3.3 to reuse. Task 3.3 must short-circuit around `confirm_destructive()` entirely (not pass a parameter into it) when a command's own `--yes` flag was given — the function has no bypass-flag parameter by design. (task 2.1)
|
||||
- The `test_test_cli.c` black-box harness (`clitest_*` functions) is file-static and single-file by design (matching design.md's File Structure Plan and this directory's own no-split norm) — tasks 2.3, 3.5, 4.1-4.4 should add their black-box test functions directly into this same file rather than a new one. `clitest_wait_for_text()` is generic (arbitrary needle/stream) and safe to call repeatedly mid-session; `clitest_send_signal()` targets the child's real pid via `kill()`. (task 1.7)
|
||||
- `argp` has no built-in `-h` alias (its default short help flag is `-?`) — Requirement 4.1 literally names `-h`, so it needed an explicit `OPTION_HIDDEN` option added, not just verification of existing defaults. Task 1.6's new `test_xcetest_process_entry.c` already covers "`-h`/`--help`/`--version` exit without entering the REPL" end-to-end against the real binary; task 1.7's `test_test_cli.c` should either skip re-adding this exact scenario or consolidate the two rather than duplicating coverage. (task 1.6)
|
||||
- The per-connection lock is a POSIX semaphore (`sem_t`), not a `pthread_mutex_t` — a mutex was tried first but rejected on review (POSIX classifies a non-owning-thread `pthread_mutex_unlock()` as UB for every mutex type, not just error-checking ones, and this design needs the worker thread to release a lock the caller thread acquired). `sem_t` has no ownership concept and is fully POSIX-defined for this pattern. See bug-1791. (task 1.5)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue