Changeset View
Changeset View
Standalone View
Standalone View
test/functional/example_test.py
Show All 17 Lines | |||||
from test_framework.mininode import ( | from test_framework.mininode import ( | ||||
CInv, | CInv, | ||||
NetworkThread, | NetworkThread, | ||||
NodeConn, | NodeConn, | ||||
NodeConnCB, | NodeConnCB, | ||||
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 | ||||
# message is received from the node-under-test. Subclass NodeConnCB and | # message is received from the node-under-test. Subclass NodeConnCB and | ||||
# override the on_*() methods if you need custom behaviour. | # override the on_*() methods if you need custom behaviour. | ||||
class BaseNode(NodeConnCB): | class BaseNode(NodeConnCB): | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
for block in blocks: | for block in blocks: | ||||
getdata_request = msg_getdata() | getdata_request = msg_getdata() | ||||
getdata_request.inv.append(CInv(2, block)) | getdata_request.inv.append(CInv(2, block)) | ||||
node2.send_message(getdata_request) | node2.send_message(getdata_request) | ||||
# 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( | wait_until(lambda: sorted(blocks) == sorted( | ||||
list(node2.block_receive_map.keys())), timeout=5) | 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 | ||||
# messages. The test thread should acquire the global lock before accessing any NodeConn data to avoid locking | # messages. The test thread should acquire the global lock before accessing any NodeConn data to avoid locking | ||||
# and synchronization issues. Note wait_until() acquires this global lock when testing the predicate. | # and synchronization issues. Note wait_until() acquires this global lock when testing the predicate. | ||||
with mininode_lock: | with mininode_lock: | ||||
for block in node2.block_receive_map.values(): | for block in node2.block_receive_map.values(): | ||||
assert_equal(block, 1) | assert_equal(block, 1) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
ExampleTest().main() | ExampleTest().main() |