Skip to content

Commit 2742c34

Browse files
brakmicMarcoFalke
andcommitted
test: add factor option to adjust test timeouts
Co-authored-by: MarcoFalke <[email protected]>
1 parent eef90c1 commit 2742c34

File tree

5 files changed

+30
-20
lines changed

5 files changed

+30
-20
lines changed

ci/test/00_setup_env_native_valgrind.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export NO_DEPENDS=1
1313
if [[ "${TRAVIS}" == "true" && "${TRAVIS_REPO_SLUG}" != "bitcoin/bitcoin" ]]; then
1414
export TEST_RUNNER_EXTRA="wallet_disable" # Only run wallet_disable as a smoke test to not hit the 50 min travis time limit
1515
else
16-
export TEST_RUNNER_EXTRA="--exclude rpc_bind" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
16+
export TEST_RUNNER_EXTRA="--exclude rpc_bind --factor=2" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
1717
fi
1818
export GOAL="install"
1919
export BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --with-gui=no CC=clang CXX=clang++" # TODO enable GUI

test/functional/test_framework/mininode.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ def __init__(self):
117117
def is_connected(self):
118118
return self._transport is not None
119119

120-
def peer_connect(self, dstaddr, dstport, *, net):
120+
def peer_connect(self, dstaddr, dstport, *, net, factor):
121121
assert not self.is_connected
122+
self.factor = factor
122123
self.dstaddr = dstaddr
123124
self.dstport = dstport
124125
# The initial message to send after the connection was made:
@@ -364,9 +365,12 @@ def on_version(self, message):
364365

365366
# Connection helper methods
366367

368+
def wait_until(self, test_function, timeout):
369+
wait_until(test_function, timeout=timeout, lock=mininode_lock, factor=self.factor)
370+
367371
def wait_for_disconnect(self, timeout=60):
368372
test_function = lambda: not self.is_connected
369-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
373+
self.wait_until(test_function, timeout=timeout)
370374

371375
# Message receiving helper methods
372376

@@ -377,14 +381,14 @@ def test_function():
377381
return False
378382
return self.last_message['tx'].tx.rehash() == txid
379383

380-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
384+
self.wait_until(test_function, timeout=timeout)
381385

382386
def wait_for_block(self, blockhash, timeout=60):
383387
def test_function():
384388
assert self.is_connected
385389
return self.last_message.get("block") and self.last_message["block"].block.rehash() == blockhash
386390

387-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
391+
self.wait_until(test_function, timeout=timeout)
388392

389393
def wait_for_header(self, blockhash, timeout=60):
390394
def test_function():
@@ -394,7 +398,7 @@ def test_function():
394398
return False
395399
return last_headers.headers[0].rehash() == int(blockhash, 16)
396400

397-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
401+
self.wait_until(test_function, timeout=timeout)
398402

399403
def wait_for_merkleblock(self, blockhash, timeout=60):
400404
def test_function():
@@ -404,7 +408,7 @@ def test_function():
404408
return False
405409
return last_filtered_block.merkleblock.header.rehash() == int(blockhash, 16)
406410

407-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
411+
self.wait_until(test_function, timeout=timeout)
408412

409413
def wait_for_getdata(self, hash_list, timeout=60):
410414
"""Waits for a getdata message.
@@ -418,7 +422,7 @@ def test_function():
418422
return False
419423
return [x.hash for x in last_data.inv] == hash_list
420424

421-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
425+
self.wait_until(test_function, timeout=timeout)
422426

423427
def wait_for_getheaders(self, timeout=60):
424428
"""Waits for a getheaders message.
@@ -432,7 +436,7 @@ def test_function():
432436
assert self.is_connected
433437
return self.last_message.get("getheaders")
434438

435-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
439+
self.wait_until(test_function, timeout=timeout)
436440

437441
def wait_for_inv(self, expected_inv, timeout=60):
438442
"""Waits for an INV message and checks that the first inv object in the message was as expected."""
@@ -445,13 +449,13 @@ def test_function():
445449
self.last_message["inv"].inv[0].type == expected_inv[0].type and \
446450
self.last_message["inv"].inv[0].hash == expected_inv[0].hash
447451

448-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
452+
self.wait_until(test_function, timeout=timeout)
449453

450454
def wait_for_verack(self, timeout=60):
451455
def test_function():
452456
return self.message_count["verack"]
453457

454-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
458+
self.wait_until(test_function, timeout=timeout)
455459

456460
# Message sending helper functions
457461

@@ -467,7 +471,7 @@ def test_function():
467471
assert self.is_connected
468472
return self.last_message.get("pong") and self.last_message["pong"].nonce == self.ping_counter
469473

470-
wait_until(test_function, timeout=timeout, lock=mininode_lock)
474+
self.wait_until(test_function, timeout=timeout)
471475
self.ping_counter += 1
472476

473477

@@ -583,15 +587,15 @@ def send_blocks_and_test(self, blocks, node, *, success=True, force_send=False,
583587
self.send_message(msg_block(block=b))
584588
else:
585589
self.send_message(msg_headers([CBlockHeader(block) for block in blocks]))
586-
wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout, lock=mininode_lock)
590+
self.wait_until(lambda: blocks[-1].sha256 in self.getdata_requests, timeout=timeout)
587591

