Skip to content

Commit fa4adc8

Browse files
refactor(identify): bring tests up to workspace standard
This patch refactors the identify tests to use `libp2p-swarm-test`. This allows us to delete quite a bit of code and makes several dev-dependencies obsolete. The `correct_transfer` test is made obsolete by more precise assertions in the `periodic_identify` test. This allows us to remove the dependency on the `upgrade::{apply_inbound,apply_outbound}` functions. Finally, we also fix a bug where the reported listen addresses to the other node could contain duplicates. Related: #3748. Pull-Request: #3851.
1 parent 1493804 commit fa4adc8

File tree

8 files changed

+204
-444
lines changed

8 files changed

+204
-444
lines changed

Cargo.lock

Lines changed: 1 addition & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

protocols/identify/Cargo.toml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,8 @@ either = "1.8.0"
2929
[dev-dependencies]
3030
async-std = { version = "1.6.2", features = ["attributes"] }
3131
env_logger = "0.10"
32-
libp2p-mplex = { workspace = true }
33-
libp2p-yamux = { workspace = true }
34-
libp2p-noise = { workspace = true }
35-
libp2p-swarm = { workspace = true, features = ["async-std"] }
36-
libp2p-tcp = { workspace = true, features = ["async-io"] }
32+
libp2p-swarm-test = { path = "../../swarm-test" }
33+
libp2p-swarm = { workspace = true, features = ["macros"] }
3734

3835
# Passing arguments to the docsrs builder in order to properly document cfg's.
3936
# More information: https://docs.rs/about/builds#cross-compiling

protocols/identify/src/behaviour.rs

