unit_tests.py -> modtest.py, daemontest.py

This commit is contained in:
The MMGen Project 2024-10-18 10:32:15 +00:00
commit 5f3920b11a
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
37 changed files with 118 additions and 90 deletions

View file

@ -58,4 +58,4 @@ jobs:
pylint --errors-only --jobs=0 mmgen
pylint --errors-only --jobs=0 test
pylint --errors-only --jobs=0 examples
pylint --errors-only --jobs=0 --disable=relative-beyond-top-level test/cmdtest_py_d
pylint --errors-only --jobs=0 --disable=relative-beyond-top-level test/cmdtest_d

View file

@ -400,7 +400,7 @@ class Config(Lockable):
short_disp_timeout = 0.1
if os.getenv('MMGEN_TEST_SUITE_POPEN_SPAWN'):
stdin_tty = True
if gc.prog_name == 'unit_tests.py':
if gc.prog_name == 'modtest.py':
_set_ok += ('debug_subseed',)
_reset_ok += ('force_standalone_scrypt_module',)

View file

@ -1 +1 @@
15.1.dev5
15.1.dev6

10
test/daemontest.py Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env python3
"""
test/daemontest.py: Daemon-related unit tests for the MMGen suite
"""
try:
from include import unit_test
except ImportError:
from test.include import unit_test

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_daemon: unit test for the MMGen suite's Daemon class
test.daemontest_d.ut_exec: unit test for the MMGen suite's Daemon class
"""
from subprocess import run, PIPE
@ -91,7 +91,7 @@ class unit_tests:
return True
def exec(self, name, ut):
def avail(self, name, ut):
return self._test_cmd(['start', '-Vm'], 'Testing availability of coin daemons...')
def cmds(self, name, ut):

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_msg: message signing unit tests for the MMGen suite
test.daemontest_d.ut_msg: message signing unit tests for the MMGen suite
"""
import os

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_rpc: RPC unit test for the MMGen suite
test.daemontest_d.ut_rpc: RPC unit test for the MMGen suite
"""
import sys, os

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_tx_deserialize: TX deserialization unit tests for the MMGen suite
test.daemontest_d.ut_tx: TX daemon tests for the MMGen suite
"""
import os, json
@ -13,8 +13,10 @@ from mmgen.protocol import init_proto
from mmgen.tx import CompletedTX
from mmgen.proto.btc.tx.base import DeserializeTX
from mmgen.rpc import rpc_init
from mmgen.daemon import CoinDaemon
from mmgen.tx import NewTX
from ..include.common import cfg, start_test_daemons, stop_test_daemons
from ..include.common import cfg, start_test_daemons, stop_test_daemons, qmsg
def print_info(name, extra_desc):
if cfg.names:
@ -106,6 +108,19 @@ class unit_tests:
altcoin_deps = ('mmgen_ref_alt',)
async def newtx(self, name, ut):
qmsg(' Testing NewTX initializer')
d = CoinDaemon(cfg, 'btc', test_suite=True)
d.start()
proto = init_proto(cfg, 'btc', need_amt=True)
await NewTX(cfg=cfg, proto=proto)
d.stop()
d.remove_datadir()
qmsg(' OK')
return True
async def core_vectors(self, name, ut):
core_repo_root = os.getenv('CORE_REPO_ROOT')

View file

