mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-02-03 22:03:01 +01:00
Merge bitcoin/bitcoin#34186: test: use dynamic port allocation in proxy tests
ce63d37ebetest: use dynamic port allocation to avoid test conflicts (woltx) Pull request description: Use `port=0` for dynamic port allocation in test framework components to avoid intermittent "address already in use" errors when running tests concurrently or when ports are stuck in TIME_WAIT state. Example: https://github.com/bitcoin/bitcoin/pull/29415#discussion_r2634509304 Changes: - Update `socks5.py` and `p2p.py` to support dynamic port allocation - Convert `feature_proxy.py` and `feature_anchors.py` to use `port=0` ACKs for top commit: achow101: ACKce63d37ebevasild: ACKce63d37ebemzumsande: re-ACKce63d37ebeTree-SHA512: 4efcedca3bde209fbd1bdc2a4ae04b7d53515587d86e421ce61064f78c675c71b45d9782b514c5e7cfc0e92842c947d49f7a3fddb03fe619fcdec9b565f0ecbd
This commit is contained in:
@@ -10,7 +10,7 @@ from test_framework.p2p import P2PInterface, P2P_SERVICES
|
||||
from test_framework.socks5 import Socks5Configuration, Socks5Server
|
||||
from test_framework.messages import CAddress, hash256
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import check_node_connections, assert_equal, p2p_port
|
||||
from test_framework.util import check_node_connections, assert_equal
|
||||
|
||||
INBOUND_CONNECTIONS = 5
|
||||
BLOCK_RELAY_CONNECTIONS = 2
|
||||
@@ -92,7 +92,9 @@ class AnchorsTest(BitcoinTestFramework):
|
||||
onion_conf = Socks5Configuration()
|
||||
onion_conf.auth = True
|
||||
onion_conf.unauth = True
|
||||
onion_conf.addr = ('127.0.0.1', p2p_port(self.num_nodes))
|
||||
# Use port=0 for dynamic allocation to avoid conflicts with concurrent
|
||||
# tests or ports in TIME_WAIT state from previous test runs.
|
||||
onion_conf.addr = ('127.0.0.1', 0)
|
||||
onion_conf.keep_alive = True
|
||||
onion_proxy = Socks5Server(onion_conf)
|
||||
onion_proxy.start()
|
||||
|
||||
@@ -46,10 +46,7 @@ import tempfile
|
||||
|
||||
from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
p2p_port,
|
||||
)
|
||||
from test_framework.util import assert_equal
|
||||
from test_framework.netutil import test_ipv6_local, test_unix_socket
|
||||
|
||||
# Networks returned by RPC getpeerinfo.
|
||||
@@ -74,22 +71,24 @@ class ProxyTest(BitcoinTestFramework):
|
||||
def setup_nodes(self):
|
||||
self.have_ipv6 = test_ipv6_local()
|
||||
self.have_unix_sockets = test_unix_socket()
|
||||
# Create two proxies on different ports
|
||||
# Create two proxies on different ports.
|
||||
# Use port=0 to let the OS assign available ports, avoiding
|
||||
# "address already in use" errors from concurrent tests.
|
||||
# ... one unauthenticated
|
||||
self.conf1 = Socks5Configuration()
|
||||
self.conf1.addr = ('127.0.0.1', p2p_port(self.num_nodes))
|
||||
self.conf1.addr = ('127.0.0.1', 0)
|
||||
self.conf1.unauth = True
|
||||
self.conf1.auth = False
|
||||
# ... one supporting authenticated and unauthenticated (Tor)
|
||||
self.conf2 = Socks5Configuration()
|
||||
self.conf2.addr = ('127.0.0.1', p2p_port(self.num_nodes + 1))
|
||||
self.conf2.addr = ('127.0.0.1', 0)
|
||||
self.conf2.unauth = True
|
||||
self.conf2.auth = True
|
||||
if self.have_ipv6:
|
||||
# ... one on IPv6 with similar configuration
|
||||
self.conf3 = Socks5Configuration()
|
||||
self.conf3.af = socket.AF_INET6
|
||||
self.conf3.addr = ('::1', p2p_port(self.num_nodes + 2))
|
||||
self.conf3.addr = ('::1', 0)
|
||||
self.conf3.unauth = True
|
||||
self.conf3.auth = True
|
||||
else:
|
||||
|
||||
@@ -787,13 +787,14 @@ class NetworkThread(threading.Thread):
|
||||
cls.protos[(addr, port)] = None
|
||||
return response
|
||||
|
||||
if (addr, port) not in cls.listeners:
|
||||
if port == 0 or (addr, port) not in cls.listeners:
|
||||
# When creating a listener on a given (addr, port) we only need to
|
||||
# do it once. If we want different behaviors for different
|
||||
# connections, we can accomplish this by providing different
|
||||
# `proto` functions
|
||||
|
||||
listener = await cls.network_event_loop.create_server(peer_protocol, addr, port)
|
||||
port = listener.sockets[0].getsockname()[1]
|
||||
logger.debug("Listening server on %s:%d should be started" % (addr, port))
|
||||
cls.listeners[(addr, port)] = listener
|
||||
|
||||
|
||||
@@ -203,6 +203,9 @@ class Socks5Server():
|
||||
self.s = socket.socket(conf.af)
|
||||
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self.s.bind(conf.addr)
|
||||
# When port=0, the OS assigns an available port. Update conf.addr
|
||||
# to reflect the actual bound address so callers can use it.
|
||||
self.conf.addr = self.s.getsockname()
|
||||
self.s.listen(5)
|
||||
self.running = False
|
||||
self.thread = None
|
||||
|
||||
Reference in New Issue
Block a user