Lines changed: 0 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -561,279 +561,6 @@ impl PeerCache {
561561
#[cfg(test)]
562562
mod tests {
563563
use super::*;
564-
use futures::pin_mut;
565-
use futures::prelude::*;
566-
use libp2p_core::{muxing::StreamMuxerBox, transport, upgrade, Transport};
567-
use libp2p_identity as identity;
568-
use libp2p_identity::PeerId;
569-
use libp2p_mplex::MplexConfig;
570-
use libp2p_noise as noise;
571-
use libp2p_swarm::{Swarm, SwarmBuilder, SwarmEvent};
572-
use libp2p_tcp as tcp;
573-
use std::time::Duration;
574-
575-
fn transport() -> (PublicKey, transport::Boxed<(PeerId, StreamMuxerBox)>) {
576-
let id_keys = identity::Keypair::generate_ed25519();
577-
let pubkey = id_keys.public();
578-
let transport = tcp::async_io::Transport::new(tcp::Config::default().nodelay(true))
579-
.upgrade(upgrade::Version::V1)
580-
.authenticate(noise::Config::new(&id_keys).unwrap())
581-
.multiplex(MplexConfig::new())
582-
.boxed();
583-
(pubkey, transport)
584-
}
585-
586-
#[test]
587-
fn periodic_identify() {
588-
let (mut swarm1, pubkey1) = {
589-
let (pubkey, transport) = transport();
590-
let protocol = Behaviour::new(
591-
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
592-
);
593-
let swarm =
594-
SwarmBuilder::with_async_std_executor(transport, protocol, pubkey.to_peer_id())
595-
.build();
596-
(swarm, pubkey)
597-
};
598-
599-
let (mut swarm2, pubkey2) = {
600-
let (pubkey, transport) = transport();
601-
let protocol = Behaviour::new(
602-
Config::new("c".to_string(), pubkey.clone()).with_agent_version("d".to_string()),
603-
);
604-
let swarm =
605-
SwarmBuilder::with_async_std_executor(transport, protocol, pubkey.to_peer_id())
606-
.build();
607-
(swarm, pubkey)
608-
};
609-
610-
swarm1
611-
.listen_on("/ip4/127.0.0.1/tcp/0".parse().unwrap())
612-
.unwrap();
613-
614-
let listen_addr = async_std::task::block_on(async {
615-
loop {
616-
let swarm1_fut = swarm1.select_next_some();
617-
pin_mut!(swarm1_fut);
618-
if let SwarmEvent::NewListenAddr { address, .. } = swarm1_fut.await {
619-
return address;
620-
}
621-
}
622-
});
623-
swarm2.dial(listen_addr).unwrap();
624-
625-
// nb. Either swarm may receive the `Identified` event first, upon which
626-
// it will permit the connection to be closed, as defined by
627-
// `Handler::connection_keep_alive`. Hence the test succeeds if
628-
// either `Identified` event arrives correctly.
629-
async_std::task::block_on(async move {
630-
loop {
631-
let swarm1_fut = swarm1.select_next_some();
632-
pin_mut!(swarm1_fut);
633-
let swarm2_fut = swarm2.select_next_some();
634-
pin_mut!(swarm2_fut);
635-
636-
match future::select(swarm1_fut, swarm2_fut)
637-
.await
638-
.factor_second()
639-
.0
640-
{
641-
future::Either::Left(SwarmEvent::Behaviour(Event::Received {
642-
info, ..
643-
})) => {
644-
assert_eq!(info.public_key, pubkey2);
645-
assert_eq!(info.protocol_version, "c");
646-
assert_eq!(info.agent_version, "d");
647-
assert!(!info.protocols.is_empty());
648-
assert!(info.listen_addrs.is_empty());
649-
return;
650-
}
651-
future::Either::Right(SwarmEvent::Behaviour(Event::Received {
652-
info, ..
653-
})) => {
654-
assert_eq!(info.public_key, pubkey1);
655-
assert_eq!(info.protocol_version, "a");
656-
assert_eq!(info.agent_version, "b");
657-
assert!(!info.protocols.is_empty());
658-
assert_eq!(info.listen_addrs.len(), 1);
659-
return;
660-
}
661-
_ => {}
662-
}
663-
}
664-
})
665-
}
666-
667-
#[test]
668-
fn identify_push() {
669-
let _ = env_logger::try_init();
670-
671-
let (mut swarm1, pubkey1) = {
672-
let (pubkey, transport) = transport();
673-
let protocol = Behaviour::new(Config::new("a".to_string(), pubkey.clone()));
674-
let swarm =
675-
SwarmBuilder::with_async_std_executor(transport, protocol, pubkey.to_peer_id())
676-
.build();
677-
(swarm, pubkey)
678-
};
679-
680-
let (mut swarm2, pubkey2) = {
681-
let (pubkey, transport) = transport();
682-
let protocol = Behaviour::new(
683-
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
684-
);
685-
let swarm =
686-
SwarmBuilder::with_async_std_executor(transport, protocol, pubkey.to_peer_id())
687-
.build();
688-
(swarm, pubkey)
689-
};
690-
691-
Swarm::listen_on(&mut swarm1, "/ip4/127.0.0.1/tcp/0".parse().unwrap()).unwrap();
692-
693-
let listen_addr = async_std::task::block_on(async {
694-
loop {
695-
let swarm1_fut = swarm1.select_next_some();
696-
pin_mut!(swarm1_fut);
697-
if let SwarmEvent::NewListenAddr { address, .. } = swarm1_fut.await {
698-
return address;
699-
}
700-
}
701-
});
702-
703-
swarm2.dial(listen_addr).unwrap();
704-
705-
async_std::task::block_on(async move {
706-
loop {
707-
let swarm1_fut = swarm1.select_next_some();
708-
let swarm2_fut = swarm2.select_next_some();
709-
710-
{
711-
pin_mut!(swarm1_fut);
712-
pin_mut!(swarm2_fut);
713-
match future::select(swarm1_fut, swarm2_fut)
714-
.await
715-
.factor_second()
716-
.0
717-
{
718-
future::Either::Left(SwarmEvent::Behaviour(Event::Received {
719-
info,
720-
..
721-
})) => {
722-
assert_eq!(info.public_key, pubkey2);
723-
assert_eq!(info.protocol_version, "a");
724-
assert_eq!(info.agent_version, "b");
725-
assert!(!info.protocols.is_empty());
726-
assert!(info.listen_addrs.is_empty());
727-
return;
728-
}
729-
future::Either::Right(SwarmEvent::ConnectionEstablished { .. }) => {
730-
// Once a connection is established, we can initiate an
731-
// active push below.
732-
}
733-
_ => continue,
734-
}
735-
}
736-
737-
swarm2
738-
.behaviour_mut()
739-
.push(std::iter::once(pubkey1.to_peer_id()));
740-
}
741-
})
742-
}
743-
744-
#[test]
745-
fn discover_peer_after_disconnect() {
746-
let _ = env_logger::try_init();
747-
748-
let mut swarm1 = {
749-
let (pubkey, transport) = transport();
750-
#[allow(deprecated)]
751-
let protocol = Behaviour::new(
752-
Config::new("a".to_string(), pubkey.clone())
753-
// `swarm1` will set `KeepAlive::No` once it identified `swarm2` and thus
754-
// closes the connection. At this point in time `swarm2` might not yet have
755-
// identified `swarm1`. To give `swarm2` enough time, set an initial delay on
756-
// `swarm1`.
757-
.with_initial_delay(Duration::from_secs(10)),
758-
);
759-
760-
SwarmBuilder::with_async_std_executor(transport, protocol, pubkey.to_peer_id()).build()
761-
};
762-
763-
let mut swarm2 = {
764-
let (pubkey, transport) = transport();
765-
let protocol = Behaviour::new(
766-
Config::new("a".to_string(), pubkey.clone()).with_agent_version("b".to_string()),
767-
);
768-
769-
SwarmBuilder::with_async_std_executor(transport, protocol, pubkey.to_peer_id()).build()
770-
};
771-
772-
let swarm1_peer_id = *swarm1.local_peer_id();
773-
774-
let listener = swarm1
775-
.listen_on("/ip4/127.0.0.1/tcp/0".parse().unwrap())
776-
.unwrap();
777-
778-
let listen_addr = async_std::task::block_on(async {
779-
loop {
780-
match swarm1.select_next_some().await {
781-
SwarmEvent::NewListenAddr {
782-
address,
783-
listener_id,
784-
} if listener_id == listener => return address,
785-
_ => {}
786-
}
787-
}
788-
});
789-
790-
async_std::task::spawn(async move {
791-
loop {
792-
swarm1.next().await;
793-
}
794-
});
795-
796-
swarm2.dial(listen_addr).unwrap();
797-
798-
// Wait until we identified.
799-
async_std::task::block_on(async {
800-
loop {
801-
if let SwarmEvent::Behaviour(Event::Received { .. }) =
802-
swarm2.select_next_some().await
803-
{
804-
break;
805-
}
806-
}
807-
});
808-
809-
swarm2.disconnect_peer_id(swarm1_peer_id).unwrap();
810-
811-
// Wait for connection to close.
812-
async_std::task::block_on(async {
813-
loop {
814-
if let SwarmEvent::ConnectionClosed { peer_id, .. } =
815-
swarm2.select_next_some().await
816-
{
817-
break peer_id;
818-
}
819-
}
820-
});
821-
822-
// We should still be able to dial now!
823-
swarm2.dial(swarm1_peer_id).unwrap();
824-
825-
let connected_peer = async_std::task::block_on(async {
826-
loop {
827-
if let SwarmEvent::ConnectionEstablished { peer_id, .. } =
828-
swarm2.select_next_some().await
829-
{
830-
break peer_id;
831-
}
832-
}
833-
});
834-
835-
assert_eq!(connected_peer, swarm1_peer_id);
836-
}
837564

838565
#[test]
839566
fn check_multiaddr_matches_peer_id() {

protocols/identify/src/handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use libp2p_swarm::{
3939
};
4040
use log::warn;
4141
use smallvec::SmallVec;
42-
use std::collections::VecDeque;
42+
use std::collections::{HashSet, VecDeque};
4343
use std::{io, pin::Pin, task::Context, task::Poll, time::Duration};
4444

4545
/// Protocol handler for sending and receiving identification requests.
@@ -89,7 +89,7 @@ pub struct Handler {
8989
#[derive(Debug)]
9090
pub struct InEvent {
9191
/// The addresses that the peer is listening on.
92-
pub listen_addrs: Vec<Multiaddr>,
92+
pub listen_addrs: HashSet<Multiaddr>,
9393

9494
/// The list of protocols supported by the peer, e.g. `/ipfs/ping/1.0.0`.
9595
pub supported_protocols: Vec<StreamProtocol>,
@@ -246,7 +246,7 @@ impl ConnectionHandler for Handler {
246246
public_key: self.public_key.clone(),
247247
protocol_version: self.protocol_version.clone(),
248248
agent_version: self.agent_version.clone(),
249-
listen_addrs,
249+
listen_addrs: Vec::from_iter(listen_addrs),
250250
protocols: supported_protocols,
251251
observed_addr: self.observed_addr.clone(),
252252
};

protocols/identify/src/mod.rs

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)