diff options
Diffstat (limited to 'qa/rpc-tests/test_framework/test_framework.py')
-rwxr-xr-x | qa/rpc-tests/test_framework/test_framework.py | 244 |
1 files changed, 0 insertions, 244 deletions
diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py deleted file mode 100755 index d7072fa78d..0000000000 --- a/qa/rpc-tests/test_framework/test_framework.py +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2014-2016 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Base class for RPC testing.""" - -import logging -import optparse -import os -import sys -import shutil -import tempfile -import traceback - -from .util import ( - initialize_chain, - start_nodes, - connect_nodes_bi, - sync_blocks, - sync_mempools, - stop_nodes, - stop_node, - enable_coverage, - check_json_precision, - initialize_chain_clean, - PortSeed, -) -from .authproxy import JSONRPCException - - -class BitcoinTestFramework(object): - - def __init__(self): - self.num_nodes = 4 - self.setup_clean_chain = False - self.nodes = None - - def run_test(self): - raise NotImplementedError - - def add_options(self, parser): - pass - - def setup_chain(self): - self.log.info("Initializing test directory "+self.options.tmpdir) - if self.setup_clean_chain: - initialize_chain_clean(self.options.tmpdir, self.num_nodes) - else: - initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir) - - def stop_node(self, num_node): - stop_node(self.nodes[num_node], num_node) - - def setup_nodes(self): - return start_nodes(self.num_nodes, self.options.tmpdir) - - def setup_network(self, split = False): - self.nodes = self.setup_nodes() - - # Connect the nodes as a "chain". This allows us - # to split the network between nodes 1 and 2 to get - # two halves that can work on competing chains. - - # If we joined network halves, connect the nodes from the joint - # on outward. This ensures that chains are properly reorganised. - if not split: - connect_nodes_bi(self.nodes, 1, 2) - sync_blocks(self.nodes[1:3]) - sync_mempools(self.nodes[1:3]) - - connect_nodes_bi(self.nodes, 0, 1) - connect_nodes_bi(self.nodes, 2, 3) - self.is_network_split = split - self.sync_all() - - def split_network(self): - """ - Split the network of four nodes into nodes 0/1 and 2/3. - """ - assert not self.is_network_split - stop_nodes(self.nodes) - self.setup_network(True) - - def sync_all(self): - if self.is_network_split: - sync_blocks(self.nodes[:2]) - sync_blocks(self.nodes[2:]) - sync_mempools(self.nodes[:2]) - sync_mempools(self.nodes[2:]) - else: - sync_blocks(self.nodes) - sync_mempools(self.nodes) - - def join_network(self): - """ - Join the (previously split) network halves together. - """ - assert self.is_network_split - stop_nodes(self.nodes) - self.setup_network(False) - - def main(self): - - parser = optparse.OptionParser(usage="%prog [options]") - parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", - 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"), - 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("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), - 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.") - parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true", - help="Print out all RPC calls as they are made") - parser.add_option("--portseed", dest="port_seed", default=os.getpid(), type='int', - help="The seed to use for assigning port numbers (default: current process id)") - parser.add_option("--coveragedir", dest="coveragedir", - help="Write tested RPC commands into this directory") - self.add_options(parser) - (self.options, self.args) = parser.parse_args() - - # backup dir variable for removal at cleanup - self.options.root, self.options.tmpdir = self.options.tmpdir, self.options.tmpdir + '/' + str(self.options.port_seed) - - if self.options.coveragedir: - enable_coverage(self.options.coveragedir) - - PortSeed.n = self.options.port_seed - - os.environ['PATH'] = self.options.srcdir+":"+self.options.srcdir+"/qt:"+os.environ['PATH'] - - check_json_precision() - - # Set up temp directory and start logging - os.makedirs(self.options.tmpdir, exist_ok=False) - self._start_logging() - - success = False - - try: - self.setup_chain() - self.setup_network() - self.run_test() - success = True - except JSONRPCException as e: - self.log.exception("JSONRPC error") - except AssertionError as e: - self.log.exception("Assertion failed") - except KeyError as e: - self.log.exception("Key error") - except Exception as e: - self.log.exception("Unexpected exception caught during testing") - except KeyboardInterrupt as e: - self.log.warning("Exiting after keyboard interrupt") - - if not self.options.noshutdown: - self.log.info("Stopping nodes") - stop_nodes(self.nodes) - else: - 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: - self.log.info("Cleaning up") - shutil.rmtree(self.options.tmpdir) - if not os.listdir(self.options.root): - os.rmdir(self.options.root) - else: - self.log.warning("Not cleaning up dir %s" % self.options.tmpdir) - if os.getenv("PYTHON_DEBUG", ""): - # Dump the end of the debug logs, to aid in debugging rare - # travis failures. - import glob - filenames = glob.glob(self.options.tmpdir + "/node*/regtest/debug.log") - MAX_LINES_TO_PRINT = 1000 - for f in filenames: - print("From" , f, ":") - from collections import deque - print("".join(deque(open(f), MAX_LINES_TO_PRINT))) - if success: - self.log.info("Tests successful") - sys.exit(0) - else: - self.log.error("Test failed. Test logging available at %s/test_framework.log", self.options.tmpdir) - logging.shutdown() - sys.exit(1) - - def _start_logging(self): - # Add logger and logging handlers - self.log = logging.getLogger('TestFramework') - self.log.setLevel(logging.DEBUG) - # Create file handler to log all messages - fh = logging.FileHandler(self.options.tmpdir + '/test_framework.log') - fh.setLevel(logging.DEBUG) - # Create console handler to log messages to stderr. By default this logs only error messages, but can be configured with --loglevel. - ch = logging.StreamHandler(sys.stdout) - # User can provide log level as a number or string (eg DEBUG). loglevel was caught as a string, so try to convert it to an int - ll = int(self.options.loglevel) if self.options.loglevel.isdigit() else self.options.loglevel.upper() - ch.setLevel(ll) - # Format logs the same as bitcoind's debug.log with microprecision (so log files can be concatenated and sorted) - formatter = logging.Formatter(fmt = '%(asctime)s.%(msecs)03d000 %(name)s (%(levelname)s): %(message)s', datefmt='%Y-%m-%d %H:%M:%S') - fh.setFormatter(formatter) - ch.setFormatter(formatter) - # add the handlers to the logger - self.log.addHandler(fh) - self.log.addHandler(ch) - - if self.options.trace_rpc: - rpc_logger = logging.getLogger("BitcoinRPC") - rpc_logger.setLevel(logging.DEBUG) - rpc_handler = logging.StreamHandler(sys.stdout) - rpc_handler.setLevel(logging.DEBUG) - rpc_logger.addHandler(rpc_handler) - -# Test framework for doing p2p comparison testing, which sets up some bitcoind -# binaries: -# 1 binary: test binary -# 2 binaries: 1 test binary, 1 ref binary -# n>2 binaries: 1 test binary, n-1 ref binaries - -class ComparisonTestFramework(BitcoinTestFramework): - - def __init__(self): - super().__init__() - self.num_nodes = 2 - self.setup_clean_chain = True - - def add_options(self, parser): - parser.add_option("--testbinary", dest="testbinary", - default=os.getenv("BITCOIND", "bitcoind"), - help="bitcoind binary to test") - parser.add_option("--refbinary", dest="refbinary", - default=os.getenv("BITCOIND", "bitcoind"), - help="bitcoind binary to use for reference nodes (if any)") - - def setup_network(self): - self.nodes = start_nodes( - self.num_nodes, self.options.tmpdir, - extra_args=[['-whitelist=127.0.0.1']] * self.num_nodes, - binary=[self.options.testbinary] + - [self.options.refbinary]*(self.num_nodes-1)) |