daemon: user-based port shifts, move port shift logic to test suite

This commit is contained in:
The MMGen Project 2026-09-21 10:30:52 +00:00
commit 0150a0ff2a
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
10 changed files with 69 additions and 38 deletions

View file

@ -46,13 +46,14 @@ class Daemon(Lockable):
new_console_mswin = False
lockfile = None
private_port = None
port_shift = 0
disable_authentication = False
avail_opts = ()
avail_flags = () # like opts, but can be set or unset after instantiation
_reset_ok = ('debug', 'wait', 'pids')
version_info_arg = '--version'
def __init__(self, cfg, *, opts=None, flags=None, test_suite=None):
def __init__(self, cfg, *, opts=None, flags=None, test_suite=None, test_user=None):
self.cfg = cfg
if gc.platform == 'win32':
@ -63,6 +64,7 @@ class Daemon(Lockable):
self.flag = ClassFlags(self, flags)
self.debug = self.debug or cfg.debug_daemon
self.test_suite = cfg.test_suite if test_suite is None else test_suite
self.test_user = test_user
def exec_cmd_thread(self, cmd):
import threading
@ -279,7 +281,6 @@ class CoinDaemon(Daemon):
avail_flags = ('keep_cfg_file',)
avail_opts = ('no_daemonize', 'online')
testnet_dir = 'testnet'
test_suite_port_shift = 1237
rpc_user = None
rpc_password = None
@ -343,8 +344,6 @@ class CoinDaemon(Daemon):
*,
network_id = None,
proto = None,
port_shift = None,
p2p_port = None,
datadir = None,
daemon_id = None,
**kwargs):
@ -391,8 +390,6 @@ class CoinDaemon(Daemon):
*,
network_id = None,
proto = None,
port_shift = None,
p2p_port = None,
datadir = None,
daemon_id = None,
**kwargs):
@ -428,15 +425,14 @@ class CoinDaemon(Daemon):
if self.proto.base_proto == 'Bitcoin' or not self.test_suite else
self.datadir)
ps_adj = (port_shift or 0) + (self.test_suite_port_shift if self.test_suite else 0)
self.rpc_port = (
self.proto.rpc_port or
cfg.rpc_port or
(self.dfl_rpc_port + self.port_shift))
# user-set values take precedence
usr_rpc_port = self.proto.rpc_port or cfg.rpc_port
self.rpc_port = usr_rpc_port + (port_shift or 0) if usr_rpc_port else ps_adj + self.dfl_rpc_port
self.p2p_port = (
p2p_port or (
self.dfl_p2p_port + ps_adj if self.dfl_p2p_port and (self.test_suite or ps_adj) else None
) if self.network != 'regtest' else None)
None if self.dfl_p2p_port is None or self.network == 'regtest' else
(self.dfl_p2p_port + self.port_shift))
fn_stem = f'{self.id}-{self.network}-daemon-{self.bind_port}'

View file

@ -1 +1 @@
16.3.0dev9
16.3.0dev10

View file

@ -83,22 +83,18 @@ class MoneroWalletDaemon(RPCDaemon):
rpc_ports = _nw(13131, 13141, None) # testnet is non-standard
use_pidfile = gc.platform == 'linux'
_reset_ok = ('debug', 'wait', 'pids', 'force_kill')
test_user_port_shifts = {
'bob': 10,
'alice': 20,
'miner': 30}
def __init__(
self,
cfg,
proto,
*,
test_user = None,
wallet_dir = None,
user = None,
passwd = None,
monerod_addr = None,
proxy = None,
port_shift = None,
datadir = None,
disable_authentication = False,
trust_monerod = False,
@ -110,14 +106,9 @@ class MoneroWalletDaemon(RPCDaemon):
super().__init__(cfg, **kwargs)
self.network = proto.network
self.rpc_port = getattr(self.rpc_ports, self.network) + (11 if self.test_suite else 0)
self.rpc_port = getattr(self.rpc_ports, self.network) + self.port_shift
self.disable_authentication = disable_authentication
if port_shift:
self.rpc_port += port_shift
elif cfg.test_user:
self.rpc_port += self.test_user_port_shifts[cfg.test_user]
if wallet_dir or cfg.wallet_dir:
self.wallet_dir = Path(wallet_dir or cfg.wallet_dir)
else:

View file

@ -149,7 +149,7 @@ class CmdTestSwapMethods:
'--rpc-host=unreachable', # unreachable host
'--ltc-rpc-host=localhost',
'--rpc-port=46381', # bad port
'--ltc-rpc-port=20680'],
'--ltc-rpc-port=19571'],
spawn_only = spawn_only)
def _swaptxsend(self, *, add_opts=[], spawn_only=False, status=False, dump_hex=False):

View file

@ -46,9 +46,9 @@ class CmdTestXMRAutosign(CmdTestXMRWallet, CmdTestAutosignThreaded):
# xmrwallet attrs:
tx_relay_user = 'miner'
user_data = (
# user sid autosign port_shift kal_range add_coind_args
('miner', '98831F3A', False, 130, '1', []),
('alice', 'FE3C6545', True, 150, '1-2', []))
# user sid autosign kal_range add_coind_args
('miner', '98831F3A', False, '1', []),
('alice', 'FE3C6545', True, '1-2', []))
# autosign attrs:
coins = ['xmr']

View file

