From beb45fc514d78f91fde18a602d475ff55102c4fe Mon Sep 17 00:00:00 2001 From: Arya Date: Thu, 10 Nov 2022 18:23:12 -0500 Subject: [PATCH] change(tests): use OS-assigned unallocated ports for getting random known ports (#5607) * updates mod docs for tests that use future blocks * updates submitblock test to use TestType methods * prunes redundant code * adds check_sync_logs_until * adds assertion for needs cached state & rpc server * updates get_raw_future_blocks fn with rpc calls * updates to get_raw_future_blocks fn and submit_block test * Rename LightwalletdTestType to TestType * moves TestType and random_known_rpc_port_config to test_type.rs and config.rs * moves get_raw_future_blocks to cached_state.rs * updates ci workflows to include submit block test * adds get_future_blocks fn and uses it in load_transactions_from_future_blocks * updates CI docker * Apply suggestions from code review Co-authored-by: teor * Applies suggestions from code review * Updates misnamed closure param * updates mod docs for test_type.rs * updates random_known_port to ask the OS for a port * uses old random_known_port for windows Co-authored-by: teor Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- zebra-test/src/net.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/zebra-test/src/net.rs b/zebra-test/src/net.rs index a12398c78..69ff9df8b 100644 --- a/zebra-test/src/net.rs +++ b/zebra-test/src/net.rs @@ -2,8 +2,6 @@ use std::env; -use rand::Rng; - /// The name of the env var that skips Zebra tests which need reliable, /// fast network connectivity. /// @@ -47,6 +45,7 @@ pub fn zebra_skip_ipv6_tests() -> bool { false } +#[cfg(windows)] /// Returns a random port number from the ephemeral port range. /// /// Does not check if the port is already in use. It's impossible to do this @@ -62,6 +61,7 @@ pub fn zebra_skip_ipv6_tests() -> bool { /// times. For example: setting up both ends of a connection, or re-using /// the same port multiple times. pub fn random_known_port() -> u16 { + use rand::Rng; // Use the intersection of the IANA/Windows/macOS ephemeral port range, // and the Linux ephemeral port range: // - https://en.wikipedia.org/wiki/Ephemeral_port#Range @@ -80,6 +80,44 @@ pub fn random_known_port() -> u16 { rand::thread_rng().gen_range(53500..60999) } +#[cfg(not(windows))] +/// Uses the "magic" port number that tells the operating system to +/// choose a random unallocated port. +/// +/// The OS chooses a different port each time it opens a connection or +/// listener with this magic port number. +/// +/// Creates a TcpListener to find a random unallocated port, then drops the TcpListener to close the socket. +/// +/// Returns the unallocated port number. +/// +/// ## Usage +/// +/// If you want a once-off random unallocated port, use +/// `random_unallocated_port`. Don't use this function if you don't need +/// to - it has a small risk of port conflicts when there is a delay +/// between this fn call and binding the tcp listener. +/// +/// Use this function when you need to use the same random port multiple +/// times. For example: setting up both ends of a connection, or re-using +/// the same port multiple times. +/// +/// ## Panics +/// +/// If the OS finds no available ports +/// +/// If there is an OS error when getting the socket address +pub fn random_known_port() -> u16 { + use std::net::{Ipv4Addr, SocketAddrV4, TcpListener}; + + let host_ip = Ipv4Addr::new(127, 0, 0, 1); + let socket = TcpListener::bind(SocketAddrV4::new(host_ip, random_unallocated_port())) + .expect("needs an available port") + .local_addr() + .expect("OS error: could not get socket addr"); + socket.port() +} + /// Returns the "magic" port number that tells the operating system to /// choose a random unallocated port. ///