support testing via MMGen test suite framework

This commit is contained in:
The MMGen Project 2022-07-27 16:16:41 +00:00
commit a01c9856b1
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
8 changed files with 308 additions and 81 deletions

View file

@ -1,4 +1,4 @@
# MMGen node tools
# MMGen Node Tools
Helper utilities for Bitcoin and forkcoin full nodes.
@ -19,6 +19,15 @@ Then,
Also make sure that `~/.local/bin` is in `PATH`.
## Test:
*NOTE: the tests require that the MMGen and MMGen Node Tools repositories be
located in the same directory.*
$ test/init.sh
$ test/test-release.sh -A # BTC-only testing
$ test/test-release.sh # Full testing
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[**Forum**][4] |

View file

@ -23,10 +23,11 @@ python_requires = >=3.7
include_package_data = True
install_requires =
mmgen>=13.1.dev19
mmgen>=13.2.dev10
packages =
mmgen_node_tools
mmgen_node_tools.data
scripts =
cmds/mmnode-blocks-info

92
test/init.sh Executable file
View file

@ -0,0 +1,92 @@
#!/bin/bash
#
# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
# Copyright (C)2013-2022 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-node-tools
# https://gitlab.com/mmgen/mmgen-node-tools
RED="\e[31;1m" GREEN="\e[32;1m" YELLOW="\e[33;1m" BLUE="\e[34;1m" RESET="\e[0m"
set -o errtrace
set -o functrace
trap 'echo -e "${GREEN}Exiting at user request$RESET"; exit' INT
trap 'echo -e "${RED}Node Tools test suite initialization exited with error (line $BASH_LINENO) $RESET"' ERR
umask 0022
PROGNAME=$(basename $0)
while getopts h OPT
do
case "$OPT" in
h) printf " %-16s Initialize the MMGen Node Tools test suite\n" "${PROGNAME}:"
echo " USAGE: $PROGNAME"
echo " OPTIONS: '-h' Print this help message"
exit ;;
*) exit ;;
esac
done
shift $((OPTIND-1))
mm_repo='../mmgen'
die() { echo -e ${YELLOW}ERROR: $1$RESET; false; }
becho() { echo -e $BLUE$1$RESET; }
check_mmgen_repo() {
( cd $mm_repo; python3 ./setup.py --url | grep -iq 'mmgen' )
}
build_mmgen_extmod() {
( cd $mm_repo; python3 ./setup.py build_ext --inplace )
}
create_dir_links() {
for target in 'mmgen' 'scripts'; do
src="$mm_repo/$target"
if [ -e $target ]; then
[ $(realpath --relative-to=. $target) == $src ] || die "'$target' does not point to '$src'"
else
echo "Creating symlink: $target"
ln -s $src
fi
done
}
create_test_links() {
sources='
test/include
test/overlay
test/__init__.py
test/test.py
test/unit_tests.py
test/test-release.sh
test/test_py_d/common.py
test/test_py_d/ts_base.py
cmds/mmgen-regtest
'
for src in $sources; do
pfx=$(echo $src | sed -r 's/[^/]//g' | sed 's/\//..\//g')
if [ ! -e $src ]; then
echo "Creating symlink: $src"
( cd "$(dirname $src)" && ln -s "$pfx$mm_repo/$src" )
fi
done
}
set -e
becho 'Initializing MMGen Node Tools Test Suite'
check_mmgen_repo || die "MMGen repository not found at $mm_repo!"
build_mmgen_extmod
create_dir_links
create_test_links
becho 'OK'

62
test/test-release.d/cfg.sh Executable file
View file