@ -21,6 +21,8 @@ test.cmdtest_d.xmrwallet: xmrwallet tests for the cmdtest.py test suite
"""
import os
os.environ['MMGEN_TEST_SUITE_ENABLE_USER_PORT_SHIFT'] = '1'
import time, re, atexit, asyncio, shutil
from subprocess import run
from collections import namedtuple
@ -69,10 +71,10 @@ class CmdTestXMRWallet(CmdTestBase):
dfl_random_txs = 3
color = True
user_data = (
# user sid autosign port_shift kal_range add_coind_args
('miner', '98831F3A', False, 130, '1-2', []),
('bob', '1378FC64', False, 140, None, ['--restricted-rpc']),
('alice', 'FE3C6545', False, 150, '1-4', []))
# user sid autosign kal_range add_coind_args
('miner', '98831F3A', False, '1-2', []),
('bob', '1378FC64', False, None, ['--restricted-rpc']),
('alice', 'FE3C6545', False, '1-4', []))
tx_relay_user = 'bob'
daemon_datadir_base = os.path.join('test', 'daemons', 'xmrtest')
compat = False
@ -148,6 +150,7 @@ class CmdTestXMRWallet(CmdTestBase):
self.start_daemons()
self.balance = None
self.spawn_env['MMGEN_TEST_SUITE_ENABLE_USER_PORT_SHIFT'] = '1'
# init methods
@ -179,7 +182,6 @@ class CmdTestXMRWallet(CmdTestBase):
user,
sid,
autosign,
shift,
kal_range,
add_coind_args) in self.user_data:
@ -189,7 +191,7 @@ class CmdTestXMRWallet(CmdTestBase):
md = CoinDaemon(
cfg = usr_cfg,
proto = usr_cfg._proto,
port_shift = shift,
test_user = user,
opts = ['online'])
md_rpc = MoneroRPCClient(
@ -205,11 +207,11 @@ class CmdTestXMRWallet(CmdTestBase):
wd = MoneroWalletDaemon(
cfg = usr_cfg,
proto = usr_cfg._proto,
test_user = user,
wallet_dir = None if autosign else
(usr_cfg._proto.network_datadir / 'tracking-wallets'),
user = 'foo',
passwd = 'bar',
port_shift = shift,
monerod_addr = f'127.0.0.1:{md.rpc_port}')
wd_rpc = MoneroWalletRPCClient(

View file

@ -243,6 +243,7 @@ class unit_tests:
MoneroWalletDaemon(
cfg = cfg,
proto = proto,
test_user = 'bob',
wallet_dir = trash_dir2,
datadir = os.path.join(trash_dir2, 'wallet_rpc'),
passwd = 'ut_rpc_passw0rd')

View file

@ -42,7 +42,6 @@ opts_data = {
-i, --daemon-ids Print all known daemon IDs
-m, --mainnet-only Perform operations for mainnet daemons only
-n, --no-daemonize Don't fork daemon to background
-p, --port-shift= Shift the RPC port by this number
-r, --remove-datadir Remove the datadir(s) after stopping the daemon(s)
-s, --get-state Get the state of the daemon(s) and exit
-t, --testing Testing mode. Print commands but don't execute them
@ -90,7 +89,6 @@ def run(network_id=None, proto=None, daemon_id=None, missing_exec_ok=False):
proto = proto,
test_suite = not cfg.usermode,
opts = ['no_daemonize'] if cfg.no_daemonize else None,
port_shift = int(cfg.port_shift or 0),
datadir = cfg.datadir,
daemon_id = daemon_id)

View file

@ -47,6 +47,7 @@ for k, v in {
'test_suite_devnet_block_period': 0,
'test_suite_devtools': False,
'test_suite_enable_color': False,
'test_suite_enable_user_port_shift': False,
'test_suite_ignore_test_py_exception': False,
'test_suite_legacy_tx': False,
'test_suite_pexpect': False,
@ -67,6 +68,7 @@ Config._env_opts += (
'MMGEN_TEST_SUITE_DEVNET_BLOCK_PERIOD',
'MMGEN_TEST_SUITE_DEVTOOLS',
'MMGEN_TEST_SUITE_ENABLE_COLOR',
'MMGEN_TEST_SUITE_ENABLE_USER_PORT_SHIFT',
'MMGEN_TEST_SUITE_EXEC_WRAPPER', # main - using os.getenv() - OK
'MMGEN_TEST_SUITE_HOLD_PROTECT_DISABLE',
'MMGEN_TEST_SUITE_IGNORE_TEST_PY_EXCEPTION',

View file

@ -0,0 +1,41 @@
# MMGen Wallet, a terminal-based cryptocurrency wallet
# Copyright (C)2013-2026 The MMGen Project <mmgen@tuta.io>
# Licensed under the GNU General Public License, Version 3:
# https://www.gnu.org/licenses
# Public project repositories:
# https://github.com/mmgen/mmgen-wallet
# https://gitlab.com/mmgen/mmgen-wallet
"""
test.overlay.fakemods.mmgen.daemon: test suite overlay for daemon module
"""
from .daemon_orig import *
from .daemon_orig import _dd, _nw # noqa
class overlay_fake_Daemon:
"""
Port shift bits:
test_suite
| test_user
| | | reserved
| | | . . . . .
7 6 5 4 3 2 1 0
"""
@property
def port_shift(self):
udata = {
'': 0,
'miner': 1,
'bob': 2,
'alice': 3}
if os.getenv('MMGEN_TEST_SUITE_ENABLE_USER_PORT_SHIFT'):
return 1 << 7 | udata[self.test_user or self.cfg.test_user] << 5
else:
return 1 << 7
Daemon.port_shift = overlay_fake_Daemon.port_shift