Procházet zdrojové kódy

support testing via MMGen test suite framework

The MMGen Project před 1 rokem
rodič
revize
a01c9856b1

+ 10 - 1
README.md

@@ -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] |

+ 2 - 1
setup.cfg

@@ -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 - 0
test/init.sh

@@ -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 - 0
test/test-release.d/cfg.sh

@@ -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'
+}

+ 0 - 79
test/test-release.sh

@@ -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 - 0
test/test_py_d/cfg.py

@@ -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 - 0
test/test_py_d/ts_misc.py

@@ -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 - 0
test/test_py_d/ts_regtest.py

@@ -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'])