mmgen-wallet/test/daemontest_d/exec.py

156 lines
4.8 KiB
Python
Executable file

#!/usr/bin/env python3
"""
test.daemontest_d.exec: unit test for the MMGen suite's Daemon class
"""
from subprocess import run, PIPE
from collections import namedtuple
from mmgen.cfg import gc
from mmgen.color import orange, red
from mmgen.util import fmt_list, in_nix_environment
from mmgen.daemon import CoinDaemon
from ..include.common import cfg, qmsg, qmsg_r, vmsg, msg, msg_r
def test_flags(coin):
d = CoinDaemon(cfg, network_id=coin)
vmsg(f'Available opts: {fmt_list(d.avail_opts, fmt="bare")}')
vmsg(f'Available flags: {fmt_list(d.avail_flags, fmt="bare")}')
vals = namedtuple('vals', ['online', 'no_daemonize', 'keep_cfg_file'])
def gen():
for opts, flags, val in (
(None, None, vals(False, False, False)),
(None, ['keep_cfg_file'], vals(False, False, True)),
(['online'], ['keep_cfg_file'], vals(True, False, True)),
(['online', 'no_daemonize'], ['keep_cfg_file'], vals(True, True, True)),
):
d = CoinDaemon(cfg, network_id=coin, opts=opts, flags=flags)
assert d.flag.keep_cfg_file == val.keep_cfg_file
assert d.opt.online == val.online
assert d.opt.no_daemonize == val.no_daemonize
d.flag.keep_cfg_file = not val.keep_cfg_file
d.flag.keep_cfg_file = val.keep_cfg_file
yield d
return tuple(gen())
def test_flags_err(ut, d):
def bad1(): d[0].flag.foo = False
def bad2(): d[0].opt.foo = False
def bad3(): d[0].opt.no_daemonize = True
def bad4(): d[0].flag.keep_cfg_file = 'x'
def bad5(): d[0].opt.no_daemonize = 'x'
def bad6(): d[0].flag.keep_cfg_file = False
def bad7(): d[1].flag.keep_cfg_file = True
ut.process_bad_data((
('flag (1)', 'ClassFlagsError', 'unrecognized flag', bad1),
('opt (1)', 'ClassFlagsError', 'unrecognized opt', bad2),
('opt (2)', 'AttributeError', 'is read-only', bad3),
('flag (2)', 'AssertionError', 'not boolean', bad4),
('opt (3)', 'AttributeError', 'is read-only', bad5),
('flag (3)', 'ClassFlagsError', 'not set', bad6),
('flag (4)', 'ClassFlagsError', 'already set', bad7),
))
class unit_tests:
win_skip = ('start', 'status', 'stop')
altcoin_deps = ('flags_eth',)
def _pre(self):
self.daemon_ctrl_args = ['btc', 'btc_tn', 'btc_rt'] if cfg.no_altcoin_deps else ['all']
def _test_cmd(self, cmd, *, opts=[], network_ids=[], ok=True):
args = (
['python3', f'test/{cmd}-coin-daemons.py']
+ opts
+ (network_ids or self.daemon_ctrl_args))
vmsg('\n' + orange(f"Running '{' '.join(args)}':"))
redir = None if cfg.verbose else PIPE
cp = run(args, stdout=redir, stderr=redir, text=True)
if cp.returncode != 0:
if cp.stdout:
msg(cp.stdout)
if cp.stderr:
msg(red(cp.stderr))
return False
if ok:
vmsg('')
qmsg('OK')
return True
def _test_daemons(self, cmd, *, msg, opts=[]):
qmsg_r(msg + ' coin daemons...')
test_reth = not (cfg.no_altcoin_deps or cfg.fast)
test_parity = not (
cfg.no_altcoin_deps
or gc.machine in ('riscv64', 'aarch64', 'armv7l')
or in_nix_environment())
ret1 = self._test_cmd(
cmd,
opts = opts,
network_ids = ['btc'] if cfg.no_altcoin_deps else ['btc', 'ltc', 'bch', 'xmr', 'eth'],
ok = not (test_reth or test_parity))
ret2 = self._test_cmd(
cmd,
opts = opts + ['--daemon-id=reth'],
network_ids = ['eth'],
ok = not test_parity) if test_reth else True
ret3 = self._test_cmd(
cmd,
opts = opts,
network_ids = ['etc'],
ok = True) if test_parity else True
return ret1 and ret2 and ret3
def flags(self, name, ut):
qmsg_r('Testing flags and opts (BTC)...')
vmsg('')
daemons = test_flags(coin='btc')
qmsg('OK')
qmsg_r('Testing error handling for flags and opts...')
vmsg('')
test_flags_err(ut, daemons)
qmsg('OK')
return True
def flags_eth(self, name, ut):
qmsg_r('Testing flags and opts (ETH)...')
vmsg('')
daemons = test_flags(coin='eth')
qmsg('OK')
qmsg_r('Testing error handling for flags and opts...')
vmsg('')
test_flags_err(ut, daemons)
qmsg('OK')
return True
def avail(self, name, ut):
return self._test_daemons(
'start',
msg = 'Testing availability of',
opts = ['--print-version', '--mainnet-only'])
def versions(self, name, ut):
qmsg_r('Displaying coin daemon versions...')
ret1 = self._test_cmd('start', opts=['--print-version'], ok=False)
ret2 = self._test_cmd('start', opts=['--print-version', '--mainnet-only'])
return ret1 and ret2
def cmds(self, name, ut):
qmsg_r('Testing start commands for coin daemons...')
return self._test_cmd('start', opts=['--testing'])
def start(self, name, ut):
return self._test_daemons('start', msg='Starting')
def status(self, name, ut):
return self._test_daemons('start', msg='Checking status of')
def stop(self, name, ut):
return self._test_daemons('stop', msg='Stopping', opts=['--remove-datadir'])