mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
Merge #11068: qa: Move wait_until to util
08ce33f8e
qa: Move wait_until to util (MarcoFalke)
Pull request description:
This moves `wait_until` to `util.py` to make it generally available to python tests.
Also, `wait_until` now takes an optional lock that is acquired while testing the predicate.
Previously the lock was always acquired, even when it was not necessary, cf. `disconnect_ban.py`.
Tree-SHA512: 18e452a017a6566fa8ad09bde058e1b841e167039dc63299e70cfa7a6dcbc779581e60ca3e8eb2f1b610767d5208b9376c203eb11015b250fd0542b5eb4215a8
This commit is contained in:
parent
d09f88d985
commit
956e6bc016
@ -109,7 +109,7 @@ class BIP65Test(BitcoinTestFramework):
|
|||||||
node0.send_and_ping(msg_block(block))
|
node0.send_and_ping(msg_block(block))
|
||||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||||
|
|
||||||
assert wait_until(lambda: "reject" in node0.last_message.keys())
|
wait_until(lambda: "reject" in node0.last_message.keys(), lock=mininode_lock)
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE)
|
assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE)
|
||||||
assert_equal(node0.last_message["reject"].reason, b'bad-version(0x00000003)')
|
assert_equal(node0.last_message["reject"].reason, b'bad-version(0x00000003)')
|
||||||
@ -136,7 +136,7 @@ class BIP65Test(BitcoinTestFramework):
|
|||||||
node0.send_and_ping(msg_block(block))
|
node0.send_and_ping(msg_block(block))
|
||||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||||
|
|
||||||
assert wait_until (lambda: "reject" in node0.last_message.keys())
|
wait_until(lambda: "reject" in node0.last_message.keys(), lock=mininode_lock)
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
assert node0.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD]
|
assert node0.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD]
|
||||||
assert_equal(node0.last_message["reject"].data, block.sha256)
|
assert_equal(node0.last_message["reject"].data, block.sha256)
|
||||||
|
@ -99,7 +99,7 @@ class BIP66Test(BitcoinTestFramework):
|
|||||||
node0.send_and_ping(msg_block(block))
|
node0.send_and_ping(msg_block(block))
|
||||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||||
|
|
||||||
assert wait_until(lambda: "reject" in node0.last_message.keys())
|
wait_until(lambda: "reject" in node0.last_message.keys(), lock=mininode_lock)
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE)
|
assert_equal(node0.last_message["reject"].code, REJECT_OBSOLETE)
|
||||||
assert_equal(node0.last_message["reject"].reason, b'bad-version(0x00000002)')
|
assert_equal(node0.last_message["reject"].reason, b'bad-version(0x00000002)')
|
||||||
@ -127,7 +127,7 @@ class BIP66Test(BitcoinTestFramework):
|
|||||||
node0.send_and_ping(msg_block(block))
|
node0.send_and_ping(msg_block(block))
|
||||||
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
|
||||||
|
|
||||||
assert wait_until (lambda: "reject" in node0.last_message.keys())
|
wait_until(lambda: "reject" in node0.last_message.keys(), lock=mininode_lock)
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
# We can receive different reject messages depending on whether
|
# We can receive different reject messages depending on whether
|
||||||
# bitcoind is running with multiple script check threads. If script
|
# bitcoind is running with multiple script check threads. If script
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test node disconnect and ban behavior"""
|
"""Test node disconnect and ban behavior"""
|
||||||
|
|
||||||
from test_framework.mininode import wait_until
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import (assert_equal,
|
from test_framework.util import (
|
||||||
|
assert_equal,
|
||||||
assert_raises_jsonrpc,
|
assert_raises_jsonrpc,
|
||||||
connect_nodes_bi,
|
connect_nodes_bi,
|
||||||
|
wait_until,
|
||||||
set_node_times,
|
set_node_times,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ class DisconnectBanTest(BitcoinTestFramework):
|
|||||||
self.log.info("setban: successfully ban single IP address")
|
self.log.info("setban: successfully ban single IP address")
|
||||||
assert_equal(len(self.nodes[1].getpeerinfo()), 2) # node1 should have 2 connections to node0 at this point
|
assert_equal(len(self.nodes[1].getpeerinfo()), 2) # node1 should have 2 connections to node0 at this point
|
||||||
self.nodes[1].setban("127.0.0.1", "add")
|
self.nodes[1].setban("127.0.0.1", "add")
|
||||||
assert wait_until(lambda: len(self.nodes[1].getpeerinfo()) == 0, timeout=10)
|
wait_until(lambda: len(self.nodes[1].getpeerinfo()) == 0, timeout=10)
|
||||||
assert_equal(len(self.nodes[1].getpeerinfo()), 0) # all nodes must be disconnected at this point
|
assert_equal(len(self.nodes[1].getpeerinfo()), 0) # all nodes must be disconnected at this point
|
||||||
assert_equal(len(self.nodes[1].listbanned()), 1)
|
assert_equal(len(self.nodes[1].listbanned()), 1)
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ class DisconnectBanTest(BitcoinTestFramework):
|
|||||||
self.log.info("disconnectnode: successfully disconnect node by address")
|
self.log.info("disconnectnode: successfully disconnect node by address")
|
||||||
address1 = self.nodes[0].getpeerinfo()[0]['addr']
|
address1 = self.nodes[0].getpeerinfo()[0]['addr']
|
||||||
self.nodes[0].disconnectnode(address=address1)
|
self.nodes[0].disconnectnode(address=address1)
|
||||||
assert wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, timeout=10)
|
wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, timeout=10)
|
||||||
assert not [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1]
|
assert not [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1]
|
||||||
|
|
||||||
self.log.info("disconnectnode: successfully reconnect node")
|
self.log.info("disconnectnode: successfully reconnect node")
|
||||||
@ -99,7 +100,7 @@ class DisconnectBanTest(BitcoinTestFramework):
|
|||||||
self.log.info("disconnectnode: successfully disconnect node by node id")
|
self.log.info("disconnectnode: successfully disconnect node by node id")
|
||||||
id1 = self.nodes[0].getpeerinfo()[0]['id']
|
id1 = self.nodes[0].getpeerinfo()[0]['id']
|
||||||
self.nodes[0].disconnectnode(nodeid=id1)
|
self.nodes[0].disconnectnode(nodeid=id1)
|
||||||
assert wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, timeout=10)
|
wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, timeout=10)
|
||||||
assert not [node for node in self.nodes[0].getpeerinfo() if node['id'] == id1]
|
assert not [node for node in self.nodes[0].getpeerinfo() if node['id'] == id1]
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -23,13 +23,13 @@ from test_framework.mininode import (
|
|||||||
mininode_lock,
|
mininode_lock,
|
||||||
msg_block,
|
msg_block,
|
||||||
msg_getdata,
|
msg_getdata,
|
||||||
wait_until,
|
|
||||||
)
|
)
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_equal,
|
assert_equal,
|
||||||
connect_nodes,
|
connect_nodes,
|
||||||
p2p_port,
|
p2p_port,
|
||||||
|
wait_until,
|
||||||
)
|
)
|
||||||
|
|
||||||
# NodeConnCB is a class containing callbacks to be executed when a P2P
|
# NodeConnCB is a class containing callbacks to be executed when a P2P
|
||||||
@ -209,7 +209,7 @@ class ExampleTest(BitcoinTestFramework):
|
|||||||
|
|
||||||
# wait_until() will loop until a predicate condition is met. Use it to test properties of the
|
# wait_until() will loop until a predicate condition is met. Use it to test properties of the
|
||||||
# NodeConnCB objects.
|
# NodeConnCB objects.
|
||||||
assert wait_until(lambda: sorted(blocks) == sorted(list(node2.block_receive_map.keys())), timeout=5)
|
wait_until(lambda: sorted(blocks) == sorted(list(node2.block_receive_map.keys())), timeout=5, lock=mininode_lock)
|
||||||
|
|
||||||
self.log.info("Check that each block was received only once")
|
self.log.info("Check that each block was received only once")
|
||||||
# The network thread uses a global lock on data access to the NodeConn objects when sending and receiving
|
# The network thread uses a global lock on data access to the NodeConn objects when sending and receiving
|
||||||
|
@ -32,7 +32,6 @@ Test is as follows:
|
|||||||
"""
|
"""
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from test_framework.mininode import wait_until
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import *
|
from test_framework.util import *
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ class MempoolPersistTest(BitcoinTestFramework):
|
|||||||
self.nodes.append(self.start_node(1, self.options.tmpdir))
|
self.nodes.append(self.start_node(1, self.options.tmpdir))
|
||||||
# Give dashd a second to reload the mempool
|
# Give dashd a second to reload the mempool
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
assert wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
|
wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
|
||||||
assert_equal(len(self.nodes[1].getrawmempool()), 0)
|
assert_equal(len(self.nodes[1].getrawmempool()), 0)
|
||||||
|
|
||||||
self.log.debug("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.")
|
self.log.debug("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.")
|
||||||
@ -84,7 +83,7 @@ class MempoolPersistTest(BitcoinTestFramework):
|
|||||||
self.stop_nodes()
|
self.stop_nodes()
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
self.nodes.append(self.start_node(0, self.options.tmpdir))
|
self.nodes.append(self.start_node(0, self.options.tmpdir))
|
||||||
assert wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
|
wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
MempoolPersistTest().main()
|
MempoolPersistTest().main()
|
||||||
|
@ -67,7 +67,7 @@ class TestNode(NodeConnCB):
|
|||||||
def request_headers_and_sync(self, locator, hashstop=0):
|
def request_headers_and_sync(self, locator, hashstop=0):
|
||||||
self.clear_block_announcement()
|
self.clear_block_announcement()
|
||||||
self.get_headers(locator, hashstop)
|
self.get_headers(locator, hashstop)
|
||||||
assert wait_until(self.received_block_announcement, timeout=30)
|
wait_until(self.received_block_announcement, timeout=30, lock=mininode_lock)
|
||||||
self.clear_block_announcement()
|
self.clear_block_announcement()
|
||||||
|
|
||||||
# Block until a block announcement for a particular block hash is
|
# Block until a block announcement for a particular block hash is
|
||||||
@ -75,7 +75,7 @@ class TestNode(NodeConnCB):
|
|||||||
def wait_for_block_announcement(self, block_hash, timeout=30):
|
def wait_for_block_announcement(self, block_hash, timeout=30):
|
||||||
def received_hash():
|
def received_hash():
|
||||||
return (block_hash in self.announced_blockhashes)
|
return (block_hash in self.announced_blockhashes)
|
||||||
return wait_until(received_hash, timeout=timeout)
|
wait_until(received_hash, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
def send_await_disconnect(self, message, timeout=30):
|
def send_await_disconnect(self, message, timeout=30):
|
||||||
"""Sends a message to the node and wait for disconnect.
|
"""Sends a message to the node and wait for disconnect.
|
||||||
@ -83,11 +83,7 @@ class TestNode(NodeConnCB):
|
|||||||
This is used when we want to send a message into the node that we expect
|
This is used when we want to send a message into the node that we expect
|
||||||
will get us disconnected, eg an invalid block."""
|
will get us disconnected, eg an invalid block."""
|
||||||
self.send_message(message)
|
self.send_message(message)
|
||||||
success = wait_until(lambda: not self.connected, timeout=timeout)
|
wait_until(lambda: not self.connected, timeout=timeout, lock=mininode_lock)
|
||||||
if not success:
|
|
||||||
logger.error("send_await_disconnect failed!")
|
|
||||||
raise AssertionError("send_await_disconnect failed!")
|
|
||||||
return success
|
|
||||||
|
|
||||||
class CompactBlocksTest(BitcoinTestFramework):
|
class CompactBlocksTest(BitcoinTestFramework):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -143,9 +139,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
# Make sure we get a SENDCMPCT message from our peer
|
# Make sure we get a SENDCMPCT message from our peer
|
||||||
def received_sendcmpct():
|
def received_sendcmpct():
|
||||||
return (len(test_node.last_sendcmpct) > 0)
|
return (len(test_node.last_sendcmpct) > 0)
|
||||||
got_message = wait_until(received_sendcmpct, timeout=30)
|
wait_until(received_sendcmpct, timeout=30, lock=mininode_lock)
|
||||||
assert(received_sendcmpct())
|
|
||||||
assert(got_message)
|
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
# Check that the first version received is the preferred one
|
# Check that the first version received is the preferred one
|
||||||
assert_equal(test_node.last_sendcmpct[0].version, preferred_version)
|
assert_equal(test_node.last_sendcmpct[0].version, preferred_version)
|
||||||
@ -158,7 +152,6 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
block_hash = int(node.generate(1)[0], 16)
|
block_hash = int(node.generate(1)[0], 16)
|
||||||
peer.wait_for_block_announcement(block_hash, timeout=30)
|
peer.wait_for_block_announcement(block_hash, timeout=30)
|
||||||
assert(peer.block_announced)
|
assert(peer.block_announced)
|
||||||
assert(got_message)
|
|
||||||
|
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
assert predicate(peer), (
|
assert predicate(peer), (
|
||||||
@ -255,7 +248,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
|
|
||||||
# Wait until we've seen the block announcement for the resulting tip
|
# Wait until we've seen the block announcement for the resulting tip
|
||||||
tip = int(node.getbestblockhash(), 16)
|
tip = int(node.getbestblockhash(), 16)
|
||||||
assert(test_node.wait_for_block_announcement(tip))
|
test_node.wait_for_block_announcement(tip)
|
||||||
|
|
||||||
# Make sure we will receive a fast-announce compact block
|
# Make sure we will receive a fast-announce compact block
|
||||||
self.request_cb_announcements(test_node, node, version)
|
self.request_cb_announcements(test_node, node, version)
|
||||||
@ -270,8 +263,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
block.rehash()
|
block.rehash()
|
||||||
|
|
||||||
# Wait until the block was announced (via compact blocks)
|
# Wait until the block was announced (via compact blocks)
|
||||||
wait_until(test_node.received_block_announcement, timeout=30)
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock)
|
||||||
assert(test_node.received_block_announcement())
|
|
||||||
|
|
||||||
# Now fetch and check the compact block
|
# Now fetch and check the compact block
|
||||||
header_and_shortids = None
|
header_and_shortids = None
|
||||||
@ -287,8 +279,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
inv = CInv(20, block_hash) # 20 == "CompactBlock"
|
inv = CInv(20, block_hash) # 20 == "CompactBlock"
|
||||||
test_node.send_message(msg_getdata([inv]))
|
test_node.send_message(msg_getdata([inv]))
|
||||||
|
|
||||||
wait_until(test_node.received_block_announcement, timeout=30)
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock)
|
||||||
assert(test_node.received_block_announcement())
|
|
||||||
|
|
||||||
# Now fetch and check the compact block
|
# Now fetch and check the compact block
|
||||||
header_and_shortids = None
|
header_and_shortids = None
|
||||||
@ -346,13 +337,11 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
|
|
||||||
if announce == "inv":
|
if announce == "inv":
|
||||||
test_node.send_message(msg_inv([CInv(2, block.sha256)]))
|
test_node.send_message(msg_inv([CInv(2, block.sha256)]))
|
||||||
success = wait_until(lambda: "getheaders" in test_node.last_message, timeout=30)
|
wait_until(lambda: "getheaders" in test_node.last_message, timeout=30, lock=mininode_lock)
|
||||||
assert(success)
|
|
||||||
test_node.send_header_for_blocks([block])
|
test_node.send_header_for_blocks([block])
|
||||||
else:
|
else:
|
||||||
test_node.send_header_for_blocks([block])
|
test_node.send_header_for_blocks([block])
|
||||||
success = wait_until(lambda: "getdata" in test_node.last_message, timeout=30)
|
wait_until(lambda: "getdata" in test_node.last_message, timeout=30, lock=mininode_lock)
|
||||||
assert(success)
|
|
||||||
assert_equal(len(test_node.last_message["getdata"].inv), 1)
|
assert_equal(len(test_node.last_message["getdata"].inv), 1)
|
||||||
assert_equal(test_node.last_message["getdata"].inv[0].type, 20)
|
assert_equal(test_node.last_message["getdata"].inv[0].type, 20)
|
||||||
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256)
|
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256)
|
||||||
@ -520,8 +509,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock)
|
assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock)
|
||||||
|
|
||||||
# We should receive a getdata request
|
# We should receive a getdata request
|
||||||
success = wait_until(lambda: "getdata" in test_node.last_message, timeout=10)
|
wait_until(lambda: "getdata" in test_node.last_message, timeout=10, lock=mininode_lock)
|
||||||
assert(success)
|
|
||||||
assert_equal(len(test_node.last_message["getdata"].inv), 1)
|
assert_equal(len(test_node.last_message["getdata"].inv), 1)
|
||||||
assert(test_node.last_message["getdata"].inv[0].type == 2)
|
assert(test_node.last_message["getdata"].inv[0].type == 2)
|
||||||
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256)
|
assert_equal(test_node.last_message["getdata"].inv[0].hash, block.sha256)
|
||||||
@ -545,8 +533,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
num_to_request = random.randint(1, len(block.vtx))
|
num_to_request = random.randint(1, len(block.vtx))
|
||||||
msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request)))
|
msg.block_txn_request.from_absolute(sorted(random.sample(range(len(block.vtx)), num_to_request)))
|
||||||
test_node.send_message(msg)
|
test_node.send_message(msg)
|
||||||
success = wait_until(lambda: "blocktxn" in test_node.last_message, timeout=10)
|
wait_until(lambda: "blocktxn" in test_node.last_message, timeout=10, lock=mininode_lock)
|
||||||
assert(success)
|
|
||||||
|
|
||||||
[tx.calc_sha256() for tx in block.vtx]
|
[tx.calc_sha256() for tx in block.vtx]
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
@ -579,22 +566,20 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
for i in range(MAX_CMPCTBLOCK_DEPTH + 1):
|
for i in range(MAX_CMPCTBLOCK_DEPTH + 1):
|
||||||
test_node.clear_block_announcement()
|
test_node.clear_block_announcement()
|
||||||
new_blocks.append(node.generate(1)[0])
|
new_blocks.append(node.generate(1)[0])
|
||||||
wait_until(test_node.received_block_announcement, timeout=30)
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock)
|
||||||
|
|
||||||
test_node.clear_block_announcement()
|
test_node.clear_block_announcement()
|
||||||
test_node.send_message(msg_getdata([CInv(20, int(new_blocks[0], 16))]))
|
test_node.send_message(msg_getdata([CInv(20, int(new_blocks[0], 16))]))
|
||||||
success = wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30)
|
wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30, lock=mininode_lock)
|
||||||
assert(success)
|
|
||||||
|
|
||||||
test_node.clear_block_announcement()
|
test_node.clear_block_announcement()
|
||||||
node.generate(1)
|
node.generate(1)
|
||||||
wait_until(test_node.received_block_announcement, timeout=30)
|
wait_until(test_node.received_block_announcement, timeout=30, lock=mininode_lock)
|
||||||
test_node.clear_block_announcement()
|
test_node.clear_block_announcement()
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
test_node.last_message.pop("block", None)
|
test_node.last_message.pop("block", None)
|
||||||
test_node.send_message(msg_getdata([CInv(20, int(new_blocks[0], 16))]))
|
test_node.send_message(msg_getdata([CInv(20, int(new_blocks[0], 16))]))
|
||||||
success = wait_until(lambda: "block" in test_node.last_message, timeout=30)
|
wait_until(lambda: "block" in test_node.last_message, timeout=30, lock=mininode_lock)
|
||||||
assert(success)
|
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
test_node.last_message["block"].block.calc_sha256()
|
test_node.last_message["block"].block.calc_sha256()
|
||||||
assert_equal(test_node.last_message["block"].block.sha256, int(new_blocks[0], 16))
|
assert_equal(test_node.last_message["block"].block.sha256, int(new_blocks[0], 16))
|
||||||
@ -639,7 +624,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||||||
node.submitblock(ToHex(block))
|
node.submitblock(ToHex(block))
|
||||||
|
|
||||||
for l in listeners:
|
for l in listeners:
|
||||||
wait_until(lambda: l.received_block_announcement(), timeout=30)
|
wait_until(lambda: l.received_block_announcement(), timeout=30, lock=mininode_lock)
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
for l in listeners:
|
for l in listeners:
|
||||||
assert "cmpctblock" in l.last_message
|
assert "cmpctblock" in l.last_message
|
||||||
|
@ -108,9 +108,9 @@ class P2PLeakTest(BitcoinTestFramework):
|
|||||||
|
|
||||||
NetworkThread().start() # Start up network handling in another thread
|
NetworkThread().start() # Start up network handling in another thread
|
||||||
|
|
||||||
assert wait_until(lambda: no_version_bannode.ever_connected, timeout=10)
|
wait_until(lambda: no_version_bannode.ever_connected, timeout=10, lock=mininode_lock)
|
||||||
assert wait_until(lambda: no_version_idlenode.ever_connected, timeout=10)
|
wait_until(lambda: no_version_idlenode.ever_connected, timeout=10, lock=mininode_lock)
|
||||||
assert wait_until(lambda: no_verack_idlenode.version_received, timeout=10)
|
wait_until(lambda: no_verack_idlenode.version_received, timeout=10, lock=mininode_lock)
|
||||||
|
|
||||||
# Mine a block and make sure that it's not sent to the connected nodes
|
# Mine a block and make sure that it's not sent to the connected nodes
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
|
@ -139,7 +139,7 @@ class TestNode(NodeConnCB):
|
|||||||
expect_headers = headers if headers != None else []
|
expect_headers = headers if headers != None else []
|
||||||
expect_inv = inv if inv != None else []
|
expect_inv = inv if inv != None else []
|
||||||
test_function = lambda: self.block_announced
|
test_function = lambda: self.block_announced
|
||||||
assert(wait_until(test_function, timeout=60))
|
wait_until(test_function, timeout=60, lock=mininode_lock)
|
||||||
with mininode_lock:
|
with mininode_lock:
|
||||||
self.block_announced = False
|
self.block_announced = False
|
||||||
|
|
||||||
@ -166,12 +166,12 @@ class TestNode(NodeConnCB):
|
|||||||
return
|
return
|
||||||
|
|
||||||
test_function = lambda: "getdata" in self.last_message and [x.hash for x in self.last_message["getdata"].inv] == hash_list
|
test_function = lambda: "getdata" in self.last_message and [x.hash for x in self.last_message["getdata"].inv] == hash_list
|
||||||
assert(wait_until(test_function, timeout=timeout))
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
return
|
return
|
||||||
|
|
||||||
def wait_for_block_announcement(self, block_hash, timeout=60):
|
def wait_for_block_announcement(self, block_hash, timeout=60):
|
||||||
test_function = lambda: self.last_blockhash_announced == block_hash
|
test_function = lambda: self.last_blockhash_announced == block_hash
|
||||||
assert(wait_until(test_function, timeout=timeout))
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
return
|
return
|
||||||
|
|
||||||
def send_header_for_blocks(self, new_blocks):
|
def send_header_for_blocks(self, new_blocks):
|
||||||
|
@ -19,7 +19,7 @@ TestNode behaves as follows:
|
|||||||
|
|
||||||
from .mininode import *
|
from .mininode import *
|
||||||
from .blockstore import BlockStore, TxStore
|
from .blockstore import BlockStore, TxStore
|
||||||
from .util import p2p_port
|
from .util import p2p_port, wait_until
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ class TestManager(object):
|
|||||||
def wait_for_disconnections(self):
|
def wait_for_disconnections(self):
|
||||||
def disconnected():
|
def disconnected():
|
||||||
return all(node.closed for node in self.test_nodes)
|
return all(node.closed for node in self.test_nodes)
|
||||||
return wait_until(disconnected, timeout=10)
|
wait_until(disconnected, timeout=10, lock=mininode_lock)
|
||||||
|
|
||||||
def wait_for_verack(self):
|
def wait_for_verack(self):
|
||||||
return all(node.wait_for_verack() for node in self.test_nodes)
|
return all(node.wait_for_verack() for node in self.test_nodes)
|
||||||
@ -197,7 +197,7 @@ class TestManager(object):
|
|||||||
def wait_for_pings(self, counter, timeout=float('inf')):
|
def wait_for_pings(self, counter, timeout=float('inf')):
|
||||||
def received_pongs():
|
def received_pongs():
|
||||||
return all(node.received_ping_response(counter) for node in self.test_nodes)
|
return all(node.received_ping_response(counter) for node in self.test_nodes)
|
||||||
return wait_until(received_pongs, timeout=timeout)
|
wait_until(received_pongs, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
# sync_blocks: Wait for all connections to request the blockhash given
|
# sync_blocks: Wait for all connections to request the blockhash given
|
||||||
# then send get_headers to find out the tip of each node, and synchronize
|
# then send get_headers to find out the tip of each node, and synchronize
|
||||||
@ -210,8 +210,7 @@ class TestManager(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# --> error if not requested
|
# --> error if not requested
|
||||||
if not wait_until(blocks_requested, attempts=20*num_blocks, sleep=0.1):
|
wait_until(blocks_requested, attempts=20*num_blocks, sleep=0.1, lock=mininode_lock)
|
||||||
raise AssertionError("Not all nodes requested block")
|
|
||||||
|
|
||||||
# Send getheaders message
|
# Send getheaders message
|
||||||
[ c.cb.send_getheaders() for c in self.connections ]
|
[ c.cb.send_getheaders() for c in self.connections ]
|
||||||
@ -231,8 +230,7 @@ class TestManager(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# --> error if not requested
|
# --> error if not requested
|
||||||
if not wait_until(transaction_requested, attempts=20*num_events):
|
wait_until(transaction_requested, attempts=20*num_events, lock=mininode_lock)
|
||||||
raise AssertionError("Not all nodes requested transaction")
|
|
||||||
|
|
||||||
# Get the mempool
|
# Get the mempool
|
||||||
[ c.cb.send_mempool() for c in self.connections ]
|
[ c.cb.send_mempool() for c in self.connections ]
|
||||||
|
@ -37,7 +37,7 @@ import time
|
|||||||
from threading import RLock, Thread
|
from threading import RLock, Thread
|
||||||
|
|
||||||
from test_framework.siphash import siphash256
|
from test_framework.siphash import siphash256
|
||||||
from test_framework.util import hex_str_to_bytes, bytes_to_hex_str
|
from test_framework.util import hex_str_to_bytes, bytes_to_hex_str, wait_until
|
||||||
|
|
||||||
import dash_hash
|
import dash_hash
|
||||||
|
|
||||||
@ -1299,22 +1299,6 @@ class msg_reject(object):
|
|||||||
return "msg_reject: %s %d %s [%064x]" \
|
return "msg_reject: %s %d %s [%064x]" \
|
||||||
% (self.message, self.code, self.reason, self.data)
|
% (self.message, self.code, self.reason, self.data)
|
||||||
|
|
||||||
# Helper function
|
|
||||||
def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), sleep=0.05):
|
|
||||||
if attempts == float('inf') and timeout == float('inf'):
|
|
||||||
timeout = 60
|
|
||||||
attempt = 0
|
|
||||||
elapsed = 0
|
|
||||||
|
|
||||||
while attempt < attempts and elapsed < timeout:
|
|
||||||
with mininode_lock:
|
|
||||||
if predicate():
|
|
||||||
return True
|
|
||||||
attempt += 1
|
|
||||||
elapsed += sleep
|
|
||||||
time.sleep(sleep)
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
class msg_sendcmpct(object):
|
class msg_sendcmpct(object):
|
||||||
command = b"sendcmpct"
|
command = b"sendcmpct"
|
||||||
@ -1624,21 +1608,21 @@ class NodeConnCB(object):
|
|||||||
|
|
||||||
def wait_for_disconnect(self, timeout=60):
|
def wait_for_disconnect(self, timeout=60):
|
||||||
test_function = lambda: not self.connected
|
test_function = lambda: not self.connected
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
# Message receiving helper methods
|
# Message receiving helper methods
|
||||||
|
|
||||||
def wait_for_block(self, blockhash, timeout=60):
|
def wait_for_block(self, blockhash, timeout=60):
|
||||||
test_function = lambda: self.last_message.get("block") and self.last_message["block"].block.rehash() == blockhash
|
test_function = lambda: self.last_message.get("block") and self.last_message["block"].block.rehash() == blockhash
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
def wait_for_getdata(self, timeout=60):
|
def wait_for_getdata(self, timeout=60):
|
||||||
test_function = lambda: self.last_message.get("getdata")
|
test_function = lambda: self.last_message.get("getdata")
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
def wait_for_getheaders(self, timeout=60):
|
def wait_for_getheaders(self, timeout=60):
|
||||||
test_function = lambda: self.last_message.get("getheaders")
|
test_function = lambda: self.last_message.get("getheaders")
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
def wait_for_inv(self, expected_inv, timeout=60):
|
def wait_for_inv(self, expected_inv, timeout=60):
|
||||||
"""Waits for an INV message and checks that the first inv object in the message was as expected."""
|
"""Waits for an INV message and checks that the first inv object in the message was as expected."""
|
||||||
@ -1647,11 +1631,11 @@ class NodeConnCB(object):
|
|||||||
test_function = lambda: self.last_message.get("inv") and \
|
test_function = lambda: self.last_message.get("inv") and \
|
||||||
self.last_message["inv"].inv[0].type == expected_inv[0].type and \
|
self.last_message["inv"].inv[0].type == expected_inv[0].type and \
|
||||||
self.last_message["inv"].inv[0].hash == expected_inv[0].hash
|
self.last_message["inv"].inv[0].hash == expected_inv[0].hash
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
def wait_for_verack(self, timeout=60):
|
def wait_for_verack(self, timeout=60):
|
||||||
test_function = lambda: self.message_count["verack"]
|
test_function = lambda: self.message_count["verack"]
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
|
|
||||||
# Message sending helper functions
|
# Message sending helper functions
|
||||||
|
|
||||||
@ -1669,7 +1653,7 @@ class NodeConnCB(object):
|
|||||||
def sync_with_ping(self, timeout=60):
|
def sync_with_ping(self, timeout=60):
|
||||||
self.send_message(msg_ping(nonce=self.ping_counter))
|
self.send_message(msg_ping(nonce=self.ping_counter))
|
||||||
test_function = lambda: self.last_message.get("pong") and self.last_message["pong"].nonce == self.ping_counter
|
test_function = lambda: self.last_message.get("pong") and self.last_message["pong"].nonce == self.ping_counter
|
||||||
assert wait_until(test_function, timeout=timeout)
|
wait_until(test_function, timeout=timeout, lock=mininode_lock)
|
||||||
self.ping_counter += 1
|
self.ping_counter += 1
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -159,6 +159,28 @@ def str_to_b64str(string):
|
|||||||
def satoshi_round(amount):
|
def satoshi_round(amount):
|
||||||
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
|
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
|
||||||
|
|
||||||
|
def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), sleep=0.05, lock=None):
|
||||||
|
if attempts == float('inf') and timeout == float('inf'):
|
||||||
|
timeout = 60
|
||||||
|
attempt = 0
|
||||||
|
timeout += time.time()
|
||||||
|
|
||||||
|
while attempt < attempts and time.time() < timeout:
|
||||||
|
if lock:
|
||||||
|
with lock:
|
||||||
|
if predicate():
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if predicate():
|
||||||
|
return
|
||||||
|
attempt += 1
|
||||||
|
time.sleep(sleep)
|
||||||
|
|
||||||
|
# Print the cause of the timeout
|
||||||
|
assert_greater_than(attempts, attempt)
|
||||||
|
assert_greater_than(timeout, time.time())
|
||||||
|
raise RuntimeError('Unreachable')
|
||||||
|
|
||||||
# RPC/P2P connection constants and functions
|
# RPC/P2P connection constants and functions
|
||||||
############################################
|
############################################
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user