Skip to content

Commit

Permalink
Merge pull request ProvableHQ#1708 from ljedrz/testnet3_test_tweaks
Browse files Browse the repository at this point in the history
A few test tweaks
  • Loading branch information
howardwu authored May 4, 2022
2 parents 182ad87 + 7375d88 commit 2bd4e17
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 154 deletions.
4 changes: 4 additions & 0 deletions .integration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ edition = "2021"
[features]
test = [ "anyhow", "clap", "snarkos", "peak_alloc", "snarkos-metrics", "tracing-subscriber" ]

[dev-dependencies.snarkos-integration]
path = "."
features = [ "test" ] # a workaround to use the `test` feature in tests by default

[dependencies.anyhow]
version = "1"
optional = true
Expand Down
16 changes: 13 additions & 3 deletions .integration/src/client_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

use clap::Parser;
use snarkos::Server;
use snarkos_environment::{Client, CurrentNetwork};
use snarkos_environment::{network::DisconnectReason, CurrentNetwork, TestEnvironment};

use std::{fs, net::SocketAddr};

/// A facade for a snarkOS client node.
pub struct ClientNode {
pub server: Server<CurrentNetwork, Client<CurrentNetwork>>,
pub server: Server<CurrentNetwork, TestEnvironment<CurrentNetwork>>,
}