@ -17,15 +17,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
test/unit_tests.py: Unit tests for the MMGen suite
test.include.unit_test: Unit test framework for the MMGen suite
"""
import sys, os, time, importlib, platform, asyncio
try:
from include.test_init import repo_root
except ImportError:
from test.include.test_init import repo_root
from .test_init import repo_root
# for the unit tests, violate MMGen Project best practices and allow use of the dev tools
# in production code:
@ -82,9 +79,16 @@ set_globals(cfg)
file_pfx = 'ut_'
tests_d = os.path.join(repo_root, 'test', 'unit_tests_d')
test_type = {
'modtest.py': 'unit',
'daemontest.py': 'daemon',
}[gc.prog_name]
all_tests = sorted(fn[len(file_pfx):-len('.py')] for fn in os.listdir(tests_d) if fn.startswith(file_pfx))
test_subdir = gc.prog_name.removesuffix('.py') + '_d'
test_dir = os.path.join(repo_root, 'test', test_subdir)
all_tests = sorted(fn[len(file_pfx):-len('.py')] for fn in os.listdir(test_dir) if fn.startswith(file_pfx))
exclude = cfg.exclude.split(',') if cfg.exclude else []
@ -101,7 +105,7 @@ if cfg.list:
if cfg.list_subtests:
def gen():
for test in all_tests:
mod = importlib.import_module(f'test.unit_tests_d.{file_pfx}{test}')
mod = importlib.import_module(f'test.{test_subdir}.{file_pfx}{test}')
if hasattr(mod, 'unit_tests'):
t = getattr(mod, 'unit_tests')
subtests = [k for k, v in t.__dict__.items() if type(v).__name__ == 'function' and k[0] != '_']
@ -148,11 +152,11 @@ class UnitTestHelpers:
tests_seen = []
def run_test(test, subtest=None):
mod = importlib.import_module(f'test.unit_tests_d.{file_pfx}{test}')
mod = importlib.import_module(f'test.{test_subdir}.{file_pfx}{test}')
def run_subtest(t, subtest):
subtest_disp = subtest.replace('_', '-')
msg(brown('Running unit subtest ') + orange(f'{test}.{subtest_disp}'))
msg(brown(f'Running {test_type} subtest ') + orange(f'{test}.{subtest_disp}'))
if getattr(t, 'silence_output', False):
t._silence()
@ -190,11 +194,11 @@ def run_test(test, subtest=None):
die(4, f'Unit subtest {subtest_disp!r} failed')
if test not in tests_seen:
gmsg(f'Running unit test {test}')
gmsg(f'Running {test_type} test {test}')
tests_seen.append(test)
if cfg.no_altcoin_deps and getattr(mod, 'altcoin_dep', None):
cfg._util.qmsg(gray(f'Skipping unit test {test!r} [--no-altcoin-deps]'))
cfg._util.qmsg(gray(f'Skipping {test_type} test {test!r} [--no-altcoin-deps]'))
return
if hasattr(mod, 'unit_tests'): # new class-based API
@ -212,22 +216,22 @@ def run_test(test, subtest=None):
for _subtest in subtests:
subtest_disp = _subtest.replace('_', '-')
if cfg.no_altcoin_deps and _subtest in altcoin_deps:
cfg._util.qmsg(gray(f'Skipping unit subtest {subtest_disp!r} [--no-altcoin-deps]'))
cfg._util.qmsg(gray(f'Skipping {test_type} subtest {subtest_disp!r} [--no-altcoin-deps]'))
continue
if sys.platform == 'win32' and _subtest in win_skip:
cfg._util.qmsg(gray(f'Skipping unit subtest {subtest_disp!r} for Windows platform'))
cfg._util.qmsg(gray(f'Skipping {test_type} subtest {subtest_disp!r} for Windows platform'))
continue
if sys.platform == 'darwin' and _subtest in mac_skip:
cfg._util.qmsg(gray(f'Skipping unit subtest {subtest_disp!r} for macOS platform'))
cfg._util.qmsg(gray(f'Skipping {test_type} subtest {subtest_disp!r} for macOS platform'))
continue
if platform.machine() == 'aarch64' and _subtest in arm_skip:
cfg._util.qmsg(gray(f'Skipping unit subtest {subtest_disp!r} for ARM platform'))
cfg._util.qmsg(gray(f'Skipping {test_type} subtest {subtest_disp!r} for ARM platform'))
continue
run_subtest(t, _subtest)
if hasattr(t, '_post'):
t._post()
else:
assert not subtest, f'{subtest!r}: subtests not supported for this unit test'
assert not subtest, f'{subtest!r}: subtests not supported for this {test_type} test'
if not mod.unit_test().run_test(test, UnitTestHelpers(test)):
die(4, 'Unit test {test!r} failed')

10
test/modtest.py Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env python3
"""
test/modtest.py: Unit tests for the MMGen suite
"""
try:
from include import unit_test
except ImportError:
from test.include import unit_test

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.__init__: shared data for unit tests for the MMGen suite
test.modtest_d.__init__: shared data for unit tests for the MMGen suite
"""
import sys, os

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_addrlist: address list unit tests for the MMGen suite
test.modtest_d.ut_addrlist: address list unit tests for the MMGen suite
"""
from mmgen.color import blue

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_addrparse: address parsing tests for the MMGen suite
test.modtest_d.ut_addrparse: address parsing tests for the MMGen suite
"""
from mmgen.color import yellow, cyan

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_baseconv: Base conversion unit test for the MMGen suite
test.modtest_d.ut_baseconv: Base conversion unit test for the MMGen suite
"""
from mmgen.util import msg, msg_r

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_bip39: BIP39 unit test for the MMGen suite
test.modtest_d.ut_bip39: BIP39 unit test for the MMGen suite
"""
from mmgen.color import blue, orange, purple

