util: new test_socket() utility function

This commit is contained in:
The MMGen Project 2026-10-26 13:36:48 +00:00
commit 3555ef3e54
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
7 changed files with 21 additions and 36 deletions

View file

@ -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:

View file

@ -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

View file

@ -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'}

View file

@ -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

View file

@ -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'

View file

@ -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

View file

@ -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)