I have written a CLI app that behaves differently depending on whether its stdout/stderr was a TTY. Now I want to test it. The problem is: Stdio::piped()
can't fake a TTY while Stdio::inherit()
can't capture stdout/stderr output.
I think your best bet here would be to tweak the CLI app with some "hidden"/internal setting/knob, such as a flag or an env var, that could override its tty detection.
- if you don't mind recompiling the CLI app just for this, using a compile-time flag such as a Cargo feature flag and
cfg
s, then you could even ensure that option does not exist for public releases of your app.
For third-party programs, a trick I've personally used, on UNIX systems, is to:
echo 'int isatty(int fd) { return 1; }' | cc -shared -o libfaketty.so -xc -
to generate a libfaketty.so
shared library, and then use LD_PRELOAD="$PWD"/libfaketty.so
env setting before running the process.
But since you are the one maintaining the CLI app, offering a knob directly seems best
Alternatively, you can make a pseudo-terminal to use for stdout/err, but then you’ll have to handle all of the terminal emulation yourself. (This is the mechanism that xterm
and friends use, so it should be a faithful test of the detection code as well as the altered behavior)
It seems that my binary does not respect LD_PRELOAD
. How do I make it read LD_PRELOAD
(but only in cfg(test)
context)?
Longform answer:
- create a new pseudoterminal with
libc::openpty
- install it with
libc::login_tty
inpre_exec
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.