156 lines
4.8 KiB
Python
Executable file
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'])
|