-
-
Notifications
You must be signed in to change notification settings - Fork 99
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
Add support for combined test output #1088
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1088 +/- ##
==========================================
- Coverage 78.21% 78.13% -0.09%
==========================================
Files 69 72 +3
Lines 17432 17971 +539
==========================================
+ Hits 13635 14042 +407
- Misses 3797 3929 +132 ☔ View full report in Codecov by Sentry. |
Oh, looks like my assumption that MacOS would work since FIONREAD does work correctly on FreeBSD was...incorrect. Will fix tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I sound rude, but I am honestly shocked to see unsafe and raw platform-dependent syscalls used instead of tokio to achieve async read.
Thanks for the PR! I haven't looked at it yet but I have to ask again (#1086 (comment)): For stdout/stderr, can we just do something like:
|
We could, I'm just not sure why? The split output can be extremely confusing when looking at a failed test because the relationship between the streams is completely broken. |
Hmm, so I guess the same argument would apply to nextest's own output as well. Why should we not provide combined output across stdout and stderr? (Maybe we should!) |
I mean, this PR enables either of those styles of output since it records which stream the output came from so that the libtest output can be combined and the rest of the code still functions as it does on main, so it wouldn't be a stretch to either convert it all or allow users to decide. The code is quite trivial. |
Trying out this PR (very excited to see this getting done!!) and I am a big fan of the separation of stdout and stderr - so just wanted to be sure that output would be the raw I am working now to get a workflow that would enable a terminal (local or CI logs) to print out all details and also capturing JSON for further processing AFAIK. As the PR here works now, I am able to use the command One request: each item in the report is valid json, but the overall set of these events flushed to stdout IMHO should be a proper json array, so in my case I would not need to post process into a valid json file by wrapping these into an array. 🙏 That seem reasonable? As it is now you get: {"type":"suite",...}
{"type":"test",...}
... But I would want: [
{"type":"suite",...},
{"type":"test",...},
...
] |
That's not how libtest works, I think if you want an improved JSON/etc output you should comment on #20 about what format would suit you, #1086 set it up so that adding new machine readable formats should be easy. |
(I think newline-delimited JSON is correct and other future formats should also use it.) |
1ba42b3
to
9784359
Compare
I've marked this as ready for review as I think this is good enough to bring in, especially considering that the libtest-json is marked as experimental. The test output is now always combined, and for non-json test output still preserves the current behavior of emitting stdout and stderr parts separately, passing all tests, however the combined output is now used as the The TestOutput additionally has a lines iterator that can help in future formats that may want to emit the output itself in a structured way, with eg. timing data, stdout vs stderr, etc. |
Thanks. This makes sense. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of comments and then this is good to go. Thanks!
FYI still working on this, while adding some tests I noticed that my naive assumption that combining 2 different streams would mostly be correct in most situations was completely wrong on both linux and windows (and most likely mac/bsd/etc) so I've fixed that for unix and am working on the Windows implementation now, just converted to draft to be more clear of the state. |
Oh, that was easier than I thought it would be. Basically, we now have 3 separate
This is using methods that were only just added in 1.74.0 which is why all of the 1.70.0 checks are failing. If moving to that MSRV isn't acceptable then I can remove the combined output capture, it would just need to be noted on the libtest output that the interleaved output in the Note I also replaced |
8051ab8
to
afb1937
Compare
Could you elaborate on what made this completely wrong? At a high level it seems like it would be fine, given that Also re Rust 1.74, stderr and stdout are just file descriptors (HANDLEs on Windows) so we should be able to convert them into Replacing windows with windows-sys is fine and was something I'd been wanting to do at some point, so thanks for doing that! |
Given something like this: #[test]
fn ordering_is_hard() {
eprintln!("first stderr");
println!("this is stdout");
eprintln!("second stderr");
panic!("oh no");
} Running this test with output capturing would basically give something like
Oh yes, that will probably work, I went for the "match std exactly" option initially just to prove out the solution without needing to worry about "minor" divergences making it not work for non-obvious reasons. I'll do that after break.
Excellent. |
Maybe you can just set stdout and stderr to point to the same pipe? That should make things a lot easier, isn't it? |
That's what this change does. |
Checkpointing so I can check Windows impl on an actual windows machine
Adds basic tests for TestOutput, particularly the line iterator
While adding tests for the libtestjson output, I noticed that my assumption that stdout/stderr ordering would be _mostly_ correct except in "extreme" scenarios was...completely wrong. With even the most simple mixed stdout/stderr output (no multithreading, no unbuffered output, no huge single writes) that the ordering of the output was wrong on my machine more often than not. After playing around with the idea of using a pseudo terminal, similar to how alacritty or other terminal emulators work, I checked the even easier case of...just passing the same file descriptor for both stdout and stderr...which works. Committing this in a separate branch so that I can push and add the Windows implementation before merging this back to the combined output branch.
f894179
to
7c1b44c
Compare
Done. |
I made some changes to prep this to land, but I wasn't able to push to this PR. So I created a new PR #1212 for this. Thanks for all the work! |
I'm planning to release a version of nextest containing support for this within the next 1-2 days. |
All right, this is part of cargo-nextest 0.9.67 which will be out within 20 minutes. |
This PR is branched off of #1086, but can be split out to its own PR separately, just wanted to show that this is working with all of the current tests, as well as allowing improved capabilities for better emulating
libtest
style output.Basically, instead of capturing stdout and stderr into their own separate buffers, test output (other process capturing like test listing is not touched in this PR) is captured into a single interleaved buffer, where each chunk of data is recorded with a timestamp when it was received, its byte range in the interleaved buffer, and which stream it came from. With this information it's possible to satisfy all of the existing code and tests by reconstructing each individual stream.
The libtest format can then just used the interleaved buffer for its output, more closely matching the output of libtest.