From 3c4243fed056d00a452cfc9d9756223c7660bfe8 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 4 Jun 2020 12:35:46 +0200 Subject: [PATCH 1/2] Add a test for lots of nodes connecting at the same time --- client/network/src/service/tests.rs | 69 +++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 8eaa98449213c..8a46ce634977f 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -272,3 +272,72 @@ fn notifications_state_consistent() { } }); } + +#[test] +fn lots_of_incoming_peers_works() { + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + + let (main_node, _) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![listen_addr.clone()], + in_peers: u32::max_value(), + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + let main_node_peer_id = main_node.local_peer_id().clone(); + + // We spawn background tasks and push them in this `Vec`. They will all be waited upon before + // this test ends. + let mut background_tasks_to_wait = Vec::new(); + + for _ in 0..256 { + let main_node_peer_id = main_node_peer_id.clone(); + + let (_dialing_node, mut event_stream) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![], + reserved_nodes: vec![config::MultiaddrWithPeerId { + multiaddr: listen_addr.clone(), + peer_id: main_node_peer_id.clone(), + }], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + background_tasks_to_wait.push(async_std::task::spawn(async move { + // Create a dummy timer that will "never" fire, and that will be overwritten when we + // actually need the timer. Using an Option would be technically cleaner, but it would + // make the code below way more complicated. + let mut timer = futures_timer::Delay::new(Duration::from_secs(3600 * 24 * 7)).fuse(); + + loop { + futures::select! { + _ = timer => { + // Test succeeds when timer fires. + return; + } + ev = event_stream.next().fuse() => { + match ev.unwrap() { + Event::NotificationStreamOpened { remote, .. } => { + assert_eq!(remote, main_node_peer_id); + // Test succeeds after 5 seconds. This timer is here in order to + // detect a potential problem after opening. + timer = futures_timer::Delay::new(Duration::from_secs(5)).fuse(); + } + Event::NotificationStreamClosed { .. } => { + // Test failed. + panic!(); + } + _ => {} + } + } + } + } + })); + } + + futures::executor::block_on(async move { + future::join_all(background_tasks_to_wait).await + }); +} From c40852882e9886156677775ea89cf498e9f69a36 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 4 Jun 2020 15:47:36 +0200 Subject: [PATCH 2/2] Do small change --- client/network/src/service/tests.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 8a46ce634977f..8e79ae0e172f4 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -294,7 +294,7 @@ fn lots_of_incoming_peers_works() { for _ in 0..256 { let main_node_peer_id = main_node_peer_id.clone(); - let (_dialing_node, mut event_stream) = build_test_full_node(config::NetworkConfiguration { + let (_dialing_node, event_stream) = build_test_full_node(config::NetworkConfiguration { notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], listen_addresses: vec![], reserved_nodes: vec![config::MultiaddrWithPeerId { @@ -311,13 +311,14 @@ fn lots_of_incoming_peers_works() { // make the code below way more complicated. let mut timer = futures_timer::Delay::new(Duration::from_secs(3600 * 24 * 7)).fuse(); + let mut event_stream = event_stream.fuse(); loop { futures::select! { _ = timer => { // Test succeeds when timer fires. return; } - ev = event_stream.next().fuse() => { + ev = event_stream.next() => { match ev.unwrap() { Event::NotificationStreamOpened { remote, .. } => { assert_eq!(remote, main_node_peer_id);