Skip to content

Commit

Permalink
fix: support parallel servers in tests
Browse files Browse the repository at this point in the history
In order to add additional integration tests, the Web and RPC servers
must run on unique addresses, otherwise trying to create an additional
server will fail due to the socket already being in use.

This is achieved by selecting the port dynamically, through setting the
port as 0 (dynamic port), which `local_addr` then resolves into an
the actual port selected, that is, replacing `127.0.0.1:0` with
`127.0.0.1:<available_port_that_was_bound_by_TcpListener>`
  • Loading branch information
Gilad Chase committed Jul 4, 2024
1 parent 26060ef commit fd11822
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
18 changes: 17 additions & 1 deletion crates/tests-integration/src/integration_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use starknet_gateway::errors::GatewayError;
use starknet_gateway::gateway::Gateway;
use starknet_mempool_types::communication::SharedMempoolClient;
use test_utils::starknet_api_test_utils::external_tx_to_json;
use tokio::net::TcpListener;

use crate::state_reader::rpc_test_state_reader_factory;

Expand All @@ -27,7 +28,7 @@ pub async fn create_gateway(
..Default::default()
};

let socket: SocketAddr = "127.0.0.1:3000".parse().unwrap();
let socket = get_available_socket().await;
let network_config = GatewayNetworkConfig { ip: socket.ip(), port: socket.port() };
let stateful_tx_validator_config = StatefulTransactionValidatorConfig::create_for_testing();

Expand Down Expand Up @@ -80,3 +81,18 @@ impl GatewayClient {
.unwrap()
}
}

/// Returns a unique IP address and port for testing purposes.
///
/// Tests run in parallel, so servers (like RPC or web) running on separate tests must have
/// different ports, otherwise the server will fail with "address already in use".
pub async fn get_available_socket() -> SocketAddr {
// Dinamically select port.
// First, set the port to 0 (dynamic port).
TcpListener::bind("127.0.0.1:0")
.await
.expect("Failed to bind to address")
// Then, resolve to the actual selected port.
.local_addr()
.expect("Failed to get local address")
}
7 changes: 6 additions & 1 deletion crates/tests-integration/src/state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ use tempfile::tempdir;
use test_utils::starknet_api_test_utils::{deploy_account_tx, deployed_account_contract_address};
use tokio::sync::RwLock;

use crate::integration_test_utils::get_available_socket;

type ContractClassesMap =
(Vec<(ClassHash, DeprecatedContractClass)>, Vec<(ClassHash, CasmContractClass)>);

Expand Down Expand Up @@ -306,7 +308,10 @@ fn get_test_pending_classes() -> Arc<RwLock<PendingClasses>> {
}

async fn run_papyrus_rpc_server(storage_reader: StorageReader) -> SocketAddr {
let rpc_config = RpcConfig::default();
let rpc_config = RpcConfig {
server_address: get_available_socket().await.to_string(),
..Default::default()
};
let (addr, handle) = run_server(
&rpc_config,
get_test_highest_block(),
Expand Down

0 comments on commit fd11822

Please sign in to comment.