diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index ffb8ecfe197..8189fe0b1ee 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -74,7 +74,7 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkg install python3 databases/py-sqlite3 net/py-pyzmq +pkg install python3 databases/py-sqlite3 net/py-pyzmq lsof ``` --- diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index d4d031d3144..22a697d731b 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -93,7 +93,14 @@ There is an included test suite that is useful for testing code changes when dev To run the test suite (recommended), you will need to have Python 3 installed: ```bash -pkgin install python313 py313-zmq +pkgin install python313 py313-zmq lsof +``` + +When the `lsof` binary package was built for a different point release, it might be necessary to force its installation as follows: + +```bash +echo "CHECK_OSABI=no" >> /etc/pkg_install.conf +pkgin install lsof ``` ## Building Bitcoin Core diff --git a/test/functional/feature_bind_extra.py b/test/functional/feature_bind_extra.py index 91f846d6f69..2b81e9210e0 100755 --- a/test/functional/feature_bind_extra.py +++ b/test/functional/feature_bind_extra.py @@ -33,6 +33,7 @@ class BindExtraTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_platform_not_posix() + self.skip_if_no_lsof_on_nonlinux() def setup_network(self): loopback_ipv4 = addr_to_hex("127.0.0.1") diff --git a/test/functional/rpc_bind.py b/test/functional/rpc_bind.py index 4494dde5dcf..81e916bb81f 100755 --- a/test/functional/rpc_bind.py +++ b/test/functional/rpc_bind.py @@ -17,6 +17,7 @@ class RPCBindTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_platform_not_posix() + self.skip_if_no_lsof_on_nonlinux() def setup_network(self): self.add_nodes(self.num_nodes, None) diff --git a/test/functional/test_framework/netutil.py b/test/functional/test_framework/netutil.py index a13ee61e59f..fdf76f8b916 100644 --- a/test/functional/test_framework/netutil.py +++ b/test/functional/test_framework/netutil.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-present The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Linux, macOS, and BSD network utilities. +"""Linux, macOS, BSD and illumos network utilities. Roughly based on https://web.archive.org/web/20190424172231/http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal """ @@ -105,11 +105,13 @@ def get_bind_addrs(pid): if conn[3] == STATE_LISTEN and conn[4] in inodes: bind_addrs.append(conn[1]) return bind_addrs - elif sys.platform.startswith(("darwin", "freebsd", "netbsd", "openbsd")): + # OpenBSD is not included, as it does not ship the lsof utility. + elif sys.platform.startswith(("darwin", "freebsd", "netbsd", "sunos5")): import re import subprocess output = subprocess.check_output(["lsof", - *(["-Di"] if sys.platform.startswith("freebsd") else []), # Ignore device cache to avoid stderr warnings. + *(["-Di"] if sys.platform.startswith(("freebsd", "netbsd", "sunos5")) else []), # Ignore device cache to avoid stderr warnings. + *(["-w"] if sys.platform.startswith("netbsd") else []), # Ignore point release mismatch warnings. "-nP", # Keep hosts and ports numeric. "-a", # Require all filters to match. "-p", str(pid), # Limit results to the target pid. @@ -151,14 +153,14 @@ def all_interfaces(): return [(namestr[i:i+16].split(b'\0', 1)[0], socket.inet_ntoa(namestr[i+20:i+24])) for i in range(0, outbytes, struct_size)] - elif sys.platform.startswith(("darwin", "freebsd", "netbsd", "openbsd")): + elif sys.platform.startswith(("darwin", "freebsd", "netbsd", "openbsd", "sunos5")): import re import subprocess output = subprocess.check_output(["ifconfig", "-au"], text=True) return [ (m["iface"].encode(), ip) for m in re.finditer(r"(?m)^(?P\S+):(?P[^\n]*(?:\n[ \t]+[^\n]*)*)", output) - for ip in re.findall(r"inet (\S+)", m["block"]) + for ip in re.findall(r"inet ([^\s/]+)", m["block"]) ] else: raise NotImplementedError(f"all_interfaces is not supported on {sys.platform}") diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 8559a2ae611..f1a8fdefd01 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -1027,6 +1027,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): if platform.system() != "Linux": raise SkipTest("not on a Linux system") + def skip_if_no_lsof_on_nonlinux(self): + """Skip the running test if the lsof utility is not available on non-Linux platforms.""" + if sys.platform != "linux" and shutil.which("lsof") is None: + raise SkipTest("lsof not available") + def skip_if_platform_not_posix(self): """Skip the running test if we are not on a POSIX platform""" if os.name != 'posix':