aboutsummaryrefslogtreecommitdiff
path: root/test/functional/test_framework/test_framework.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/test_framework/test_framework.py')
-rwxr-xr-xtest/functional/test_framework/test_framework.py49
1 files changed, 40 insertions, 9 deletions
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 543643f273..472664a314 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Base class for RPC testing."""
+import configparser
from enum import Enum
import logging
import optparse
@@ -41,7 +42,28 @@ TEST_EXIT_PASSED = 0
TEST_EXIT_FAILED = 1
TEST_EXIT_SKIPPED = 77
-class BitcoinTestFramework():
+
+class BitcoinTestMetaClass(type):
+ """Metaclass for BitcoinTestFramework.
+
+ Ensures that any attempt to register a subclass of `BitcoinTestFramework`
+ adheres to a standard whereby the subclass overrides `set_test_params` and
+ `run_test` but DOES NOT override either `__init__` or `main`. If any of
+ those standards are violated, a ``TypeError`` is raised."""
+
+ def __new__(cls, clsname, bases, dct):
+ if not clsname == 'BitcoinTestFramework':
+ if not ('run_test' in dct and 'set_test_params' in dct):
+ raise TypeError("BitcoinTestFramework subclasses must override "
+ "'run_test' and 'set_test_params'")
+ if '__init__' in dct or 'main' in dct:
+ raise TypeError("BitcoinTestFramework subclasses may not override "
+ "'__init__' or 'main'")
+
+ return super().__new__(cls, clsname, bases, dct)
+
+
+class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""Base class for a bitcoin test script.
Individual bitcoin test scripts should subclass this class and override the set_test_params() and run_test() methods.
@@ -76,10 +98,10 @@ class BitcoinTestFramework():
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
help="Don't stop bitcoinds after the test execution")
- parser.add_option("--srcdir", dest="srcdir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + "/../../../src"),
+ parser.add_option("--srcdir", dest="srcdir", default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../../src"),
help="Source directory containing bitcoind/bitcoin-cli (default: %default)")
- parser.add_option("--cachedir", dest="cachedir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + "/../../cache"),
- help="Directory for caching pregenerated datadirs")
+ parser.add_option("--cachedir", dest="cachedir", default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../cache"),
+ help="Directory for caching pregenerated datadirs (default: %default)")
parser.add_option("--tmpdir", dest="tmpdir", help="Root directory for datadirs")
parser.add_option("-l", "--loglevel", dest="loglevel", default="INFO",
help="log events at this level and higher to the console. Can be set to DEBUG, INFO, WARNING, ERROR or CRITICAL. Passing --loglevel DEBUG will output all logs to console. Note that logs at all levels are always written to the test_framework.log file in the temporary test directory.")
@@ -90,7 +112,8 @@ class BitcoinTestFramework():
parser.add_option("--coveragedir", dest="coveragedir",
help="Write tested RPC commands into this directory")
parser.add_option("--configfile", dest="configfile",
- help="Location of the test framework config file")
+ default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../config.ini"),
+ help="Location of the test framework config file (default: %default)")
parser.add_option("--pdbonfailure", dest="pdbonfailure", default=False, action="store_true",
help="Attach a python debugger if test fails")
parser.add_option("--usecli", dest="usecli", default=False, action="store_true",
@@ -108,6 +131,11 @@ class BitcoinTestFramework():
self.options.cachedir = os.path.abspath(self.options.cachedir)
+ config = configparser.ConfigParser()
+ config.read_file(open(self.options.configfile))
+ self.options.bitcoind = os.getenv("BITCOIND", default=config["environment"]["BUILDDIR"] + '/src/bitcoind' + config["environment"]["EXEEXT"])
+ self.options.bitcoincli = os.getenv("BITCOINCLI", default=config["environment"]["BUILDDIR"] + '/src/bitcoin-cli' + config["environment"]["EXEEXT"])
+
# Set up temp directory and start logging
if self.options.tmpdir:
self.options.tmpdir = os.path.abspath(self.options.tmpdir)
@@ -148,6 +176,8 @@ class BitcoinTestFramework():
if self.nodes:
self.stop_nodes()
else:
+ for node in self.nodes:
+ node.cleanup_on_exit = False
self.log.info("Note: bitcoinds were not stopped and may still be running")
if not self.options.nocleanup and not self.options.noshutdown and success != TestStatus.FAILED:
@@ -223,12 +253,12 @@ class BitcoinTestFramework():
if extra_args is None:
extra_args = [[]] * num_nodes
if binary is None:
- binary = [None] * num_nodes
+ binary = [self.options.bitcoind] * num_nodes
assert_equal(len(extra_confs), num_nodes)
assert_equal(len(extra_args), num_nodes)
assert_equal(len(binary), num_nodes)
for i in range(num_nodes):
- self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), rpchost=rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli))
+ self.nodes.append(TestNode(i, get_datadir_path(self.options.tmpdir, i), rpchost=rpchost, timewait=timewait, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], use_cli=self.options.usecli))
def start_node(self, i, *args, **kwargs):
"""Start a bitcoind"""
@@ -376,10 +406,10 @@ class BitcoinTestFramework():
# Create cache directories, run bitcoinds:
for i in range(MAX_NODES):
datadir = initialize_datadir(self.options.cachedir, i)
- args = [os.getenv("BITCOIND", "bitcoind"), "-datadir=" + datadir]
+ args = [self.options.bitcoind, "-datadir=" + datadir]
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
- self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[],rpchost=None, timewait=None, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None))
+ self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), extra_conf=["bind=127.0.0.1"], extra_args=[], rpchost=None, timewait=None, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, stderr=None, mocktime=self.mocktime, coverage_dir=None))
self.nodes[i].args = args
self.start_node(i)
@@ -432,6 +462,7 @@ class BitcoinTestFramework():
for i in range(self.num_nodes):
initialize_datadir(self.options.tmpdir, i)
+
class SkipTest(Exception):
"""This exception is raised to skip a test"""
def __init__(self, message):