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

muxers: Add test harness for StreamMuxer implementations #2952

Merged
merged 17 commits into from Oct 17, 2022

Conversation

thomaseizinger
Copy link
Contributor

@thomaseizinger thomaseizinger commented Sep 29, 2022

Description

This adds a basic test harness for stream muxers. It covers everything that was covered by the old mplex tests but additionally runs them also for yamux.

yamux doesn't pass one of them. I don't understand yet whether it is a harness bug or an actual bug in yamux. In any case, this is a strict improvement over what we currently have so I would like to not block this PR on that. The harness will be used to make progress on the WebRTC implementation. See melekes#9 (comment).

As part of writing this harness, I realised that StreamMuxerExt::next_{inbound,outbound} were a bad idea because they don't uphold the StreamMuxer contract of calling StreamMuxer::poll so I went ahead and deprecated them.

cc @melekes

Links to any relevant issues

Open Questions

Open tasks

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • A changelog entry has been made in the appropriate crates

Copy link
Contributor

@melekes melekes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very much in favor of this change. Thanks @thomaseizinger for the excellent design.

muxers/test-harness/src/lib.rs Outdated Show resolved Hide resolved
Comment on lines +82 to +105
/// Verifies that the dialer of a substream can receive a message.
pub async fn dialer_can_receive<A, B, S, E>(alice: A, bob: B)
where
A: StreamMuxer<Substream = S, Error = E> + Unpin,
B: StreamMuxer<Substream = S, Error = E> + Unpin,
S: AsyncRead + AsyncWrite + Send + Unpin + 'static,
E: fmt::Debug,
{
run_commutative(
alice,
bob,
|mut stream| async move {
let mut buf = Vec::new();
stream.read_to_end(&mut buf).await.unwrap();

assert_eq!(buf, b"PING");
},
|mut stream| async move {
stream.write_all(b"PING").await.unwrap();
stream.close().await.unwrap();
},
)
.await;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the official winner in the competition of most-concise-test-case within the rust-libp2p repository!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it comes to tests, every character of noise counts. You don't want to read details that are not important :)

I'd like to get rid of the trait bounds put I don't think it is possible.

muxers/yamux/tests/compliance.rs Show resolved Hide resolved
}

#[async_std::test]
#[ignore] // Hangs forever, is this a harness bug? It passes if we try to write to the stream.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May it be the case that the Rust yamux implementation only announces the stream to the remote once it writes the first byte onto it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be yeah.

Because of multistream-select, we will always write something but it is still a bit odd.

core/src/muxing.rs Outdated Show resolved Hide resolved
@thomaseizinger
Copy link
Contributor Author

I managed to adapt the mplex implementation so I got the reset test case to pass.

Going to work on yamux next.

@thomaseizinger
Copy link
Contributor Author

thomaseizinger commented Oct 8, 2022

I managed to adapt the mplex implementation so I got the reset test case to pass.

We should probably extract that into a separate PR. It might break something and that will make bisecting easier.

@thomaseizinger
Copy link
Contributor Author

Given that both our muxers, mplex and yamux need work to actually conform to the "send reset on drop" test, I suggest we merge this without all of that and just the first couple of tests. That is already an improvement.

We can then fix the muxer implementations in a separate PR!

@thomaseizinger
Copy link
Contributor Author

Removed the mplex changes as per comment above and chat with @mxinden out-of-band. This is ready for another review :)

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, wonderful work! Thanks Thomas!

@thomaseizinger
Copy link
Contributor Author

Merging because semver checks are a false-positive error.

@thomaseizinger thomaseizinger merged commit 4d4833f into master Oct 17, 2022
@thomaseizinger thomaseizinger deleted the 508-muxer-tests branch October 17, 2022 00:23
thomaseizinger added a commit to kpp/rust-libp2p that referenced this pull request Oct 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a crate that provides a test suit for an implementation of StreamMuxer
3 participants