Skip to content

Commit

Permalink
feat: make runtime features optional in swarm-test (#5551)
Browse files Browse the repository at this point in the history
## Description

<!--
Please write a summary of your changes and why you made them.
This section will appear as the commit message after merging.
Please craft it accordingly.
For a quick primer on good commit messages, check out this blog post:
https://cbea.ms/git-commit/

Please include any relevant issues in here, for example:

Related https://github.com/libp2p/rust-libp2p/issues/ABCD.
Fixes https://github.com/libp2p/rust-libp2p/issues/XYZ.
-->

Sometimes a test uses custom swarm building logic and doesn't need `fn
new_ephemeral`, and sometimes a test uses `tokio` runtime other than
`async-std`.
This PR adds the `tokio` runtime support and makes both `async-std` and
`tokio` runtimes optional behind features to make it more flexible.

## Notes & open questions

<!--
Any notes, remarks or open questions you have to make about the PR which
don't need to go into the final commit message.
-->

## Change checklist

<!-- Please add a Changelog entry in the appropriate crates and bump the
crate versions if needed. See
<https://github.com/libp2p/rust-libp2p/blob/master/docs/release.md#development-between-releases>-->

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

---------

Co-authored-by: João Oliveira <[email protected]>
  • Loading branch information
hanabi1224 and jxs authored Oct 15, 2024
1 parent d3228ad commit 812a7cd
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ libp2p-server = { version = "0.12.8", path = "misc/server" }
libp2p-stream = { version = "0.2.0-alpha", path = "protocols/stream" }
libp2p-swarm = { version = "0.45.2", path = "swarm" }
libp2p-swarm-derive = { version = "=0.35.0", path = "swarm-derive" } # `libp2p-swarm-derive` may not be compatible with different `libp2p-swarm` non-breaking releases. E.g. `libp2p-swarm` might introduce a new enum variant `FromSwarm` (which is `#[non-exhaustive]`) in a non-breaking release. Older versions of `libp2p-swarm-derive` would not forward this enum variant within the `NetworkBehaviour` hierarchy. Thus the version pinning is required.
libp2p-swarm-test = { version = "0.4.0", path = "swarm-test" }
libp2p-swarm-test = { version = "0.4.1", path = "swarm-test" }
libp2p-tcp = { version = "0.42.0", path = "transports/tcp" }
libp2p-tls = { version = "0.5.0", path = "transports/tls" }
libp2p-uds = { version = "0.41.0", path = "transports/uds" }
Expand Down
7 changes: 7 additions & 0 deletions swarm-test/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.4.1

- Add `tokio` runtime support and make `tokio` and `async-std` runtimes optional behind features.
See [PR 5551].

[PR 5551]: https://github.com/libp2p/rust-libp2p/pull/5551

## 0.4.0

<!-- Update to libp2p-swarm v0.45.0 -->
Expand Down
12 changes: 9 additions & 3 deletions swarm-test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libp2p-swarm-test"
version = "0.4.0"
version = "0.4.1"
edition = "2021"
rust-version = { workspace = true }
license = "MIT"
Expand All @@ -16,13 +16,19 @@ async-trait = "0.1.80"
libp2p-core = { workspace = true }
libp2p-identity = { workspace = true, features = ["rand"] }
libp2p-plaintext = { workspace = true }
libp2p-swarm = { workspace = true, features = ["async-std"] }
libp2p-tcp = { workspace = true, features = ["async-io"] }
libp2p-swarm = { workspace = true }
libp2p-tcp = { workspace = true }
libp2p-yamux = { workspace = true }
futures = { workspace = true }
rand = "0.8.5"
tracing = { workspace = true }
futures-timer = "3.0.3"

[features]
default = ["async-std"]

async-std = ["libp2p-swarm/async-std", "libp2p-tcp/async-io"]
tokio = ["libp2p-swarm/tokio", "libp2p-tcp/tokio"]

[lints]
workspace = true
69 changes: 54 additions & 15 deletions swarm-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,10 @@
use async_trait::async_trait;
use futures::future::{BoxFuture, Either};
use futures::{FutureExt, StreamExt};
use libp2p_core::{
multiaddr::Protocol, transport::MemoryTransport, upgrade::Version, Multiaddr, Transport,
};
use libp2p_identity::{Keypair, PeerId};
use libp2p_plaintext as plaintext;
use libp2p_core::{multiaddr::Protocol, Multiaddr};
use libp2p_identity::PeerId;
use libp2p_swarm::dial_opts::PeerCondition;
use libp2p_swarm::{self as swarm, dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmEvent};
use libp2p_yamux as yamux;
use libp2p_swarm::{dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmEvent};
use std::fmt::Debug;
use std::future::IntoFuture;
use std::time::Duration;
Expand All @@ -38,12 +34,23 @@ use std::time::Duration;
pub trait SwarmExt {
type NB: NetworkBehaviour;

/// Create a new [`Swarm`] with an ephemeral identity.
/// Create a new [`Swarm`] with an ephemeral identity and the `async-std` runtime.
///
/// The swarm will use a [`MemoryTransport`] together with a [`plaintext::Config`] authentication layer and
/// [`yamux::Config`] as the multiplexer. However, these details should not be relied upon by the test
/// The swarm will use a [`libp2p_core::transport::MemoryTransport`] together with a [`libp2p_plaintext::Config`] authentication layer and
/// [`libp2p_yamux::Config`] as the multiplexer. However, these details should not be relied upon by the test
/// and may change at any time.
fn new_ephemeral(behaviour_fn: impl FnOnce(Keypair) -> Self::NB) -> Self
#[cfg(feature = "async-std")]
fn new_ephemeral(behaviour_fn: impl FnOnce(libp2p_identity::Keypair) -> Self::NB) -> Self
where
Self: Sized;

/// Create a new [`Swarm`] with an ephemeral identity and the `tokio` runtime.
///
/// The swarm will use a [`libp2p_core::transport::MemoryTransport`] together with a [`libp2p_plaintext::Config`] authentication layer and
/// [`libp2p_yamux::Config`] as the multiplexer. However, these details should not be relied upon by the test
/// and may change at any time.
#[cfg(feature = "tokio")]
fn new_ephemeral_tokio(behaviour_fn: impl FnOnce(libp2p_identity::Keypair) -> Self::NB) -> Self
where
Self: Sized;

Expand Down Expand Up @@ -200,26 +207,58 @@ where
{
type NB = B;

fn new_ephemeral(behaviour_fn: impl FnOnce(Keypair) -> Self::NB) -> Self
#[cfg(feature = "async-std")]
fn new_ephemeral(behaviour_fn: impl FnOnce(libp2p_identity::Keypair) -> Self::NB) -> Self
where
Self: Sized,
{
use libp2p_core::{transport::MemoryTransport, upgrade::Version, Transport as _};
use libp2p_identity::Keypair;

let identity = Keypair::generate_ed25519();
let peer_id = PeerId::from(identity.public());

let transport = MemoryTransport::default()
.or_transport(libp2p_tcp::async_io::Transport::default())
.upgrade(Version::V1)
.authenticate(plaintext::Config::new(&identity))
.multiplex(yamux::Config::default())
.authenticate(libp2p_plaintext::Config::new(&identity))
.multiplex(libp2p_yamux::Config::default())
.timeout(Duration::from_secs(20))
.boxed();

Swarm::new(
transport,
behaviour_fn(identity),
peer_id,
libp2p_swarm::Config::with_async_std_executor()
.with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures.,
)
}

#[cfg(feature = "tokio")]
fn new_ephemeral_tokio(behaviour_fn: impl FnOnce(libp2p_identity::Keypair) -> Self::NB) -> Self
where
Self: Sized,
{
use libp2p_core::{transport::MemoryTransport, upgrade::Version, Transport as _};
use libp2p_identity::Keypair;

let identity = Keypair::generate_ed25519();
let peer_id = PeerId::from(identity.public());

let transport = MemoryTransport::default()
.or_transport(libp2p_tcp::tokio::Transport::default())
.upgrade(Version::V1)
.authenticate(libp2p_plaintext::Config::new(&identity))
.multiplex(libp2p_yamux::Config::default())
.timeout(Duration::from_secs(20))
.boxed();

Swarm::new(
transport,
behaviour_fn(identity),
peer_id,
swarm::Config::with_async_std_executor()
libp2p_swarm::Config::with_tokio_executor()
.with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures.,
)
}
Expand Down

0 comments on commit 812a7cd

Please sign in to comment.