View file

@ -1,15 +1,7 @@
#!/usr/bin/env python3
#
# MMGen Wallet, a terminal-based cryptocurrency wallet
# Copyright (C)2013-2024 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.unit_tests_d.ut_bip_hd: bip_hd unit test for the MMGen suite
test.modtest_d.ut_bip_hd: bip_hd unit test for the MMGen suite
"""
from mmgen.color import gray, pink, blue

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_cashaddr: unit test for the BCH cashaddr module
test.modtest_d.ut_cashaddr: unit test for the BCH cashaddr module
"""
altcoin_dep = True

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_dep: dependency unit tests for the MMGen suite
test.modtest_d.ut_dep: dependency unit tests for the MMGen suite
Test whether dependencies are installed and functional.
No data verification is performed.

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_devtools: devtools unit tests for the MMGen suite
test.modtest_d.ut_devtools: devtools unit tests for the MMGen suite
"""
import os, json

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_ecc: elliptic curve unit test for the MMGen suite
test.modtest_d.ut_ecc: elliptic curve unit test for the MMGen suite
"""
from mmgen.proto.secp256k1.secp256k1 import pubkey_gen, pubkey_tweak_add, pubkey_check

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_flags: unit test for the MMGen suite's ClassFlags class
test.modtest_d.ut_flags: unit test for the MMGen suite's ClassFlags class
"""
from mmgen.flags import ClassOpts, ClassFlags

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_gen: key/address generation unit tests for the MMGen suite
test.modtest_d.ut_gen: key/address generation unit tests for the MMGen suite
"""
from mmgen.color import blue

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_indexed_dict: IndexedDict class unit test for the MMGen suite
test.modtest_d.ut_indexed_dict: IndexedDict class unit test for the MMGen suite
"""
from mmgen.util import msg, msg_r, die

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_lockable: unit test for the MMGen suite's Lockable class
test.modtest_d.ut_lockable: unit test for the MMGen suite's Lockable class
"""
from decimal import Decimal

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_misc: miscellaneous unit tests for the MMGen suite
test.modtest_d.ut_misc: miscellaneous unit tests for the MMGen suite
"""
import re, time

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_mn_entry: Mnemonic user entry unit test for the MMGen suite
test.modtest_d.ut_mn_entry: Mnemonic user entry unit test for the MMGen suite
"""
from mmgen.mn_entry import mn_entry

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_obj: data object unit tests for the MMGen suite
test.modtest_d.ut_obj: data object unit tests for the MMGen suite
"""
from decimal import Decimal, getcontext

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_scrypt: password hashing unit test for the MMGen suite
test.modtest_d.ut_scrypt: password hashing unit test for the MMGen suite
"""
from mmgen.util import msg, msg_r

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_seedsplit: seed splitting unit test for the MMGen suite
test.modtest_d.ut_seedsplit: seed splitting unit test for the MMGen suite
"""
from mmgen.util import msg, msg_r

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_subseed: subseed unit test for the MMGen suite
test.modtest_d.ut_subseed: subseed unit test for the MMGen suite
"""
from mmgen.util import msg, msg_r

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_testdep: test dependency unit tests for the MMGen suite
test.modtest_d.ut_testdep: test dependency unit tests for the MMGen suite
"""
import sys, os

View file

@ -1,15 +1,14 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_tx: TX unit tests for the MMGen suite
test.modtest_d.ut_tx: TX unit tests for the MMGen suite
"""
import os, re
from mmgen.devtools import get_diff, get_ndiff
from mmgen.tx import NewTX, CompletedTX, UnsignedTX
from mmgen.tx import CompletedTX, UnsignedTX
from mmgen.tx.file import MMGenTxFile
from mmgen.daemon import CoinDaemon
from mmgen.protocol import init_proto
from mmgen.cfg import Config
@ -45,19 +44,6 @@ class unit_tests:
altcoin_deps = ('txfile_alt', 'txfile_alt_legacy')
async def tx(self, name, ut):
qmsg(' Testing NewTX initializer')
d = CoinDaemon(cfg, 'btc', test_suite=True)
d.start()
proto = init_proto(cfg, 'btc', need_amt=True)
await NewTX(cfg=cfg, proto=proto)
d.stop()
d.remove_datadir()
qmsg(' OK')
return True
async def txfile(self, name, ut):
return await do_txfile_test(
'Bitcoin',

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test.unit_tests_d.ut_misc: utility unit tests for the MMGen suite
test.modtest_d.ut_misc: utility unit tests for the MMGen suite
"""
from mmgen.color import cyan

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
test/unit_tests_d/ut_xmrseed: Monero mnemonic unit test for the MMGen suite
test.modtest_d.ut_xmrseed: Monero mnemonic unit test for the MMGen suite
"""
altcoin_dep = True

View file

@ -8,7 +8,7 @@
# https://github.com/mmgen/mmgen-wallet
# https://gitlab.com/mmgen/mmgen-wallet
all_tests="dep dev lint obj color unit hash ref altref altgen xmr eth autosign btc btc_tn btc_rt bch bch_tn bch_rt ltc ltc_tn ltc_rt tool tool2 gen alt help"
all_tests="dep dev lint obj color daemon mod hash ref altref altgen xmr eth autosign btc btc_tn btc_rt bch bch_tn bch_rt ltc ltc_tn ltc_rt tool tool2 gen alt help"
groups_desc="
default - All tests minus the extra tests
@ -19,10 +19,10 @@ groups_desc="
"
init_groups() {
dfl_tests='dep alt obj color unit hash ref tool tool2 gen help autosign btc btc_tn btc_rt altref altgen bch bch_rt ltc ltc_rt eth etc xmr'
dfl_tests='dep alt obj color daemon mod hash ref tool tool2 gen help autosign btc btc_tn btc_rt altref altgen bch bch_rt ltc ltc_rt eth etc xmr'
extra_tests='dep dev lint autosign_live ltc_tn bch_tn'
noalt_tests='dep alt obj color unit hash ref tool tool2 gen help autosign btc btc_tn btc_rt'
quick_tests='dep alt obj color unit hash ref tool tool2 gen help autosign btc btc_rt altref altgen eth etc xmr'
noalt_tests='dep alt obj color daemon mod hash ref tool tool2 gen help autosign btc btc_tn btc_rt'
quick_tests='dep alt obj color daemon mod hash ref tool tool2 gen help autosign btc btc_rt altref altgen eth etc xmr'
qskip_tests='lint btc_tn bch bch_rt ltc ltc_rt'
noalt_ok_tests='lint'
@ -61,7 +61,10 @@ init_tests() {
t_color='- test/colortest.py'
d_dep="system and testing dependencies"
t_dep="- $unit_tests_py testdep dep daemon.exec"
t_dep="
- $modtest_py testdep dep
- $daemontest_py exec
"
d_dev="developer scripts ${YELLOW}(additional dependencies required)$RESET"
t_dev="
@ -82,8 +85,11 @@ init_tests() {
if [ "$SKIP_ALT_DEP" ]; then t_lint_skip='b'; else t_lint_skip='a'; fi
d_unit="low-level subsystems"
t_unit="- $unit_tests_py --exclude testdep,dep,daemon"
d_daemon="low-level subsystems involving coin daemons"
t_daemon="- $daemontest_py --exclude exec"
d_mod="low-level subsystems"
t_mod="- $modtest_py --exclude testdep,dep"
d_hash="internal hash function implementations"
t_hash="

View file

@ -258,7 +258,8 @@ fi
cmdtest_py='test/cmdtest.py -n'
objtest_py='test/objtest.py'
objattrtest_py='test/objattrtest.py'
unit_tests_py='test/unit_tests.py --names --quiet'
modtest_py='test/modtest.py --names --quiet'
daemontest_py='test/daemontest.py --names --quiet'
tooltest_py='test/tooltest.py'
tooltest2_py='test/tooltest2.py --names --quiet'
gentest_py='test/gentest.py --quiet'
@ -312,7 +313,8 @@ do
exit ;;
A) SKIP_ALT_DEP=1
cmdtest_py+=" --no-altcoin"
unit_tests_py+=" --no-altcoin-deps"
modtest_py+=" --no-altcoin-deps"
daemontest_py+=" --no-altcoin-deps"
scrambletest_py+=" --no-altcoin"
tooltest2_py+=" --no-altcoin" ;;
b) cmdtest_py+=" --buf-keypress" ;;
@ -323,7 +325,8 @@ do
tooltest2_py+=" --fork --coverage"
scrambletest_py+=" --coverage"
python="python3 -m trace --count --file=test/trace.acc --coverdir=test/trace"
unit_tests_py="$python $unit_tests_py"
modtest_py="$python $modtest_py"
daemontest_py="$python $daemontest_py"
objtest_py="$python $objtest_py"
objattrtest_py="$python $objattrtest_py"
gentest_py="$python $gentest_py"
@ -334,8 +337,8 @@ do
D) export MMGEN_TEST_SUITE_DETERMINISTIC=1
export MMGEN_DISABLE_COLOR=1 ;;
e) exec_prog=$(realpath $OPTARG) ;;
f) rounds=6 FAST=1 fast_opt='--fast' unit_tests_py+=" --fast" ;;
F) rounds=3 FAST=1 fast_opt='--fast' unit_tests_py+=" --fast" ;;
f) rounds=6 FAST=1 fast_opt='--fast' modtest_py+=" --fast" daemontest_py+=" --fast" ;;
F) rounds=3 FAST=1 fast_opt='--fast' modtest_py+=" --fast" daemontest_py+=" --fast" ;;
I) INSTALL_PACKAGE=1 ;;
L) list_avail_tests; exit ;;
l) list_group_symbols; exit ;;
@ -350,7 +353,8 @@ do
V) VERBOSE='--verbose' VERBOSE_SHORTOPT='-v' QUIET=''
[ "$EXACT_OUTPUT" ] || cmdtest_py+=" --verbose"
STDOUT_DEVNULL='' STDERR_DEVNULL=''
unit_tests_py="${unit_tests_py/--quiet/--verbose}"
modtest_py="${modtest_py/--quiet/--verbose}"
daemontest_py="${daemontest_py/--quiet/--verbose}"
altcoin_mod_opts="${altcoin_mod_opts/--quiet/--verbose}"
tooltest2_py="${tooltest2_py/--quiet/--verbose}"
gentest_py="${gentest_py/--quiet/--verbose}"
@ -387,7 +391,8 @@ case $1 in
'noalt') tests=$noalt_tests
SKIP_ALT_DEP=1
cmdtest_py+=" --no-altcoin"
unit_tests_py+=" --no-altcoin-deps"
modtest_py+=" --no-altcoin-deps"
daemontest_py+=" --no-altcoin-deps"
scrambletest_py+=" --no-altcoin" ;;
'quick') tests=$quick_tests ;;
'qskip') tests=$qskip_tests ;;

View file

@ -23,9 +23,9 @@ from mmgen.bip39 import is_bip39_mnemonic
from mmgen.baseconv import is_mmgen_mnemonic, is_b58_str
from mmgen.xmrseed import is_xmrseed
from ..unit_tests_d.ut_baseconv import unit_test as ut_baseconv
from ..unit_tests_d.ut_bip39 import unit_tests as ut_bip39
from ..unit_tests_d.ut_xmrseed import unit_tests as ut_xmrseed
from ..modtest_d.ut_baseconv import unit_test as ut_baseconv
from ..modtest_d.ut_bip39 import unit_tests as ut_bip39
from ..modtest_d.ut_xmrseed import unit_tests as ut_xmrseed
from ..include.common import cfg, sample_text
proto = cfg._proto