Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capturing stdout from test code is inconsistent #12309

Open
MicahChalmer opened this Issue Feb 16, 2014 · 15 comments

Comments

Projects
None yet
@MicahChalmer
Copy link
Contributor

MicahChalmer commented Feb 16, 2014

The feature that captures "stdout" for tests doesn't capture all the ways that a test could print to stdout.

#[test]
fn output_capture_tests() {
    println!("This gets captured...");
    let _ = std::io::stdout().write_line("but this does not...");
    let _ = std::task::try(proc() { println!("..and neither does this...") });
    let _ = std::run::process_status("/bin/echo", [~"...nor this..."]);
    fail!();
}

Only the first println! call gets captured--the rest appear intermingled with the test output:

running 1 test
but this does not...
..and neither does this...
...nor this...
test output_capture_tests ... FAILED

failures:

---- output_capture_tests stdout ----
    This gets captured...
    task 'output_capture_tests' failed at 'explicit failure', subproc-test-stdout.rs:7


failures:
    output_capture_tests

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

It would be nice if all of these got captured.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 16, 2014

In my opinion, the only real bug here is that the child task's println isn't captured. Capturing stdout/stderr is not supposed to be comprehensive, it's supposed to clean up the output.

You'll almost always be able to subvert whatever capturing is going on, it's not supposed to be exhaustive.

@MicahChalmer

This comment has been minimized.

Copy link
Contributor Author

MicahChalmer commented Feb 16, 2014

Ok, so std::io::stdout() will always hit the process-wide FD 1 (not task-local), whereas the functions in std::io::stdio will write to a task-local "stdout" which could be redirected at spawn time. Perhaps the task-local "stdout" should have a different name? Otherwise this could get rather confusing. I think people will expect the term "stdout" to always refer to the process global version. "Task default output" maybe?

If the task-local one is still going to be named "stdout", then I think the documentation will need to be updated in a lot of places to make it explicit which "stdout" is being used. For instance, the documentation of std::io::stdio::println refers to "the stdout of the current process"--but that's no longer the case, now it's "the stdout of the current task" (and probably an explanation of how that is not the same thing as the stdout of the current process.)

Once that distinction is clear, it's natural to assume that child processes will inherit the process global FD, so I see why that's not a bug. It's easy enough to capture the output and print it to the task's "stdout".

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Jan 23, 2015

This is still true today with Thread::scoped.

@steveklabnik steveklabnik added the A-libs label Jan 23, 2015

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Feb 16, 2015

Nominating for 1.0-beta P-backcompat-libs. We need to finalize our capture story.

@aturon aturon added the I-nominated label Feb 16, 2015

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Feb 19, 2015

1.0 beta, P-backcompat-libs, I-needsdecision

@pnkfelix pnkfelix added this to the 1.0 beta milestone Feb 19, 2015

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Mar 24, 2015

triage: (1.0)

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Mar 24, 2015

triage: P-high (1.0)

@rust-highfive rust-highfive modified the milestones: 1.0, 1.0 beta Mar 24, 2015

@alexcrichton alexcrichton self-assigned this Apr 2, 2015

@steveklabnik steveklabnik removed this from the 1.0 milestone May 21, 2015

@thijsc thijsc referenced this issue Jan 28, 2016

Closed

Process IO probe #14

sgrif added a commit to diesel-rs/diesel that referenced this issue Jan 31, 2016

Don't spam migration output during test runs
Rust *should* be swallowing all stdout output during test runs, but for
some reason it isn't. This appears to be due to
rust-lang/rust#12309. However, we can't have
out test suite spam to the point of unreadability until that's fixed, so
let's just not output from migrations during tests.

This was paired, so it has been committed without PR.

Fixes #156.

sgrif added a commit to diesel-rs/diesel that referenced this issue Feb 3, 2016

Don't spam migration output during test runs
Rust *should* be swallowing all stdout output during test runs, but for
some reason it isn't. This appears to be due to
rust-lang/rust#12309. However, we can't have
out test suite spam to the point of unreadability until that's fixed, so
let's just not output from migrations during tests.

This was paired, so it has been committed without PR.

Fixes #156.

sgrif added a commit to diesel-rs/diesel that referenced this issue Feb 3, 2016

Don't spam migration output during test runs
Rust *should* be swallowing all stdout output during test runs, but for
some reason it isn't. This appears to be due to
rust-lang/rust#12309. However, we can't have
out test suite spam to the point of unreadability until that's fixed, so
let's just not output from migrations during tests.

This was paired, so it has been committed without PR.

Fixes #156.
@dbrgn

This comment has been minimized.

Copy link
Contributor

dbrgn commented Mar 16, 2016

I also stumbled over this issue when starting a test server as a child process. The stdout logged by the server does not get captured.

While I could redirect the output to /dev/null, that makes it hard to debug problems. On the other hand, allowing the stdout to be printed causes pages of unnecessary output, making it hard to see the actual test results.

@brson brson added P-low T-libs and removed P-medium labels Oct 20, 2016

@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented Oct 20, 2016

@alexcrichton just an idea, but how about we use something like freopen (and dup to keep stdout around as a different fd) to replace the stdout file descriptor for the duration of the testing? It should be cheap enough to be able to do that for tests, it would also capture all sorts of outputs and would let us to avoid having that weird thread-local stdout overwrite code we have now.

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Oct 20, 2016

@nagisa Can't use freopen to deal with Rust's stdout on Windows.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Oct 20, 2016

@nagisa sounds plausible to me, I think there may also be ways to muck around with this on Windows as well. We'd likely still need to fiddle with private APIs in the standard library, however, as on Windows at least we cache the handles returned by the system so if they're reset we'd have to bust that cache.

@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented Oct 20, 2016

@retep998

This comment has been minimized.

Copy link
Member

retep998 commented Oct 20, 2016

@nagisa If Rust didn't cache the result of GetStdHandle, then yes that would work.

@sanmai-NL

This comment has been minimized.

Copy link

sanmai-NL commented Feb 17, 2018

@alexcrichton: these many reports and suggestions for improvement can be circumvented by removing the whole output capturing code and instead optionally report test outcomes as JSON messages on stdout, and assume tests themselves do not pollute stdout. Then we’d be done with these annoyances without putting in effort to unbreak output capturing. Are you open to a PR?

Also, this issue should be moved to the Cargo issue tracker.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 24, 2018

@sanmai-NL I think that such a PR would unfortunately be a breaking change and as a result needs to be considered a little more carefully (e.g. with the dev-tools team). This is still a rustc issue as-is so I don't think it should move.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.