From 3555ef3e542d3b8c9f22d21ea89811382d20c86b Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Mon, 26 Oct 2026 13:36:48 +0000 Subject: [PATCH] util: new `test_socket()` utility function --- mmgen/daemon.py | 13 ++----------- mmgen/proto/xmr/daemon.py | 7 ++----- mmgen/rpc/local.py | 7 ++----- mmgen/util.py | 11 +++++++++++ mmgen/util2.py | 9 --------- test/cmdtest_d/httpd/__init__.py | 5 ++--- test/cmdtest_d/include/proxy.py | 5 ++--- 7 files changed, 21 insertions(+), 36 deletions(-) diff --git a/mmgen/daemon.py b/mmgen/daemon.py index e91134dc..0d682e2a 100644 --- a/mmgen/daemon.py +++ b/mmgen/daemon.py @@ -25,7 +25,7 @@ from pathlib import Path from .cfg import gc from .base_obj import Lockable -from .util import msg, Msg_r, die, remove_dups, oneshot_warning, fmt_list +from .util import msg, Msg_r, die, remove_dups, oneshot_warning, fmt_list, test_socket from .flags import ClassFlags, ClassOpts _dd = namedtuple('daemon_data', ['coind_name', 'coind_version', 'coind_version_str']) # latest tested version @@ -150,7 +150,7 @@ class Daemon(Lockable): def state(self): if self.debug: msg(f'Testing port {self.bind_port}') - return 'ready' if self.test_socket('localhost', self.bind_port) else 'stopped' + return 'ready' if test_socket('localhost', self.bind_port, timeout=10) else 'stopped' @property def start_cmds(self): @@ -227,15 +227,6 @@ class Daemon(Lockable): self.stop(silent=silent) return self.start(silent=silent) - def test_socket(self, host, port, *, timeout=10): - import socket - try: - socket.create_connection((host, port), timeout=timeout).close() - except ConnectionError: - return False - else: - return True - def wait_for_state(self, req_state): for _ in range(self.cfg.daemon_state_timeout * 5): if self.state == req_state: diff --git a/mmgen/proto/xmr/daemon.py b/mmgen/proto/xmr/daemon.py index 74e457a9..e72e017c 100644 --- a/mmgen/proto/xmr/daemon.py +++ b/mmgen/proto/xmr/daemon.py @@ -13,7 +13,7 @@ proto.xmr.daemon: Monero base protocol daemon classes from pathlib import Path from ...cfg import gc -from ...util import list_gen, die, contains_any +from ...util import list_gen, die, contains_any, test_socket from ...daemon import CoinDaemon, RPCDaemon, _nw, _dd class monero_daemon(CoinDaemon): @@ -128,10 +128,7 @@ class MoneroWalletDaemon(RPCDaemon): proto = proto).rpc_port) if test_monerod and self.monerod_port: - import socket - try: - socket.create_connection(('localhost', self.monerod_port), timeout=1).close() - except ConnectionError: + if not test_socket('localhost', self.monerod_port, timeout=1): die('SocketError', f'Unable to connect to Monero daemon at localhost:{self.monerod_port}') self.user = user or self.cfg.wallet_rpc_user or self.cfg.monero_wallet_rpc_user diff --git a/mmgen/rpc/local.py b/mmgen/rpc/local.py index 6b1cfda8..77a414eb 100644 --- a/mmgen/rpc/local.py +++ b/mmgen/rpc/local.py @@ -13,7 +13,7 @@ rpc.local: local RPC client class for the MMGen Project import json, asyncio, importlib from ..cfg import gc -from ..util import msg, die, fmt, oneshot_warning, isAsync +from ..util import msg, die, fmt, oneshot_warning, isAsync, test_socket from . import util @@ -41,10 +41,7 @@ class RPCClient: util.dmsg_rpc(f' cls [{self.name}] host [{host}] port [{port}]\n') if test_connection: - import socket - try: - socket.create_connection((host, port), timeout=1).close() - except ConnectionError: + if not test_socket(host, port, timeout=1): die('SocketError', f'Unable to connect to {host}:{port}') self.http_hdrs = {'Content-Type': 'application/json'} diff --git a/mmgen/util.py b/mmgen/util.py index 14d1b923..91d1b52c 100644 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -518,3 +518,14 @@ def cached_property(orig_func): def isAsync(func): return bool(func.__code__.co_flags & 128) + +def test_socket(host, port, *, timeout=None): + import socket + try: + socket.create_connection( + (host, port), + **({} if timeout is None else {'timeout': timeout})).close() + except ConnectionError: + return False + else: + return True diff --git a/mmgen/util2.py b/mmgen/util2.py index 850afd26..6b3828bb 100644 --- a/mmgen/util2.py +++ b/mmgen/util2.py @@ -244,15 +244,6 @@ def cliargs_convert(args): return tuple(gen()) -def port_in_use(port): - import socket - try: - socket.create_connection(('localhost', port)).close() - except ConnectionError: - return False - else: - return True - class ExpInt(int): 'encode or parse an integer in exponential notation with specified precision' diff --git a/test/cmdtest_d/httpd/__init__.py b/test/cmdtest_d/httpd/__init__.py index 937239ea..d48f89bb 100644 --- a/test/cmdtest_d/httpd/__init__.py +++ b/test/cmdtest_d/httpd/__init__.py @@ -12,8 +12,7 @@ test.cmdtest_d.httpd: WSGI http server from wsgiref.simple_server import make_server, WSGIRequestHandler -from mmgen.util import msg -from mmgen.util2 import port_in_use +from mmgen.util import msg, test_socket # pylint: disable=no-name-in-module class SilentRequestHandler(WSGIRequestHandler): @@ -27,7 +26,7 @@ class HTTPD: def start(self): - if port_in_use(self.port): + if test_socket('localhost', self.port): msg(f'\nPort {self.port} in use. Assuming {self.name} is running') return True diff --git a/test/cmdtest_d/include/proxy.py b/test/cmdtest_d/include/proxy.py index 0cc35363..66dea6db 100644 --- a/test/cmdtest_d/include/proxy.py +++ b/test/cmdtest_d/include/proxy.py @@ -14,8 +14,7 @@ import atexit from subprocess import run from mmgen.cfg import gc -from mmgen.util import msg, die, fmt -from mmgen.util2 import port_in_use +from mmgen.util import msg, die, fmt, test_socket # pylint: disable=no-name-in-module from ...include.common import omsg @@ -72,7 +71,7 @@ class TestProxy: b1 = ['localhost', 'true'] b2 = ['-fN', '-E', 'txrelay-proxy.debug', 'localhost'] - if port_in_use(self.port): + if test_socket('localhost', self.port): omsg(f'Port {self.port} already in use. Assuming SSH SOCKS server is running') else: cp = run(a + b0 + b1, capture_output=True, text=True)