tokio-test: Is there a way to avoid a StreamMock from sending EOF at the end of its life? #6988
Replies: 2 comments 3 replies
-
No, we only have support for waiting. You could try to use a large duration?
Not other than copying the code and modifying your copy. |
Beta Was this translation helpful? Give feedback.
-
The problem with a long duration is that the test ends up always waiting for that duration, even if it doesn't need to (e.g. if the other half of the stream ends). For some cases, where a response might be coming but within some long timeout (say, a minute in rare cases), then 99% of the time the test is done in < 100ms, but the test ends up waiting 60 seconds for the stream to end every time. There's also an issue with it racing in CI/CD environments - it's not unusual for something that works with a delay of 1 second to fail in a CI pipeline due to... reasons... thus requiring long timeouts for developers, and slow tests. I've worked in code bases (not with this library) where we've had hundreds of (parameterised) tests like this, and an extra 500ms per test blows the entire test time out from minutes to hours. How conducive do you think the design is to adding something like this? I could tinker with it myself on a fork if I had some idea that it wasn't going to take me weeks or involve significant refactoring. Would a PR on this topic be considered? What up-front design work is needed, or is a PoC a good start? |
Beta Was this translation helpful? Give feedback.
-
I have a server-side
handle_connection(reader, writer)
function that has the socket split into two halves so that I can usetokio_test::stream_mock::StreamMock
(viatokio_test::io::Builder::new()
typically, although I sometimes useStreamMockBuilder::new()
instead).I've found myself having to add artificial delays to the chain to prevent the half-socket from closing prematurely and sending EOF.
For example, consider a protocol fragment where a command and response is tested:
In this test case, I would not want to incorporate EOF handling into the test, because under normal operation the connection might continue to be used for other commands. What I wish to test is that the server responds with the correct message, even if it takes a "long" time. (In this case the wait is only 0.5 seconds, but consider longer cases where it might take, say, up to 20 seconds, but with a typical response time of < 1 second. This would involve adding large delays to tests that aren't even needed most of the time).
With the code written above, after 500ms, the reader half will be closed and my code will see EOF on the reader socket. I'd prefer that it didn't as that isn't part of the protocol I'm testing (in my use case, EOF on the reader will stop the entire connection and internally cause both the reader and writer actors to shut down, which causes a race with whether "GET 1 READY" is sent on the write half, or not).
Is there something similar to this?
Then when the test function gets to the end, the assertion in the
drop()
function forreader
could just check that all data was read, as it does now, and I can avoid arbitrary delays because everything should just proceed in lockstep anyway.General question: is there a technique for extending these StreamMocks to support custom features like checkpoints and timeouts?
Beta Was this translation helpful? Give feedback.
All reactions