Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/mininode.py
Show First 20 Lines • Show All 431 Lines • ▼ Show 20 Lines | class P2PInterface(P2PConnection): | ||||
def wait_for_disconnect(self, timeout=60): | def wait_for_disconnect(self, timeout=60): | ||||
def test_function(): return not self.is_connected | def test_function(): return not self.is_connected | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
# Message receiving helper methods | # Message receiving helper methods | ||||
def wait_for_tx(self, txid, timeout=60): | def wait_for_tx(self, txid, timeout=60): | ||||
def test_function(): | def test_function(): | ||||
assert self.is_connected | |||||
if not self.last_message.get('tx'): | if not self.last_message.get('tx'): | ||||
return False | return False | ||||
return self.last_message['tx'].tx.rehash() == txid | return self.last_message['tx'].tx.rehash() == txid | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
def wait_for_block(self, blockhash, timeout=60): | def wait_for_block(self, blockhash, timeout=60): | ||||
def test_function(): return self.last_message.get( | def test_function(): | ||||
assert self.is_connected | |||||
return self.last_message.get( | |||||
"block") and self.last_message["block"].block.rehash() == blockhash | "block") and self.last_message["block"].block.rehash() == blockhash | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
def wait_for_header(self, blockhash, timeout=60): | def wait_for_header(self, blockhash, timeout=60): | ||||
def test_function(): | def test_function(): | ||||
assert self.is_connected | |||||
last_headers = self.last_message.get('headers') | last_headers = self.last_message.get('headers') | ||||
if not last_headers: | if not last_headers: | ||||
return False | return False | ||||
return last_headers.headers[0].rehash() == int(blockhash, 16) | return last_headers.headers[0].rehash() == int(blockhash, 16) | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
def wait_for_merkleblock(self, blockhash, timeout=60): | def wait_for_merkleblock(self, blockhash, timeout=60): | ||||
def test_function(): | def test_function(): | ||||
assert self.is_connected | assert self.is_connected | ||||
last_filtered_block = self.last_message.get('merkleblock') | last_filtered_block = self.last_message.get('merkleblock') | ||||
if not last_filtered_block: | if not last_filtered_block: | ||||
return False | return False | ||||
return last_filtered_block.merkleblock.header.rehash() == int(blockhash, 16) | return last_filtered_block.merkleblock.header.rehash() == int(blockhash, 16) | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
def wait_for_getdata(self, timeout=60): | def wait_for_getdata(self, timeout=60): | ||||
"""Waits for a getdata message. | """Waits for a getdata message. | ||||
Receiving any getdata message will satisfy the predicate. the last_message["getdata"] | Receiving any getdata message will satisfy the predicate. the last_message["getdata"] | ||||
value must be explicitly cleared before calling this method, or this will return | value must be explicitly cleared before calling this method, or this will return | ||||
immediately with success. TODO: change this method to take a hash value and only | immediately with success. TODO: change this method to take a hash value and only | ||||
return true if the correct block/tx has been requested.""" | return true if the correct block/tx has been requested.""" | ||||
def test_function(): return self.last_message.get("getdata") | |||||
def test_function(): | |||||
assert self.is_connected | |||||
return self.last_message.get("getdata") | |||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
def wait_for_getheaders(self, timeout=60): | def wait_for_getheaders(self, timeout=60): | ||||
"""Waits for a getheaders message. | """Waits for a getheaders message. | ||||
Receiving any getheaders message will satisfy the predicate. the last_message["getheaders"] | Receiving any getheaders message will satisfy the predicate. the last_message["getheaders"] | ||||
value must be explicitly cleared before calling this method, or this will return | value must be explicitly cleared before calling this method, or this will return | ||||
immediately with success. TODO: change this method to take a hash value and only | immediately with success. TODO: change this method to take a hash value and only | ||||
return true if the correct block header has been requested.""" | return true if the correct block header has been requested.""" | ||||
def test_function(): return self.last_message.get("getheaders") | |||||
def test_function(): | |||||
assert self.is_connected | |||||
return self.last_message.get("getheaders") | |||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | 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.""" | ||||
if len(expected_inv) > 1: | if len(expected_inv) > 1: | ||||
raise NotImplementedError( | raise NotImplementedError( | ||||
"wait_for_inv() will only verify the first inv object") | "wait_for_inv() will only verify the first inv object") | ||||
def test_function(): return self.last_message.get("inv") and \ | def test_function(): | ||||
assert self.is_connected | |||||
return 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 | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
def wait_for_verack(self, timeout=60): | def wait_for_verack(self, timeout=60): | ||||
def test_function(): return self.message_count["verack"] | def test_function(): | ||||
return self.message_count["verack"] | |||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
# Message sending helper functions | # Message sending helper functions | ||||
def send_and_ping(self, message, timeout=60): | def send_and_ping(self, message, timeout=60): | ||||
self.send_message(message) | self.send_message(message) | ||||
self.sync_with_ping(timeout=timeout) | self.sync_with_ping(timeout=timeout) | ||||
# Sync up with the node | # Sync up with the node | ||||
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)) | ||||
def test_function(): | def test_function(): | ||||
if not self.last_message.get("pong"): | assert self.is_connected | ||||
return False | return self.last_message.get( | ||||
return self.last_message["pong"].nonce == self.ping_counter | "pong") and self.last_message["pong"].nonce == self.ping_counter | ||||
wait_until(test_function, timeout=timeout, lock=mininode_lock) | wait_until(test_function, timeout=timeout, lock=mininode_lock) | ||||
self.ping_counter += 1 | self.ping_counter += 1 | ||||
# One lock for synchronizing all data access between the networking thread (see | # One lock for synchronizing all data access between the networking thread (see | ||||
# NetworkThread below) and the thread running the test logic. For simplicity, | # NetworkThread below) and the thread running the test logic. For simplicity, | ||||
# P2PConnection acquires this lock whenever delivering a message to a P2PInterface. | # P2PConnection acquires this lock whenever delivering a message to a P2PInterface. | ||||
# This lock should be acquired in the thread running the test logic to synchronize | # This lock should be acquired in the thread running the test logic to synchronize | ||||
▲ Show 20 Lines • Show All 175 Lines • Show Last 20 Lines |