@ -0,0 +1,62 @@
#!/bin/bash
#
# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
# Copyright (C)2013-2022 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-node-tools
# https://gitlab.com/mmgen/mmgen-node-tools
list_avail_tests() {
echo "AVAILABLE TESTS:"
echo " unit - unit tests"
echo " btc_rt - Bitcoin regtest"
echo " bch_rt - Bitcoin Cash Node (BCH) regtest"
echo " ltc_rt - Litecoin regtest"
echo " misc - miscellaneous tests that don't fit in the above categories"
echo
echo "AVAILABLE TEST GROUPS:"
echo " default - All tests minus the extra tests"
echo " extra - All tests minus the default tests"
echo " noalt - BTC-only tests"
echo " quick - Default tests minus btc_tn, bch, bch_rt, ltc and ltc_rt"
echo " qskip - The tests skipped in the 'quick' test group"
echo
echo "By default, all tests are run"
}
init_groups() {
dfl_tests='unit misc btc_rt bch_rt ltc_rt'
extra_tests=''
noalt_tests='unit misc btc_rt'
quick_tests='unit misc btc_rt'
qskip_tests='bch_rt ltc_rt'
}
init_tests() {
i_unit='Unit'
s_unit="The following tests will test various low-level subsystems"
t_unit="- $unit_tests_py --node-tools"
f_unit='Unit tests completed'
i_misc='Misc'
s_misc="The following tests will test miscellaneous script features"
t_misc="- $test_py helpscreens"
f_misc='Misc tests completed'
i_btc_rt='Bitcoin regtest'
s_btc_rt="The following tests will test MMGen's regtest (Bob and Alice) mode"
t_btc_rt="- $test_py regtest"
f_btc_rt='Regtest (Bob and Alice) mode tests for BTC completed'
i_bch_rt='BitcoinCashNode (BCH) regtest'
s_bch_rt="The following tests will test MMGen's regtest (Bob and Alice) mode"
t_bch_rt="- $test_py --coin=bch regtest"
f_bch_rt='Regtest (Bob and Alice) mode tests for BCH completed'
i_ltc_rt='Litecoin regtest'
s_ltc_rt="The following tests will test MMGen's regtest (Bob and Alice) mode"
t_ltc_rt="- $test_py --coin=ltc regtest"
f_ltc_rt='Regtest (Bob and Alice) mode tests for LTC completed'
}

View file

@ -1,79 +0,0 @@
#!/bin/bash
export MMGEN_TEST_SUITE=1
export PYTHONPATH=.
orig_pwd=$(pwd)
RED="\e[31;1m" GREEN="\e[32;1m" YELLOW="\e[33;1m" BLUE="\e[34;1m" MAGENTA="\e[35;1m" CYAN="\e[36;1m"
RESET="\e[0m"
set -o errtrace
set -o functrace
trap 'echo -e "${GREEN}Exiting at user request$RESET"; exit' INT
trap 'echo -e "${RED}Node tools test suite exited with error$RESET"' ERR
umask 0022
unit_tests_py='test/unit_tests.py --names --quiet'
PROGNAME=$(basename $0)
while getopts hv OPT
do
case "$OPT" in
h) printf " %-16s The MMGen node tools test suite\n" "${PROGNAME}:"
echo " USAGE: $PROGNAME [options] [tests or test group]"
echo " OPTIONS: '-h' Print this help message"
echo " '-v' Run commands with '--verbose' switch"
exit ;;
v) VERBOSE=1
unit_tests_py="${unit_tests_py/--quiet/--verbose}" ;;
*) exit ;;
esac
done
shift $((OPTIND-1))
nt_repo='../mmgen-node-tools'
mm_repo='../mmgen'
die() { echo -e $YELLOW$1$RESET; false; }
gecho() { echo -e $GREEN$1$RESET; }
pecho() { echo -e $MAGENTA$1$RESET; }
becho() { echo -e $BLUE$1$RESET; }
check_mmgen_repo() {
( cd $mm_repo; python3 ./setup.py --url | grep -iq 'mmgen' )
}
create_links() {
( cd $mm_repo && [ -L 'mmgen_node_tools' ] || ln -s "$orig_pwd/mmgen_node_tools" )
(
cd 'test/unit_tests_d'
for fn in ../../$nt_repo/test/unit_tests_d/nt_*.py; do
[ -L "$(basename $fn)" ] || ln -s "$fn"
done
)
}
run_unit_tests() {
pecho 'Running unit tests:'
$unit_tests_py --node-tools
pecho 'Completed unit tests'
}
# start execution
set -e
becho 'Starting node tools test suite (WIP)'
check_mmgen_repo || die "No MMGen repository found at $mm_repo!"
cd $mm_repo
create_links
run_unit_tests
becho 'Node tools test suite completed successfully'