588592
if expect_disconnect:
589593
self.wait_for_disconnect(timeout=timeout)
590594
else:
591595
self.sync_with_ping(timeout=timeout)
592596

593597
if success:
594-
wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout)
598+
self.wait_until(lambda: node.getbestblockhash() == blocks[-1].hash, timeout=timeout)
595599
else:
596600
assert node.getbestblockhash() != blocks[-1].hash
597601

test/functional/test_framework/test_framework.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def __init__(self):
101101
self.bind_to_localhost_only = True
102102
self.set_test_params()
103103
self.parse_args()
104+
self.rpc_timeout = int(self.rpc_timeout * self.options.factor) # optionally, increase timeout by a factor
104105

105106
def main(self):
106107
"""Main function. This should not be overridden by the subclass test scripts."""
@@ -167,6 +168,7 @@ def parse_args(self):
167168
help="set a random seed for deterministically reproducing a previous test run")
168169
parser.add_argument("--descriptors", default=False, action="store_true",
169170
help="Run test using a descriptor wallet")
171+
parser.add_argument('--factor', type=float, default=1.0, help='adjust test timeouts by a factor')
170172
self.add_options(parser)
171173
self.options = parser.parse_args()
172174

@@ -412,6 +414,7 @@ def add_nodes(self, num_nodes, extra_args=None, *, rpchost=None, binary=None, bi
412414
chain=self.chain,
413415
rpchost=rpchost,
414416
timewait=self.rpc_timeout,
417+
factor=self.options.factor,
415418
bitcoind=binary[i],
416419
bitcoin_cli=binary_cli[i],
417420
version=versions[i],
@@ -558,6 +561,7 @@ def _initialize_chain(self):
558561
extra_args=['-disablewallet'],
559562
rpchost=None,
560563
timewait=self.rpc_timeout,
564+
factor=self.options.factor,
561565
bitcoind=self.options.bitcoind,
562566
bitcoin_cli=self.options.bitcoincli,
563567
coverage_dir=None,

test/functional/test_framework/test_node.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class TestNode():
6262
To make things easier for the test writer, any unrecognised messages will
6363
be dispatched to the RPC connection."""
6464

65-
def __init__(self, i, datadir, *, chain, rpchost, timewait, bitcoind, bitcoin_cli, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False, use_valgrind=False, version=None, descriptors=False):
65+
def __init__(self, i, datadir, *, chain, rpchost, timewait, factor, bitcoind, bitcoin_cli, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False, use_valgrind=False, version=None, descriptors=False):
6666
"""
6767
Kwargs:
6868
start_perf (bool): If True, begin profiling the node with `perf` as soon as
@@ -128,6 +128,7 @@ def __init__(self, i, datadir, *, chain, rpchost, timewait, bitcoind, bitcoin_cl
128128
self.perf_subprocesses = {}
129129

130130
self.p2ps = []
131+
self.factor = factor
131132

132133
AddressKeyPair = collections.namedtuple('AddressKeyPair', ['address', 'key'])
133134
PRIV_KEYS = [
@@ -324,13 +325,13 @@ def is_node_stopped(self):
324325
return True
325326

326327
def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT):
327-
wait_until(self.is_node_stopped, timeout=timeout)
328+
wait_until(self.is_node_stopped, timeout=timeout, factor=self.factor)
328329

329330
@contextlib.contextmanager
330331
def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2):
331332
if unexpected_msgs is None:
332333
unexpected_msgs = []
333-
time_end = time.time() + timeout
334+
time_end = time.time() + timeout * self.factor
334335
debug_log = os.path.join(self.datadir, self.chain, 'debug.log')
335336
with open(debug_log, encoding='utf-8') as dl:
336337
dl.seek(0, 2)
@@ -487,7 +488,7 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
487488
if 'dstaddr' not in kwargs:
488489
kwargs['dstaddr'] = '127.0.0.1'
489490

490-
p2p_conn.peer_connect(**kwargs, net=self.chain)()
491+
p2p_conn.peer_connect(**kwargs, net=self.chain, factor=self.factor)()
491492
self.p2ps.append(p2p_conn)
492493
if wait_for_verack:
493494
# Wait for the node to send us the version and verack

test/functional/test_framework/util.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,10 @@ def str_to_b64str(string):
208208
def satoshi_round(amount):
209209
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
210210

211-
def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), lock=None):
211+
def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), lock=None, factor=1.0):
212212
if attempts == float('inf') and timeout == float('inf'):
213213
timeout = 60
214+
timeout = timeout * factor
214215
attempt = 0
215216
time_end = time.time() + timeout
216217

@@ -265,7 +266,7 @@ def get_rpc_proxy(url, node_number, *, timeout=None, coveragedir=None):
265266
"""
266267
proxy_kwargs = {}
267268
if timeout is not None:
268-
proxy_kwargs['timeout'] = timeout
269+
proxy_kwargs['timeout'] = int(timeout)
269270

270271
proxy = AuthServiceProxy(url, **proxy_kwargs)
271272
proxy.url = url # store URL on proxy for info

0 commit comments

Comments
 (0)