-
Notifications
You must be signed in to change notification settings - Fork 21
Feature Request: wait
and/or then
methods after writing to stdin
#106
Comments
So the crux of the issue is this:
So is If we move forward with this, it seems the most ideal would be a ( |
I believe so. According to the documentation for the
The current implementation for my application is to exit on stdin EOF. Maybe I am missing something in my implementations to avoid this problem?
You are correct. The CUT implements a RPC server over stdio and/or TCP depending on configuration, and it continuously reads from stdin and writes to stdout from two separate threads to mimic the independent, bi-directional communication of a TCP socket. I implemented RPC communication over stdio for embedding but also specifically for testing the application. If I use the TCP server, then I would potentially need hundreds, or possibly even thousands, of simultaneous TCP connections, or I would have to run the tests in serial as opposed to parallel (increasing test time). Using stdio communication, I can avoid running out of TCP connections for testing and still run in parallel. I know there are other ways to test RPCs without having to "spin up" a server for each one, but there are times when I want to test the whole process and have confidence the framing, (de)serialization, routing, etc. all work as expected.
Yes, after writing the above discussion and thinking about it some more, I agree that this is probably an edge case. I don't know if enough developers have encountered, or will encounter, this quirk when working with stdio and the So, I understand leaving out a #[test]
fn chaining_stdin_messages() {
Assert::command(&["some_cmd"])
// `then` would be a wrapper around `and_then` but, selfishly, the
// `and_then` method would provide a mechanism to implement a delay for
// my tests.
.stdin("message1").then("message2").then("message3").and_then(|stdin| stdin.write_all("message4"))
.succeeds()
.and()
.stdout().contains("expected message after delay")
.unwrap();
} An |
To be clear, I'm not outright saying no, just wanting to better understand. Additionally, I'm grateful we at least have the issue so even if we close it, others might find it in the future.
That chaining is just combining predicates, its not doing much else. If there is a use case for chaining but right now, I'm not seeing it beyond your case. btw would something like rexpect be useful? See https://crates.io/crates/rexpect Something else to note, #98 is us experimenting with making the API more of a toolbox so you can create your own solutions with it. |
I will take a look at rexpect, thanks for the recommendation. In the mean time, I was experimenting the other day and came up with a change that keeps the public API usage unchanged, but allows "optional" access to the |
Okay, this issue/feature request and related PR (#107) can be closed. I have a solution for my use case using the assert_cmd crate that does not need any changes to this crate. Instead, I used The assert_cmd crate made it really easy to create a custom test fixture. I believe this is the intention of the crate. Thank you for the all of the work and information. I have created a gist of my implementation for reference and in case anyone else is interested. I am open to comments on it. |
Glad the new |
I came across this crate recently, but I cannot remember where...maybe from the CLI-WG? Anyways, it provides a lot of the functionality I wrote in the past for testing some internal projects, so I am excited to start using it in the future, and add tests for some of my Rust CLI applications. Great Work!
I am currently working on a project where I am writing messages into stdin and reading from stdout. I have some tests that deliberately result in relatively long execution times (on the order of 10's of seconds). The general test follows: (1) write message to stdin, (2) wait some amount of time depending on expected processing time, (3) read stdout and check for correctness. For these tests, where a long execution time occurs, I have not found a way to use this crate. I believe the problem is that the stdin handle from the internal
Command
is being dropped after writing to stdin but before the command has had time to write to stdout, which leaves the contents of stdout from thewait_with_output
method empty. Any correctness assertions on the output then fail.Instead of using this crate, here is a non-working example of the test I implemented:
I would like to see a
wait
,hold
, ordelay
method added to theAssert
struct as I believe theAssert
struct is essentially doing the same time as my non-working example test, but does not have thethread::sleep
line. If such a method existed, the above test could be rewritten more succinctly using this crate as follows:I believe this is cleaner and easier to read, but I understand
wait
might be confusing since there is thewait
andwait_with_output
methods for theCommand
struct instd::process
. So, maybehold
ordelay
would be better, with a slight personal preference at the moment towards "hold"?However, this got me thinking that maybe a
wait/hold/delay
method is too restrictive? There might be other tests in the future that need to do more than just wait for some time after writing to stdin. So, maybe athen
method with a predicate would be better? The above example with thewait/hold/delay
method could be re-implemented as follows:Of course, both a
wait/hold/delay
andthen
methods could be added because thethen
implementation of wait/hold/delay is a little more verbose/noisy. I am open to alternatives for thethen
method name as well.Any thoughts or comments about this proposed feature/enhancement would be greatly appreciated.
Thanks again for the great crate and work!
The text was updated successfully, but these errors were encountered: