Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/test_node.py
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | class TestNode(): | ||||
- state about the node (whether it's running, etc) | - state about the node (whether it's running, etc) | ||||
- a Python subprocess.Popen object representing the running process | - a Python subprocess.Popen object representing the running process | ||||
- an RPC connection to the node | - an RPC connection to the node | ||||
- one or more P2P connections to the node | - one or more P2P connections to the node | ||||
To make things easier for the test writer, any unrecognised messages will | To make things easier for the test writer, any unrecognised messages will | ||||
be dispatched to the RPC connection.""" | be dispatched to the RPC connection.""" | ||||
def __init__(self, i, datadir, *, host, rpc_port, p2p_port, timewait, bitcoind, | def __init__(self, i, datadir, *, chain, host, rpc_port, p2p_port, timewait, bitcoind, bitcoin_cli, | ||||
bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False, emulator=None): | mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False, emulator=None): | ||||
self.index = i | self.index = i | ||||
self.datadir = datadir | self.datadir = datadir | ||||
self.bitcoinconf = os.path.join(self.datadir, "bitcoin.conf") | self.bitcoinconf = os.path.join(self.datadir, "bitcoin.conf") | ||||
self.stdout_dir = os.path.join(self.datadir, "stdout") | self.stdout_dir = os.path.join(self.datadir, "stdout") | ||||
self.stderr_dir = os.path.join(self.datadir, "stderr") | self.stderr_dir = os.path.join(self.datadir, "stderr") | ||||
self.chain = chain | |||||
self.host = host | self.host = host | ||||
self.rpc_port = rpc_port | self.rpc_port = rpc_port | ||||
self.p2p_port = p2p_port | self.p2p_port = p2p_port | ||||
self.name = "testnode-{}".format(i) | self.name = "testnode-{}".format(i) | ||||
self.rpc_timeout = timewait | self.rpc_timeout = timewait | ||||
self.binary = bitcoind | self.binary = bitcoind | ||||
if not os.path.isfile(self.binary): | if not os.path.isfile(self.binary): | ||||
raise FileNotFoundError( | raise FileNotFoundError( | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | def start(self, extra_args=None, stdout=None, | ||||
stdout = tempfile.NamedTemporaryFile( | stdout = tempfile.NamedTemporaryFile( | ||||
dir=self.stdout_dir, delete=False) | dir=self.stdout_dir, delete=False) | ||||
self.stderr = stderr | self.stderr = stderr | ||||
self.stdout = stdout | self.stdout = stdout | ||||
# Delete any existing cookie file -- if such a file exists (eg due to | # Delete any existing cookie file -- if such a file exists (eg due to | ||||
# unclean shutdown), it will get overwritten anyway by bitcoind, and | # unclean shutdown), it will get overwritten anyway by bitcoind, and | ||||
# potentially interfere with our attempt to authenticate | # potentially interfere with our attempt to authenticate | ||||
delete_cookie_file(self.datadir) | delete_cookie_file(self.datadir, self.chain) | ||||
# add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are | # add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are | ||||
# written to stderr and not the terminal | # written to stderr and not the terminal | ||||
subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1") | subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1") | ||||
p_args = [self.binary] + self.default_args + extra_args | p_args = [self.binary] + self.default_args + extra_args | ||||
if self.emulator is not None: | if self.emulator is not None: | ||||
p_args = [self.emulator] + p_args | p_args = [self.emulator] + p_args | ||||
Show All 12 Lines | def wait_for_rpc_connection(self): | ||||
"""Sets up an RPC connection to the bitcoind process. Returns False if unable to connect.""" | """Sets up an RPC connection to the bitcoind process. Returns False if unable to connect.""" | ||||
# Poll at a rate of four times per second | # Poll at a rate of four times per second | ||||
poll_per_s = 4 | poll_per_s = 4 | ||||
for _ in range(poll_per_s * self.rpc_timeout): | for _ in range(poll_per_s * self.rpc_timeout): | ||||
if self.process.poll() is not None: | if self.process.poll() is not None: | ||||
raise FailedToStartError(self._node_msg( | raise FailedToStartError(self._node_msg( | ||||
'bitcoind exited with status {} during initialization'.format(self.process.returncode))) | 'bitcoind exited with status {} during initialization'.format(self.process.returncode))) | ||||
try: | try: | ||||
rpc = get_rpc_proxy(rpc_url(self.datadir, self.host, self.rpc_port), | rpc = get_rpc_proxy( | ||||
self.index, timeout=self.rpc_timeout, coveragedir=self.coverage_dir) | rpc_url( | ||||
self.datadir, | |||||
self.chain, | |||||
self.host, | |||||
self.rpc_port), | |||||
self.index, | |||||
timeout=self.rpc_timeout, | |||||
coveragedir=self.coverage_dir) | |||||
rpc.getblockcount() | rpc.getblockcount() | ||||
# If the call to getblockcount() succeeds then the RPC | # If the call to getblockcount() succeeds then the RPC | ||||
# connection is up | # connection is up | ||||
self.log.debug("RPC successfully started") | self.log.debug("RPC successfully started") | ||||
if self.use_cli: | if self.use_cli: | ||||
return | return | ||||
self.rpc = rpc | self.rpc = rpc | ||||
self.rpc_connected = True | self.rpc_connected = True | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | class TestNode(): | ||||
def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): | def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): | ||||
wait_until(self.is_node_stopped, timeout=timeout) | wait_until(self.is_node_stopped, timeout=timeout) | ||||
@contextlib.contextmanager | @contextlib.contextmanager | ||||
def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2): | def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2): | ||||
if unexpected_msgs is None: | if unexpected_msgs is None: | ||||
unexpected_msgs = [] | unexpected_msgs = [] | ||||
time_end = time.time() + timeout | time_end = time.time() + timeout | ||||
debug_log = os.path.join(self.datadir, 'regtest', 'debug.log') | debug_log = os.path.join(self.datadir, self.chain, 'debug.log') | ||||
with open(debug_log, encoding='utf-8') as dl: | with open(debug_log, encoding='utf-8') as dl: | ||||
dl.seek(0, 2) | dl.seek(0, 2) | ||||
prev_size = dl.tell() | prev_size = dl.tell() | ||||
yield | yield | ||||
while True: | while True: | ||||
found = True | found = True | ||||
▲ Show 20 Lines • Show All 209 Lines • Show Last 20 Lines |