Dash Core  0.12.2.1
P2P Digital Currency
test_framework.py
Go to the documentation of this file.
1 #!/usr/bin/env python2
2 # Copyright (c) 2014-2015 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 # Base class for RPC testing
7 
8 # Add python-bitcoinrpc to module search path:
9 import os
10 import sys
11 
12 import shutil
13 import tempfile
14 import traceback
15 
16 from .util import (
17  initialize_chain,
18  assert_equal,
19  start_nodes,
20  connect_nodes_bi,
21  sync_blocks,
22  sync_mempools,
23  stop_nodes,
24  wait_bitcoinds,
25  enable_coverage,
26  check_json_precision,
27  initialize_chain_clean,
28 )
29 from .authproxy import AuthServiceProxy, JSONRPCException
30 
31 
32 class BitcoinTestFramework(object):
33 
34  # These may be over-ridden by subclasses:
35  def run_test(self):
36  for node in self.nodes:
37  assert_equal(node.getblockcount(), 200)
38  assert_equal(node.getbalance(), 25*500)
39 
40  def add_options(self, parser):
41  pass
42 
43  def setup_chain(self):
44  print("Initializing test directory "+self.options.tmpdir)
45  initialize_chain(self.options.tmpdir)
46 
47  def setup_nodes(self):
48  return start_nodes(4, self.options.tmpdir)
49 
50  def setup_network(self, split = False):
51  self.nodes = self.setup_nodes()
52 
53  # Connect the nodes as a "chain". This allows us
54  # to split the network between nodes 1 and 2 to get
55  # two halves that can work on competing chains.
56 
57  # If we joined network halves, connect the nodes from the joint
58  # on outward. This ensures that chains are properly reorganised.
59  if not split:
60  connect_nodes_bi(self.nodes, 1, 2)
61  sync_blocks(self.nodes[1:3])
62  sync_mempools(self.nodes[1:3])
63 
64  connect_nodes_bi(self.nodes, 0, 1)
65  connect_nodes_bi(self.nodes, 2, 3)
66  self.is_network_split = split
67  self.sync_all()
68 
69  def split_network(self):
70  """
71  Split the network of four nodes into nodes 0/1 and 2/3.
72  """
73  assert not self.is_network_split
74  stop_nodes(self.nodes)
76  self.setup_network(True)
77 
78  def sync_all(self):
79  if self.is_network_split:
80  sync_blocks(self.nodes[:2])
81  sync_blocks(self.nodes[2:])
82  sync_mempools(self.nodes[:2])
83  sync_mempools(self.nodes[2:])
84  else:
85  sync_blocks(self.nodes)
86  sync_mempools(self.nodes)
87 
88  def join_network(self):
89  """
90  Join the (previously split) network halves together.
91  """
92  assert self.is_network_split
93  stop_nodes(self.nodes)
95  self.setup_network(False)
96 
97  def main(self):
98  import optparse
99 
100  parser = optparse.OptionParser(usage="%prog [options]")
101  parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
102  help="Leave dashds and test.* datadir on exit or error")
103  parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true",
104  help="Don't stop dashds after the test execution")
105  parser.add_option("--srcdir", dest="srcdir", default="../../src",
106  help="Source directory containing dashd/dash-cli (default: %default)")
107  parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
108  help="Root directory for datadirs")
109  parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true",
110  help="Print out all RPC calls as they are made")
111  parser.add_option("--coveragedir", dest="coveragedir",
112  help="Write tested RPC commands into this directory")
113  self.add_options(parser)
114  (self.options, self.args) = parser.parse_args()
115 
116  if self.options.trace_rpc:
117  import logging
118  logging.basicConfig(level=logging.DEBUG)
119 
120  if self.options.coveragedir:
121  enable_coverage(self.options.coveragedir)
122 
123  os.environ['PATH'] = self.options.srcdir+":"+self.options.srcdir+"/qt:"+os.environ['PATH']
124 
126 
127  success = False
128  try:
129  if not os.path.isdir(self.options.tmpdir):
130  os.makedirs(self.options.tmpdir)
131  self.setup_chain()
132 
133  self.setup_network()
134 
135  self.run_test()
136 
137  success = True
138 
139  except JSONRPCException as e:
140  print("JSONRPC error: "+e.error['message'])
141  traceback.print_tb(sys.exc_info()[2])
142  except AssertionError as e:
143  print("Assertion failed: "+ str(e))
144  traceback.print_tb(sys.exc_info()[2])
145  except Exception as e:
146  print("Unexpected exception caught during testing: " + repr(e))
147  traceback.print_tb(sys.exc_info()[2])
148 
149  if not self.options.noshutdown:
150  print("Stopping nodes")
151  stop_nodes(self.nodes)
153  else:
154  print("Note: dashds were not stopped and may still be running")
155 
156  if not self.options.nocleanup and not self.options.noshutdown:
157  print("Cleaning up")
158  shutil.rmtree(self.options.tmpdir)
159 
160  if success:
161  print("Tests successful")
162  sys.exit(0)
163  else:
164  print("Failed")
165  sys.exit(1)
166 
167 
168 # Test framework for doing p2p comparison testing, which sets up some bitcoind
169 # binaries:
170 # 1 binary: test binary
171 # 2 binaries: 1 test binary, 1 ref binary
172 # n>2 binaries: 1 test binary, n-1 ref binaries
173 
175 
176  # Can override the num_nodes variable to indicate how many nodes to run.
177  def __init__(self):
178  self.num_nodes = 2
179 
180  def add_options(self, parser):
181  parser.add_option("--testbinary", dest="testbinary",
182  default=os.getenv("DASHD", "dashd"),
183  help="bitcoind binary to test")
184  parser.add_option("--refbinary", dest="refbinary",
185  default=os.getenv("DASHD", "dashd"),
186  help="bitcoind binary to use for reference nodes (if any)")
187 
188  def setup_chain(self):
189  print "Initializing test directory "+self.options.tmpdir
190  initialize_chain_clean(self.options.tmpdir, self.num_nodes)
191 
192  def setup_network(self):
194  self.num_nodes, self.options.tmpdir,
195  extra_args=[['-debug', '-whitelist=127.0.0.1']] * self.num_nodes,
196  binary=[self.options.testbinary] +
197  [self.options.refbinary]*(self.num_nodes-1))
def wait_bitcoinds()
Definition: util.py:337
def initialize_chain(test_dir)
Definition: util.py:184
def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None)
Definition: util.py:305
def check_json_precision()
Definition: spendfrom.py:28
def sync_mempools(rpc_connections, wait=1)
Definition: util.py:127
def initialize_chain_clean(test_dir, num_nodes)
Definition: util.py:252
def stop_nodes(nodes)
Definition: util.py:328
def sync_blocks(rpc_connections, wait=1)
Definition: util.py:117
def enable_coverage(dirname)
Definition: util.py:52
def assert_equal(thing1, thing2)
Definition: util.py:461
def connect_nodes_bi(nodes, a, b)
Definition: util.py:351