Skip to content
This repository has been archived by the owner on Oct 31, 2024. It is now read-only.

Commit

Permalink
feat: adding better port detection (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
Freyskeyd authored Jul 11, 2023
1 parent 2832fab commit 49b17e9
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
RUST_LOG: topos=warn

cert_delivery:
runs-on: ubuntu-latest
runs-on: ubuntu-latest-16-core
needs: [test_stable]
strategy:
fail-fast: true
Expand Down
6 changes: 2 additions & 4 deletions crates/topos-p2p/src/tests/support/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::net::UdpSocket;

use libp2p::{
identity::{self, ed25519::SecretKey, Keypair},
Multiaddr, PeerId,
};
use rstest::fixture;
use tokio::spawn;
use topos_test_sdk::networking::get_available_port;

use crate::{network::NetworkBuilder, Client, Runtime};

Expand Down Expand Up @@ -39,8 +38,7 @@ pub fn keypair_from_byte(seed: u8) -> Keypair {

pub fn local_peer(peer_index: u8) -> (Keypair, Multiaddr) {
let peer_id: Keypair = keypair_from_byte(peer_index);
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let port = socket.local_addr().unwrap().port();
let port = get_available_port();
let local_listen_addr: Multiaddr = format!("/ip4/127.0.0.1/tcp/{port}").parse().unwrap();
(peer_id, local_listen_addr)
}
47 changes: 14 additions & 33 deletions crates/topos-tce-api/tests/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use futures::Stream;
use rstest::rstest;
use serde::Deserialize;
use std::future::IntoFuture;
use std::{net::UdpSocket, time::Duration};
use std::time::Duration;
use test_log::test;
use tokio::sync::mpsc;
use tokio::{spawn, sync::oneshot};
Expand All @@ -23,6 +23,7 @@ use topos_core::{
use topos_tce_api::{Runtime, RuntimeEvent};
use topos_test_sdk::certificates::create_certificate_chain;
use topos_test_sdk::constants::*;
use topos_test_sdk::networking::get_available_addr;
use topos_test_sdk::storage::storage_client;
use topos_test_sdk::tce::public_api::{create_public_api, PublicApiContext};

Expand Down Expand Up @@ -200,14 +201,9 @@ async fn can_catchup_with_old_certs(
async fn can_catchup_with_old_certs_with_position() {
let (tx, mut rx) = mpsc::channel::<Certificate>(16);

let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let addr = socket.local_addr().ok().unwrap();

let graphql_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let graphql_addr = graphql_socket.local_addr().ok().unwrap();

let metrics_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let metrics_addr = metrics_socket.local_addr().ok().unwrap();
let addr = get_available_addr();
let graphql_addr = get_available_addr();
let metrics_addr = get_available_addr();

// launch data store
let certificates = create_certificate_chain(SOURCE_SUBNET_ID_1, &[TARGET_SUBNET_ID_1], 15);
Expand Down Expand Up @@ -328,14 +324,9 @@ async fn can_listen_for_multiple_subnet_id() {}
#[timeout(Duration::from_secs(2))]
#[test(tokio::test)]
async fn boots_healthy_graphql_server() {
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let addr = socket.local_addr().ok().unwrap();

let graphql_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let graphql_addr = graphql_socket.local_addr().ok().unwrap();

let metrics_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let metrics_addr = metrics_socket.local_addr().ok().unwrap();
let addr = get_available_addr();
let graphql_addr = get_available_addr();
let metrics_addr = get_available_addr();

// launch data store
let certificates = create_certificate_chain(SOURCE_SUBNET_ID_1, &[TARGET_SUBNET_ID_1], 15);
Expand Down Expand Up @@ -373,14 +364,9 @@ async fn boots_healthy_graphql_server() {
#[timeout(Duration::from_secs(2))]
#[test(tokio::test)]
async fn graphql_server_enables_cors() {
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let addr = socket.local_addr().ok().unwrap();

let graphql_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let graphql_addr = graphql_socket.local_addr().ok().unwrap();

let metrics_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let metrics_addr = metrics_socket.local_addr().ok().unwrap();
let addr = get_available_addr();
let graphql_addr = get_available_addr();
let metrics_addr = get_available_addr();

// launch data store
let certificates = create_certificate_chain(SOURCE_SUBNET_ID_1, &[TARGET_SUBNET_ID_1], 15);
Expand Down Expand Up @@ -442,14 +428,9 @@ async fn graphql_server_enables_cors() {
async fn can_query_graphql_endpoint_for_certificates() {
let (tx, mut rx) = mpsc::channel::<Certificate>(16);

let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let addr = socket.local_addr().ok().unwrap();

let graphql_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let graphql_addr = graphql_socket.local_addr().ok().unwrap();

let metrics_socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let metrics_addr = metrics_socket.local_addr().ok().unwrap();
let addr = get_available_addr();
let graphql_addr = get_available_addr();
let metrics_addr = get_available_addr();

// launch data store
let certificates = create_certificate_chain(SOURCE_SUBNET_ID_1, &[TARGET_SUBNET_ID_1], 15);
Expand Down
1 change: 1 addition & 0 deletions crates/topos-test-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod certificates;
#[cfg(feature = "tce")]
pub mod tce;

pub mod networking;
pub mod p2p;
pub mod sequencer;
pub mod storage;
Expand Down
22 changes: 22 additions & 0 deletions crates/topos-test-sdk/src/networking/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use std::net::SocketAddr;
use std::net::{TcpListener, TcpStream};

pub fn get_available_port() -> u16 {
get_available_addr().port()
}

pub fn get_available_addr() -> SocketAddr {
let host = "127.0.0.1";

let listener = TcpListener::bind((host, 0)).expect("Can't bind to an available port");
let addr = listener
.local_addr()
.expect("Can't extract local addr from listener");

// Forcing the port into the TIME_WAIT state is necessary to ensure that the port will be
// reserved from some limited amount of time (roughly 60s on some Linux systems)
let _sender = TcpStream::connect(addr).expect("Can't connect to an available port");
let _incoming = listener.accept().expect("Can't accept connection");

addr
}
7 changes: 3 additions & 4 deletions crates/topos-test-sdk/src/p2p/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use std::net::UdpSocket;

use libp2p::{
identity::{self, Keypair},
Multiaddr,
};

use crate::networking::get_available_port;

pub type Port = u16;

pub fn local_peer(peer_index: u8) -> (Keypair, Port, Multiaddr) {
let peer_id: Keypair = keypair_from_seed(peer_index);
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
let port = socket.local_addr().unwrap().port();
let port = get_available_port();
let local_listen_addr: Multiaddr = format!(
"/ip4/127.0.0.1/tcp/{}/p2p/{}",
port,
Expand Down
33 changes: 6 additions & 27 deletions crates/topos-test-sdk/src/tce/public_api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::net::SocketAddr;
use std::net::UdpSocket;
use std::str::FromStr;

use futures::Stream;
Expand All @@ -13,6 +11,7 @@ use topos_tce_api::RuntimeClient;
use topos_tce_api::RuntimeEvent;
use topos_tce_storage::StorageClient;

use crate::networking::get_available_addr;
use crate::storage::storage_client;

pub struct PublicApiContext {
Expand All @@ -22,37 +21,17 @@ pub struct PublicApiContext {
pub console_client: ConsoleServiceClient<Channel>,
}

#[fixture]
fn default_public_api_addr() -> SocketAddr {
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
socket.local_addr().expect("Can't extract local_addr")
}

#[fixture]
fn default_public_graphql_addr() -> SocketAddr {
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
socket.local_addr().expect("Can't extract local_addr")
}

#[fixture]
fn default_public_metrics_addr() -> SocketAddr {
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port");
socket.local_addr().expect("Can't extract local_addr")
}

#[fixture]
pub async fn create_public_api(
#[future] storage_client: StorageClient,
default_public_api_addr: SocketAddr,
default_public_graphql_addr: SocketAddr,
default_public_metrics_addr: SocketAddr,
) -> (PublicApiContext, impl Stream<Item = RuntimeEvent>) {
let storage_client = storage_client.await;
let grpc_addr = default_public_api_addr;
let api_port = grpc_addr.port();

let graphql_addr = default_public_graphql_addr;
let metrics_addr = default_public_metrics_addr;
let grpc_addr = get_available_addr();
let graphql_addr = get_available_addr();
let metrics_addr = get_available_addr();

let api_port = grpc_addr.port();

let api_endpoint = format!("http://0.0.0.0:{api_port}");
let (client, stream) = topos_tce_api::Runtime::builder()
Expand Down
6 changes: 3 additions & 3 deletions crates/topos/tests/tce.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod utils;

use std::{net::UdpSocket, process::Command, time::Duration};
use std::{process::Command, time::Duration};

use assert_cmd::prelude::*;
use futures::FutureExt;
Expand All @@ -11,6 +11,7 @@ use topos_core::api::grpc::tce::v1::{
console_service_server::{ConsoleService, ConsoleServiceServer},
PushPeerListRequest, PushPeerListResponse, StatusRequest, StatusResponse,
};
use topos_test_sdk::networking::get_available_addr;

#[test]
fn help_display() -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -28,8 +29,7 @@ fn help_display() -> Result<(), Box<dyn std::error::Error>> {

#[tokio::test]
async fn do_not_push_empty_list() -> Result<(), Box<dyn std::error::Error>> {
let socket = UdpSocket::bind("0.0.0.0:0").expect("Can't find an available port on host");
let addr = socket.local_addr().unwrap();
let addr = get_available_addr();
let port = addr.port();

let server = ConsoleServiceServer::new(DummyServer);
Expand Down

0 comments on commit 49b17e9

Please sign in to comment.