28
test/test_py_d/cfg.py Executable file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env python3
#
# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
# Copyright (C)2013-2022 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-node-tools
# https://gitlab.com/mmgen/mmgen-node-tools
"""
test.test_py_d.cfg: configuration data for test.py
"""
import os
cmd_groups_dfl = {
'helpscreens': ('TestSuiteHelp',{'modname':'misc','full_data':True}),
'regtest': ('TestSuiteRegtest',{}),
}
cmd_groups_extra = {}
cfgs = {
'1': {}, # regtest
}
def fixup_cfgs(): pass

50
test/test_py_d/ts_misc.py Executable file
View file

@ -0,0 +1,50 @@
#!/usr/bin/env python3
#
# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
# Copyright (C)2013-2022 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-node-tools
# https://gitlab.com/mmgen/mmgen-node-tools
"""
ts_misc.py: Miscellaneous test groups for the test.py test suite
"""
from mmgen.globalvars import g
from ..include.common import *
from .common import *
from .ts_base import *
class TestSuiteHelp(TestSuiteBase):
'help, info and usage screens'
networks = ('btc','ltc','bch')
tmpdir_nums = []
passthru_opts = ('daemon_data_dir','rpc_port','coin','testnet')
cmd_group = (
('version', (1,'version message',[])),
('helpscreens', (1,'help screens', [])),
('longhelpscreens', (1,'help screens (--longhelp)',[])),
)
def version(self):
t = self.spawn(f'mmnode-netrate',['--version'])
t.expect('MMNODE-NETRATE version')
return t
def helpscreens(self,arg='--help',scripts=(),expect='USAGE:.*OPTIONS:'):
scripts = list(scripts) or [s for s in os.listdir('cmds') if s.startswith('mmnode-')]
for s in sorted(scripts):
t = self.spawn(s,[arg],extra_desc=f'({s})')
t.expect(expect,regex=True)
t.read()
t.ok()
t.skip_ok = True
return t
def longhelpscreens(self):
return self.helpscreens(arg='--longhelp',expect='USAGE:.*LONG OPTIONS:')

64
test/test_py_d/ts_regtest.py Executable file
View file

@ -0,0 +1,64 @@
#!/usr/bin/env python3
#
# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
# Copyright (C)2013-2022 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-node-tools
# https://gitlab.com/mmgen/mmgen-node-tools
"""
ts_regtest.py: Regtest tests for the test.py test suite
"""
import os
from mmgen.opts import opt
from mmgen.util import die,gmsg
from ..include.common import *
from .common import *
from .ts_base import *
class TestSuiteRegtest(TestSuiteBase):
'various operations via regtest mode'
networks = ('btc','ltc','bch')
passthru_opts = ('coin',)
extra_spawn_args = ['--regtest=1']
tmpdir_nums = [1]
color = True
deterministic = False
cmd_group = (
('setup', 'regtest (Bob and Alice) mode setup'),
('stop', 'stopping regtest daemon'),
)
def __init__(self,trunner,cfgs,spawn):
TestSuiteBase.__init__(self,trunner,cfgs,spawn)
if trunner == None:
return
if self.proto.testnet:
die(2,'--testnet and --regtest options incompatible with regtest test suite')
os.environ['MMGEN_TEST_SUITE_REGTEST'] = '1'
def __del__(self):
os.environ['MMGEN_TEST_SUITE_REGTEST'] = ''
def setup(self):
stop_test_daemons(self.proto.network_id,force=True,remove_datadir=True)
from shutil import rmtree
try: rmtree(joinpath(self.tr.data_dir,'regtest'))
except: pass
t = self.spawn('mmgen-regtest',['-n','setup'])
for s in ('Starting','Creating','Creating','Creating','Mined','Setup complete'):
t.expect(s)
return t
def stop(self):
if opt.no_daemon_stop:
self.spawn('',msg_only=True)
msg_r('(leaving daemon running by user request)')
return 'ok'
else:
return self.spawn('mmgen-regtest',['stop'])