Skip to content

Commit e0463f3

Browse files
committed
test: Update feature_bind_port_discover.py to use dynamic ports and add comprehensive test coverage
Signed-off-by: b-l-u-e <[email protected]>
1 parent 97fa4e9 commit e0463f3

File tree

1 file changed

+66
-26
lines changed

1 file changed

+66
-26
lines changed

test/functional/feature_bind_port_discover.py

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,67 @@
1010
from test_framework.util import (
1111
assert_equal,
1212
assert_not_equal,
13+
p2p_port,
14+
tor_port,
1315
)
1416

15-
# We need to bind to a routable address for this test to exercise the relevant code
16-
# and also must have another routable address on another interface which must not
17-
# be named "lo" or "lo0".
18-
# To set these routable addresses on the machine, use:
17+
# We need to bind to routable addresses for this test. Both addresses must be on an
18+
# interface that is UP and not a loopback interface (IFF_LOOPBACK). To set these
19+
# routable addresses on the machine, use:
1920
# Linux:
20-
# ifconfig lo:0 1.1.1.1/32 up && ifconfig lo:1 2.2.2.2/32 up # to set up
21-
# ifconfig lo:0 down && ifconfig lo:1 down # to remove it, after the test
21+
# First find your interfaces: ip addr show
22+
# Then use your actual interface names (replace INTERFACE_NAME with yours):
23+
# ip addr add 1.1.1.1/32 dev INTERFACE_NAME && ip addr add 2.2.2.2/32 dev INTERFACE_NAME # to set up
24+
# ip addr del 1.1.1.1/32 dev INTERFACE_NAME && ip addr del 2.2.2.2/32 dev INTERFACE_NAME # to remove it
25+
#
26+
# macOS:
27+
# ifconfig en0 alias 1.1.1.1 && ifconfig en0 alias 2.2.2.2 # to set up
28+
# ifconfig en0 1.1.1.1 -alias && ifconfig en0 2.2.2.2 -alias # to remove it, after the test
29+
#
2230
# FreeBSD:
2331
# ifconfig em0 1.1.1.1/32 alias && ifconfig wlan0 2.2.2.2/32 alias # to set up
2432
# ifconfig em0 1.1.1.1 -alias && ifconfig wlan0 2.2.2.2 -alias # to remove it, after the test
2533
ADDR1 = '1.1.1.1'
2634
ADDR2 = '2.2.2.2'
2735

28-
BIND_PORT = 31001
29-
3036
class BindPortDiscoverTest(BitcoinTestFramework):
3137
def set_test_params(self):
3238
# Avoid any -bind= on the command line. Force the framework to avoid adding -bind=127.0.0.1.
33-
self.setup_clean_chain = True
3439
self.bind_to_localhost_only = False
40+
# Get dynamic ports for each node from the test framework
41+
self.bind_ports = [
42+
p2p_port(0),
43+
p2p_port(2), # node0 will use their port + 1 for onion listen, which is the same as p2p_port(1), so avoid collision
44+
p2p_port(3),
45+
p2p_port(4),
46+
]
3547
self.extra_args = [
36-
['-discover', f'-port={BIND_PORT}'], # bind on any
37-
['-discover', f'-bind={ADDR1}:{BIND_PORT}'],
48+
['-discover', f'-port={self.bind_ports[0]}', '-listen=1'], # Without any -bind
49+
['-discover', f'-bind=0.0.0.0:{self.bind_ports[1]}'], # Explicit -bind=0.0.0.0
50+
# Explicit -whitebind=0.0.0.0, add onion bind to avoid port conflict
51+
['-discover', f'-whitebind=0.0.0.0:{self.bind_ports[2]}', f'-bind=127.0.0.1:{tor_port(3)}=onion'],
52+
['-discover', f'-bind={ADDR1}:{self.bind_ports[3]}'], # Explicit -bind=routable_addr
3853
]
3954
self.num_nodes = len(self.extra_args)
4055

56+
def setup_network(self):
57+
"""
58+
Override to avoid connecting nodes together. This test intentionally does not connect nodes
59+
because each node is bound to a different address or interface, and connections are not needed.
60+
"""
61+
self.setup_nodes()
62+
63+
def setup_nodes(self):
64+
"""
65+
Override to set has_explicit_bind=True for nodes with explicit bind arguments.
66+
"""
67+
self.add_nodes(self.num_nodes, self.extra_args)
68+
# TestNode.start() will add -bind= to extra_args if has_explicit_bind is
69+
# False. We do not want any -bind= thus set has_explicit_bind to True.
70+
for node in self.nodes:
71+
node.has_explicit_bind = True
72+
self.start_nodes()
73+
4174
def add_options(self, parser):
4275
parser.add_argument(
4376
"--ihave1111and2222", action='store_true', dest="ihave1111and2222",
@@ -52,28 +85,35 @@ def skip_test_if_missing_module(self):
5285

5386
def run_test(self):
5487
self.log.info(
55-
"Test that if -bind= is not passed then all addresses are "
88+
"Test that if -bind= is not passed or -bind=0.0.0.0 is used then all addresses are "
5689
"added to localaddresses")
57-
found_addr1 = False
58-
found_addr2 = False
59-
for local in self.nodes[0].getnetworkinfo()['localaddresses']:
60-
if local['address'] == ADDR1:
61-
found_addr1 = True
62-
assert_equal(local['port'], BIND_PORT)
63-
if local['address'] == ADDR2:
64-
found_addr2 = True
65-
assert_equal(local['port'], BIND_PORT)
66-
assert found_addr1
67-
assert found_addr2
90+
for i in [0, 1, 2]:
91+
found_addr1 = False
92+
found_addr2 = False
93+
localaddresses = self.nodes[i].getnetworkinfo()['localaddresses']
94+
for local in localaddresses:
95+
if local['address'] == ADDR1:
96+
found_addr1 = True
97+
assert_equal(local['port'], self.bind_ports[i])
98+
if local['address'] == ADDR2:
99+
found_addr2 = True
100+
assert_equal(local['port'], self.bind_ports[i])
101+
if not found_addr1:
102+
self.log.error(f"Address {ADDR1} not found in node{i}'s local addresses: {localaddresses}")
103+
assert False
104+
if not found_addr2:
105+
self.log.error(f"Address {ADDR2} not found in node{i}'s local addresses: {localaddresses}")
106+
assert False
68107

69108
self.log.info(
70-
"Test that if -bind= is passed then only that address is "
109+
"Test that if -bind=routable_addr is passed then only that address is "
71110
"added to localaddresses")
72111
found_addr1 = False
73-
for local in self.nodes[1].getnetworkinfo()['localaddresses']:
112+
i = 3
113+
for local in self.nodes[i].getnetworkinfo()['localaddresses']:
74114
if local['address'] == ADDR1:
75115
found_addr1 = True
76-
assert_equal(local['port'], BIND_PORT)
116+
assert_equal(local['port'], self.bind_ports[i])
77117
assert_not_equal(local['address'], ADDR2)
78118
assert found_addr1
79119

0 commit comments

Comments
 (0)