diff --git a/test/functional/test_framework/mininode.py b/test/functional/test_framework/mininode.py --- a/test/functional/test_framework/mininode.py +++ b/test/functional/test_framework/mininode.py @@ -597,8 +597,7 @@ self.block_store[block.sha256] = block self.last_block_hash = block.sha256 - reject_reason = [reject_reason] if reject_reason else [] - with node.assert_debug_log(expected_msgs=reject_reason): + def test(): self.send_message(msg_headers([CBlockHeader(blocks[-1])])) if request_block: @@ -611,11 +610,17 @@ self.sync_with_ping(timeout=timeout) if success: - wait_until(lambda: node.getbestblockhash() - == blocks[-1].hash, timeout=timeout) + wait_until(lambda: node.getbestblockhash() == + blocks[-1].hash, timeout=timeout) else: assert node.getbestblockhash() != blocks[-1].hash + if reject_reason: + with node.assert_debug_log(expected_msgs=[reject_reason]): + test() + else: + test() + def send_txs_and_test(self, txs, node, *, success=True, expect_disconnect=False, reject_reason=None): """Send txs to test node and test whether they're accepted to the mempool. @@ -630,8 +635,7 @@ for tx in txs: self.tx_store[tx.sha256] = tx - reject_reason = [reject_reason] if reject_reason else [] - with node.assert_debug_log(expected_msgs=reject_reason): + def test(): for tx in txs: self.send_message(msg_tx(tx)) @@ -651,3 +655,9 @@ for tx in txs: assert tx.hash not in raw_mempool, "{} tx found in mempool".format( tx.hash) + + if reject_reason: + with node.assert_debug_log(expected_msgs=[reject_reason]): + test() + else: + test() diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -355,6 +355,18 @@ @contextlib.contextmanager def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2): + """Assert that some debug messages are present within some timeout. + Unexpected debug messages may be optionally provided to fail a test + if they appear before expected messages. + + Note: expected_msgs must always be non-empty even if the goal is to check + for unexpected_msgs. This provides a bounded scenario such that "we expect + to reach some target resulting in expected_msgs without seeing unexpected_msgs. + Otherwise, we are testing that something never happens, which is fundamentally + not robust test logic. + """ + if not expected_msgs: + raise AssertionError("Expected debug messages is empty") if unexpected_msgs is None: unexpected_msgs = [] time_end = time.time() + timeout