-
-
Notifications
You must be signed in to change notification settings - Fork 3
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
test: Introduce crate flow-test
#114
Conversation
Pull Request Test Coverage Report for Build 7879436885Details
💛 - Coveralls |
The current design looks like: #[test]
fn simple_example() {
let mut setup = ClientSetup::new(ClientFlowOptions::default());
let greeting = setup.server_sends_greeting(b"* OK ...\n");
setup.client_receives_greeting(greeting);
let noop = setup.client_sends_command(b"A1 NOOP\n");
setup.server_receives_command(noop);
} All actions (send and receive) are sequential and there is no visible async/await in the test. This is very convenient, but it has a caveat: We assume that there is enough TCP buffer between server and client to buffer the message. If we send a very large message, it will fail: #[test]
fn very_large_greeting() {
let mut setup = ClientSetup::new(ClientFlowOptions::default());
let mut gibberish = vec![b'x' as u8; 9999999];
gibberish.push(b'\n');
setup.server_sends_gibberish(&gibberish); // <- Timeout because send buffer is full
setup.client_receives_error(); // <- This line is never executed
} On my machine it's possible to send messages with up to ~200KB. What should we do? I think there are 3 options:
What do you think? |
I tried out finding a better design and came up with this: #[test]
fn simple_example() {
let (rt, mut server, mut client) = TestSetup::default().test_client();
let greeting = b"* OK ...\r\n";
rt.run2(server.send(greeting), client.receive_greeting(greeting));
let noop = b"A1 NOOP\r\n";
rt.run2(client.send_command(noop), server.receive(noop));
let status = b"A1 OK ...\r\n";
rt.run2(server.send(status), client.receive_status(status));
} I really like the new design!
|
test-setup
flow-test
ada2252
to
4e84aca
Compare
I think the current state is a good proof-of-concept that can be merged and it's ready to be reviewed. |
272bc6b
to
ea3fcd3
Compare
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.
Looks simple! I like it, too. I made a few improvements (that you can take, drop, or question) and have a design question:
Design:
- Using strings (instead of objects) makes the tests easier to read.
- Do we expect to use way more complicated messages? They can be created from
message.dump()
so should still be fine.
- Do we expect to use way more complicated messages? They can be created from
- We use a canonical representation for IMAP messages (which technically does not exist.) The types in imap-types are somehow the "canonical" representation, though. So, there is a chance we may get failing test because someone in imap-codec decided to use another "default" representation :-) This is mostly casing but there are a few instances of
(item)
(with parenthesis) v.s.item
(w/o parenthesis). imap-codec (always?) opts for the shortest option. But it could happen that we need to change it due to a broken server or so. Anyway, I generally think it's fine.
Yes, we'll use more complicated messages. Also I want to generate random messages via
The mock is allowed to send non-canonical messages. And that's good because we might want to test that we can parse them (in this case the mock would represent a server/client which is not implemented via
I think that's okay because it will happen rarely. |
18c6cc2
to
8f0130f
Compare
First attempt to introduce a test setup that allows to write tests conveniently.
My design constraints:
ClientFlow
andServerFlow
are tested separatelycargo test