impl ClientNode {
Expand All @@ -36,6 +36,11 @@ impl ClientNode {
self.server.peers().connected_peers().await
}

/// Returns the number of connected peers of the node.
pub async fn number_of_connected_peers(&self) -> usize {
self.server.peers().number_of_connected_peers().await
}

/// Resets the node's known peers. This is practical, as it makes the node not reconnect
/// to known peers in test cases where it's undesirable.
pub async fn reset_known_peers(&self) {
Expand All @@ -47,6 +52,11 @@ impl ClientNode {
self.server.connect_to(addr).await
}

/// Disonnects the node from the given address.
pub async fn disconnect(&self, addr: SocketAddr) {
self.server.disconnect_from(addr, DisconnectReason::NoReasonGiven).await
}

/// Starts a snarkOS node with all the default characteristics from `ClientNode::with_args`.
pub async fn default() -> Self {
ClientNode::with_args(&["--node", "127.0.0.1:0"]).await
Expand All @@ -58,7 +68,7 @@ impl ClientNode {
let permanent_args = &["snarkos", "--norpc"];
let combined_args = permanent_args.iter().chain(extra_args.iter());
let config = snarkos::Node::parse_from(combined_args);
let server = Server::<CurrentNetwork, Client<CurrentNetwork>>::initialize(&config, None, None)
let server = Server::<CurrentNetwork, TestEnvironment<CurrentNetwork>>::initialize(&config, None, None)
.await
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion .integration/src/test_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl TestNode {

let pea2pea_node = Pea2PeaNode::new(Some(config)).await.unwrap();
let client_state = Default::default();
let node = TestNode(SynthNode::new(pea2pea_node, client_state));
let node = TestNode::new(pea2pea_node, client_state);
node.enable_disconnect().await;
node.enable_handshake().await;
node.enable_reading().await;
Expand Down
29 changes: 14 additions & 15 deletions .integration/tests/network/basic_connectivity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,14 @@
// along with the snarkOS library. If not, see <https://www.gnu.org/licenses/>.

use crate::common::spawn_test_node_with_nonce;
use snarkos_integration::{wait_until, ClientNode, TestNode, MAXIMUM_NUMBER_OF_PEERS};
use snarkos_environment::{CurrentNetwork, Environment, TestEnvironment};
use snarkos_integration::{wait_until, ClientNode, TestNode};

use pea2pea::Pea2Pea;
use std::{
sync::{
atomic::{AtomicU8, Ordering::*},
Arc,
},
time::Duration,
use std::sync::{
atomic::{AtomicU8, Ordering::*},
Arc,
};
use tokio::{task, time};

#[tokio::test]
async fn client_nodes_can_connect_to_each_other() {
Expand Down Expand Up @@ -135,7 +132,7 @@ async fn concurrent_duplicate_connection_attempts_fail() {
let test_node = test_node.clone();
let error_count = error_count.clone();

task::spawn(async move {
tokio::spawn(async move {
if test_node.node().connect(client_node_addr).await.is_err() {
error_count.fetch_add(1, Relaxed);
}
Expand All @@ -152,25 +149,27 @@ async fn connection_limits_are_obeyed() {
// Start a snarkOS node.
let client_node = ClientNode::default().await;

const MAXIMUM_NUMBER_OF_PEERS: usize = TestEnvironment::<CurrentNetwork>::MAXIMUM_NUMBER_OF_PEERS as usize;

// Start the maximum number of test nodes the snarkOS node is permitted to connect to at once.
let mut test_nodes = Vec::with_capacity(MAXIMUM_NUMBER_OF_PEERS);
for _ in 0..MAXIMUM_NUMBER_OF_PEERS {
test_nodes.push(TestNode::default().await);
}

// Create one additional test node.
let extra_test_node = TestNode::default().await;
let extra_test_node_addr = extra_test_node.node().listening_addr().unwrap();

// All the test nodes should be able to connect to the snarkOS node.
for test_node in &test_nodes {
test_node.node().connect(client_node.local_addr()).await.unwrap();
}

// A short sleep to ensure all the connections are ready.
time::sleep(Duration::from_millis(10)).await;

// Create one additional test node.
let extra_test_node = TestNode::default().await;
let extra_test_node_addr = extra_test_node.node().listening_addr().unwrap();
wait_until!(1, client_node.number_of_connected_peers().await == MAXIMUM_NUMBER_OF_PEERS);

// Assert that snarkOS can't connect to it.
// Assert that snarkOS can't connect to the extra node.
assert!(client_node.connect(extra_test_node_addr).await.is_err());

// Assert that the test node can't connect to the snarkOS node either.
Expand Down
123 changes: 116 additions & 7 deletions .integration/tests/network/perf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,127 @@
// You should have received a copy of the GNU General Public License
// along with the snarkOS library. If not, see <https://www.gnu.org/licenses/>.

use snarkos_integration::ClientNode;
use pea2pea::{protocols::Writing, Pea2Pea};
use snarkos_environment::{
helpers::{NodeType, State},
network::{Data, Message},
Client,
CurrentNetwork,
Environment,
};
use snarkos_integration::{wait_until, ClientNode, TestNode};
use snarkvm::dpc::traits::network::Network;

use std::time::Instant;
use std::time::{Duration, Instant};

#[tokio::test]
#[ignore = "this test is purely informational; latest result: ~675ms"]
#[ignore = "this test is purely informational; latest result: ~540ms"]
async fn measure_node_startup() {
let now = Instant::now();
const NUM_ITERATIONS: usize = 10;
let mut avg_start_up_time = Duration::default();

// Start a snarkOS node.
let _snarkos_node = ClientNode::default().await;
for _ in 0..NUM_ITERATIONS {
let start = Instant::now();
let _snarkos_node = ClientNode::default().await;
avg_start_up_time += start.elapsed();
}
avg_start_up_time /= NUM_ITERATIONS as u32;

// Display the result.
println!("snarkOS start-up time: {}ms", now.elapsed().as_millis());
println!("snarkOS start-up time: {:?}", avg_start_up_time);
}

#[tokio::test]
#[ignore = "this test is purely informational; latest result: ~185ms"]
async fn measure_connection_time() {
const NUM_ITERATIONS: usize = 10;
let mut avg_conn_time = Duration::default();

let connector = ClientNode::default().await;
let connector_addr = connector.local_addr();
let connectee = ClientNode::default().await;
let connectee_addr = connectee.local_addr();

for _ in 0..NUM_ITERATIONS {
let start = Instant::now();
connector.connect(connectee_addr).await.unwrap();
avg_conn_time += start.elapsed();
wait_until!(1, connectee.number_of_connected_peers().await == 1);

connector.disconnect(connectee_addr).await;
connectee.disconnect(connector_addr).await;
wait_until!(1, connector.number_of_connected_peers().await == 0);
wait_until!(1, connectee.number_of_connected_peers().await == 0);
connector.reset_known_peers().await;
connectee.reset_known_peers().await;
}
avg_conn_time /= NUM_ITERATIONS as u32;

// Display the result.
println!("snarkOS connection time: {:?}", avg_conn_time);
}

#[tokio::test]
#[ignore = "this test is purely informational; latest result: ~2ms"]
async fn measure_peer_request_time() {
const NUM_ITERATIONS: usize = 10;
let mut avg_request_time = Duration::default();

let test_node = TestNode::default().await;
let client_node = ClientNode::default().await;
let client_addr = client_node.local_addr();
test_node.node().connect(client_addr).await.unwrap();
wait_until!(1, client_node.number_of_connected_peers().await == 1);
wait_until!(1, test_node.node().stats().received().0 as usize == 1);

let init_recv_count = test_node.node().stats().received().0 as usize;
for i in 0..NUM_ITERATIONS {
let start = Instant::now();
test_node
.send_direct_message(client_addr, Message::PeerRequest)
.unwrap()
.await
.unwrap();
wait_until!(1, test_node.node().stats().received().0 as usize == init_recv_count + i + 1);
avg_request_time += start.elapsed();
}
avg_request_time /= NUM_ITERATIONS as u32;

// Display the result.
println!("snarkOS peer request time: {:?}", avg_request_time);
}

#[tokio::test]
#[ignore = "this test is purely informational; latest result: ~55ms"]
async fn measure_ping_time() {
const NUM_ITERATIONS: usize = 10;
let mut avg_request_time = Duration::default();

let test_node = TestNode::default().await;
let client_node = ClientNode::default().await;
let client_addr = client_node.local_addr();
test_node.node().connect(client_addr).await.unwrap();
wait_until!(1, client_node.number_of_connected_peers().await == 1);
wait_until!(1, test_node.node().stats().received().0 as usize == 1);

let ping = Message::Ping(
<Client<CurrentNetwork>>::MESSAGE_VERSION,
CurrentNetwork::ALEO_MAXIMUM_FORK_DEPTH,
NodeType::Client,
State::Ready,
CurrentNetwork::genesis_block().hash(),
Data::Object(CurrentNetwork::genesis_block().header().clone()),
);

let init_recv_count = test_node.node().stats().received().0 as usize;
for i in 0..NUM_ITERATIONS {
let start = Instant::now();
test_node.send_direct_message(client_addr, ping.clone()).unwrap().await.unwrap();
wait_until!(1, test_node.node().stats().received().0 as usize == init_recv_count + i + 1);
avg_request_time += start.elapsed();
}
avg_request_time /= NUM_ITERATIONS as u32;

// Display the result.
println!("snarkOS ping time: {:?}", avg_request_time);
}
2 changes: 2 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ optional = true
[dev-dependencies.rusty-hook]
version = "0.11"

[dev-dependencies.snarkos]
path = "."
features = [ "test" ] # a workaround to use the `test` feature in tests by default

[profile.release]
opt-level = 3
lto = "thin"
Expand Down
13 changes: 13 additions & 0 deletions environment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,16 @@ impl<N: Network> Environment for ProverTrial<N> {
const MAXIMUM_NUMBER_OF_PEERS: usize = 21;
const COINBASE_IS_PUBLIC: bool = true;
}

#[derive(Clone, Debug, Default)]
pub struct TestEnvironment<N: Network>(PhantomData<N>);

#[rustfmt::skip]
impl<N: Network> Environment for TestEnvironment<N> {
type Network = N;
const NODE_TYPE: NodeType = NodeType::Prover;
const SYNC_NODES: &'static [&'static str] = &[];
const MINIMUM_NUMBER_OF_PEERS: usize = 1;
const MAXIMUM_NUMBER_OF_PEERS: usize = 5;
const COINBASE_IS_PUBLIC: bool = true;
}
2 changes: 1 addition & 1 deletion network/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ impl<N: Network, E: Environment> Ledger<N, E> {
///
/// Disconnects the given peer from the ledger.
///
async fn disconnect(&self, peer_ip: SocketAddr, reason: DisconnectReason) {
pub async fn disconnect(&self, peer_ip: SocketAddr, reason: DisconnectReason) {
info!("Disconnecting from {} ({:?})", peer_ip, reason);
// Remove all entries of the peer from the ledger.
self.remove_peer(&peer_ip).await;
Expand Down
Loading

0 comments on commit 2bd4e17

Please sign in to comment.