dash/test/functional/p2p-timeouts.py
Wladimir J. van der Laan feb0c4949b Merge #14733: P2P: Make peer timeout configurable, speed up very slow test and ensure correct code path tested.
48b37db50 make peertimeout a debug argument, remove error message translation (Zain Iqbal Allarakhia)
8042bbfbf p2p: allow p2ptimeout to be configurable, speed up slow test (Zain Iqbal Allarakhia)

Pull request description:

  **Summary:**

  1. _Primary_: Adds a `debug_only=true` flag for peertimeout, defaults to 60 sec., the current hard-coded setting.
  2. _Secondary_: Drastically speeds up `p2p_timeout.py` test.
  3. _Secondary_: Tests that the correct code path is being tested by adding log assertions to the test.

  **Rationale:**

  - P2P timeout was hard-coded: make it explicitly specified and configurable, instead of a magic number.
  - Addresses #13518; `p2p_timeout.py` takes 4 sec. to run instead of 61 sec.
  - Makes `p2p_timeout.py` more explicit. Previously, we relied on a comment to inform us of the timeout amount being tested. Now it is specified directly in the test via passing in the new arg; `-peertimeout=3`.
  - Opens us up to testing more P2P scenarios; oftentimes slow tests are the reason we don't test.

  **Locally verified changes:**

  _With Proposed Change (4.7 sec.):_
  ```
  $ time ./test/functional/p2p_timeouts.py
  2018-11-19T00:04:19.077000Z TestFramework (INFO): Initializing test directory /tmp/testhja7g2n7
  2018-11-19T00:04:23.479000Z TestFramework (INFO): Stopping nodes
  2018-11-19T00:04:23.683000Z TestFramework (INFO): Cleaning up /tmp/testhja7g2n7 on exit
  2018-11-19T00:04:23.683000Z TestFramework (INFO): Tests successful

  real    0m4.743s
  ```

  _Currently  on master (62.8 sec.):_
  ```
  $ time ./test/functional/p2p_timeouts.py
  2018-11-19T00:06:10.948000Z TestFramework (INFO): Initializing test directory /tmp/test6mo6k21h
  2018-11-19T00:07:13.376000Z TestFramework (INFO): Stopping nodes
  2018-11-19T00:07:13.631000Z TestFramework (INFO): Cleaning up /tmp/test6mo6k21h on exit
  2018-11-19T00:07:13.631000Z TestFramework (INFO): Tests successful

  real    1m2.836s
  ```

  _Error message demonstrated for new argument `-peertimeout`:_
  ```
  $ ./bitcoind -peertimeout=-5
  ...
  Error: peertimeout cannot be configured with a negative value.
  ```

Tree-SHA512: ff7a244ebea54c4059407bf4fb86465714e6a79cef5d2bcaa22cfe831a81761aaf597ba4d5172fc2ec12266f54712216fc41b5d24849e5d9dab39ba6f09e3a2a
2020-06-12 17:03:00 -05:00

84 lines
2.7 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (c) 2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test various net timeouts.
- Create three dashd nodes:
no_verack_node - we never send a verack in response to their version
no_version_node - we never send a version (only a ping)
no_send_node - we never send any P2P message.
- Start all three nodes
- Wait 1 second
- Assert that we're connected
- Send a ping to no_verack_node and no_version_node
- Wait 1 second
- Assert that we're still connected
- Send a ping to no_verack_node and no_version_node
- Wait 2 seconds
- Assert that we're no longer connected (timeout to receive version/verack is 3 seconds)
"""
from time import sleep
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
class TestNode(P2PInterface):
def on_version(self, message):
# Don't send a verack in response
pass
class TimeoutsTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
# set timeout to receive version/verack to 3 seconds
self.extra_args = [["-peertimeout=3"]]
def run_test(self):
# Setup the p2p connections and start up the network thread.
no_verack_node = self.nodes[0].add_p2p_connection(TestNode())
no_version_node = self.nodes[0].add_p2p_connection(TestNode(), send_version=False)
no_send_node = self.nodes[0].add_p2p_connection(TestNode(), send_version=False)
network_thread_start()
sleep(1)
assert no_verack_node.connected
assert no_version_node.connected
assert no_send_node.connected
no_verack_node.send_message(msg_ping())
no_version_node.send_message(msg_ping())
sleep(1)
assert "version" in no_verack_node.last_message
assert no_verack_node.connected
assert no_version_node.connected
assert no_send_node.connected
no_verack_node.send_message(msg_ping())
no_version_node.send_message(msg_ping())
expected_timeout_logs = [
"version handshake timeout from 0",
"socket no message in first 3 seconds, 1 0 from 1",
"socket no message in first 3 seconds, 0 0 from 2",
]
with self.nodes[0].assert_debug_log(expected_msgs=expected_timeout_logs):
sleep(2)
assert not no_verack_node.connected
assert not no_version_node.connected
assert not no_send_node.connected
if __name__ == '__main__':
TimeoutsTest().main()