|
|
|
@ -42,6 +42,21 @@ from .util import (
@@ -42,6 +42,21 @@ from .util import (
|
|
|
|
|
from .authproxy import JSONRPCException |
|
|
|
|
|
|
|
|
|
class BitcoinTestFramework(object): |
|
|
|
|
"""Base class for a bitcoin test script. |
|
|
|
|
|
|
|
|
|
Individual bitcoin test scripts should subclass this class and override the following methods: |
|
|
|
|
|
|
|
|
|
- __init__() |
|
|
|
|
- add_options() |
|
|
|
|
- setup_chain() |
|
|
|
|
- setup_network() |
|
|
|
|
- run_test() |
|
|
|
|
|
|
|
|
|
The main() method should not be overridden. |
|
|
|
|
|
|
|
|
|
This class also contains various public and private helper methods.""" |
|
|
|
|
|
|
|
|
|
# Methods to override in subclass test scripts. |
|
|
|
|
|
|
|
|
|
TEST_EXIT_PASSED = 0 |
|
|
|
|
TEST_EXIT_FAILED = 1 |
|
|
|
@ -52,9 +67,6 @@ class BitcoinTestFramework(object):
@@ -52,9 +67,6 @@ class BitcoinTestFramework(object):
|
|
|
|
|
self.setup_clean_chain = False |
|
|
|
|
self.nodes = None |
|
|
|
|
|
|
|
|
|
def run_test(self): |
|
|
|
|
raise NotImplementedError |
|
|
|
|
|
|
|
|
|
def add_options(self, parser): |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
@ -65,24 +77,6 @@ class BitcoinTestFramework(object):
@@ -65,24 +77,6 @@ class BitcoinTestFramework(object):
|
|
|
|
|
else: |
|
|
|
|
self._initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir) |
|
|
|
|
|
|
|
|
|
def start_node(self, i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): |
|
|
|
|
return start_node(i, dirname, extra_args, rpchost, timewait, binary, stderr) |
|
|
|
|
|
|
|
|
|
def start_nodes(self, num_nodes, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): |
|
|
|
|
return start_nodes(num_nodes, dirname, extra_args, rpchost, timewait, binary) |
|
|
|
|
|
|
|
|
|
def stop_node(self, num_node): |
|
|
|
|
stop_node(self.nodes[num_node], num_node) |
|
|
|
|
|
|
|
|
|
def stop_nodes(self): |
|
|
|
|
stop_nodes(self.nodes) |
|
|
|
|
|
|
|
|
|
def setup_nodes(self): |
|
|
|
|
extra_args = None |
|
|
|
|
if hasattr(self, "extra_args"): |
|
|
|
|
extra_args = self.extra_args |
|
|
|
|
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) |
|
|
|
|
|
|
|
|
|
def setup_network(self): |
|
|
|
|
self.setup_nodes() |
|
|
|
|
|
|
|
|
@ -93,27 +87,16 @@ class BitcoinTestFramework(object):
@@ -93,27 +87,16 @@ class BitcoinTestFramework(object):
|
|
|
|
|
connect_nodes_bi(self.nodes, i, i + 1) |
|
|
|
|
self.sync_all() |
|
|
|
|
|
|
|
|
|
def split_network(self): |
|
|
|
|
""" |
|
|
|
|
Split the network of four nodes into nodes 0/1 and 2/3. |
|
|
|
|
""" |
|
|
|
|
disconnect_nodes(self.nodes[1], 2) |
|
|
|
|
disconnect_nodes(self.nodes[2], 1) |
|
|
|
|
self.sync_all([self.nodes[:2], self.nodes[2:]]) |
|
|
|
|
|
|
|
|
|
def sync_all(self, node_groups=None): |
|
|
|
|
if not node_groups: |
|
|
|
|
node_groups = [self.nodes] |
|
|
|
|
def setup_nodes(self): |
|
|
|
|
extra_args = None |
|
|
|
|
if hasattr(self, "extra_args"): |
|
|
|
|
extra_args = self.extra_args |
|
|
|
|
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) |
|
|
|
|
|
|
|
|
|
[sync_blocks(group) for group in node_groups] |
|
|
|
|
[sync_mempools(group) for group in node_groups] |
|
|
|
|
def run_test(self): |
|
|
|
|
raise NotImplementedError |
|
|
|
|
|
|
|
|
|
def join_network(self): |
|
|
|
|
""" |
|
|
|
|
Join the (previously split) network halves together. |
|
|
|
|
""" |
|
|
|
|
connect_nodes_bi(self.nodes, 1, 2) |
|
|
|
|
self.sync_all() |
|
|
|
|
# Main function. This should not be overridden by the subclass test scripts. |
|
|
|
|
|
|
|
|
|
def main(self): |
|
|
|
|
|
|
|
|
@ -209,6 +192,45 @@ class BitcoinTestFramework(object):
@@ -209,6 +192,45 @@ class BitcoinTestFramework(object):
|
|
|
|
|
logging.shutdown() |
|
|
|
|
sys.exit(self.TEST_EXIT_FAILED) |
|
|
|
|
|
|
|
|
|
# Public helper methods. These can be accessed by the subclass test scripts. |
|
|
|
|
|
|
|
|
|
def start_node(self, i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): |
|
|
|
|
return start_node(i, dirname, extra_args, rpchost, timewait, binary, stderr) |
|
|
|
|
|
|
|
|
|
def start_nodes(self, num_nodes, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): |
|
|
|
|
return start_nodes(num_nodes, dirname, extra_args, rpchost, timewait, binary) |
|
|
|
|
|
|
|
|
|
def stop_node(self, num_node): |
|
|
|
|
stop_node(self.nodes[num_node], num_node) |
|
|
|
|
|
|
|
|
|
def stop_nodes(self): |
|
|
|
|
stop_nodes(self.nodes) |
|
|
|
|
|
|
|
|
|
def split_network(self): |
|
|
|
|
""" |
|
|
|
|
Split the network of four nodes into nodes 0/1 and 2/3. |
|
|
|
|
""" |
|
|
|
|
disconnect_nodes(self.nodes[1], 2) |
|
|
|
|
disconnect_nodes(self.nodes[2], 1) |
|
|
|
|
self.sync_all([self.nodes[:2], self.nodes[2:]]) |
|
|
|
|
|
|
|
|
|
def join_network(self): |
|
|
|
|
""" |
|
|
|
|
Join the (previously split) network halves together. |
|
|
|
|
""" |
|
|
|
|
connect_nodes_bi(self.nodes, 1, 2) |
|
|
|
|
self.sync_all() |
|
|
|
|
|
|
|
|
|
def sync_all(self, node_groups=None): |
|
|
|
|
if not node_groups: |
|
|
|
|
node_groups = [self.nodes] |
|
|
|
|
|
|
|
|
|
for group in node_groups: |
|
|
|
|
sync_blocks(group) |
|
|
|
|
sync_mempools(group) |
|
|
|
|
|
|
|
|
|
# Private helper methods. These should not be accessed by the subclass test scripts. |
|
|
|
|
|
|
|
|
|
def _start_logging(self): |
|
|
|
|
# Add logger and logging handlers |
|
|
|
|
self.log = logging.getLogger('TestFramework') |
|
|
|
|