1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Shared test helpers for the AI features.
//!
//! `ask`, `exam`, and `trace` all drive Claude through [`crate::ask::run`] and
//! fake it with a tiny on-disk `claude` script. This centralises the helpers
//! they used to copy-paste, and bakes in the two things that have bitten us:
//! every reply CLI drains stdin (or `ask::run`'s prompt write races the child
//! into a broken pipe under load), and the exec lock is poison-tolerant (a
//! panicking test must not cascade `PoisonError`s into the others).
use ;
use crateAskConfig;
/// Serializes tests that write + exec a fake CLI: a concurrent fork would
/// inherit the briefly write-open script fd and fail `exec` with `ETXTBSY`.
static EXEC_LOCK: = new;
/// Acquires [`EXEC_LOCK`], tolerating poison. A test that panics while holding
/// the guard would otherwise poison the mutex and cascade into spurious
/// `PoisonError`s in every other test that shares it.
pub
/// Writes an executable fake `claude` at `<dir>/fake-claude` running the shell
/// `body`, and returns its path. The body **must consume stdin** — `ask::run`
/// feeds the prompt through stdin, and a body that exits without reading races
/// the write into a broken pipe. For the common "reply with fixed text" case,
/// use [`fake_reply`], which drains stdin for you.
pub
/// A fake CLI that drains stdin, then prints `reply` verbatim. The reply is
/// `cat`-ed from a file so it needs no shell escaping (handy for JSON), and
/// draining first makes it immune to the broken-pipe race regardless of timing.
pub
/// A fake CLI for **arg-delivery** backends (Codex `exec`): it prints `reply`
/// verbatim and needs no stdin, because the prompt arrives as a command-line
/// argument, not on stdin. `ask::run` closes stdin immediately for arg
/// delivery, so unlike [`fake_reply`] this script deliberately does *not* drain
/// it. The reply is `cat`-ed from a file so it needs no shell escaping.
pub
/// An [`AskConfig`] pointing at `command`, with a short test timeout.
pub