aboutsummaryrefslogtreecommitdiff
path: root/test/functional/test_framework
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2021-11-09 09:58:39 +0100
committerMarcoFalke <falke.marco@gmail.com>2021-11-09 09:58:51 +0100
commit94db963de501e4aba6e5d8150a01ceb85753dee1 (patch)
tree823e9d70163a42007f6f039e0585f54224669611 /test/functional/test_framework
parent49143477e774476635c65253ff4c7222df875eb3 (diff)
parentfacc352648e4fe1ed9b406400b6e4a9d51f30349 (diff)
Merge bitcoin/bitcoin#23300: test: Implicitly sync after generate*, unless opted out
facc352648e4fe1ed9b406400b6e4a9d51f30349 test: Implicitly sync after generate*, unless opted out (MarcoFalke) Pull request description: The most frequent failure in functional tests are intermittent races. Fixing such bugs is cumbersome because it involves: * Noticing the failure * Fetching and reading the log to determine the test case that failed * Adding a `self.sync_all()` where it was forgotten * Spamming out a pr and waiting for review, which is already sparse Also, writing a linter to catch those is not possible, nor is review effective in finding these bugs prior to merge. Fix all future intermittent races caused by a missing sync_block call by calling `sync_all` implicitly after each `generate*`, unless opted out. This ensures that the code is race-free (with regards to blocks) when the tests pass once, instead of our current approach where the code can never be guaranteed to be race-free. There are some scripted-diff cleanups (see https://github.com/bitcoin/bitcoin/pull/22567), but they will be submitted in a follow-up to reduce the conflicts in this pull. ACKs for top commit: lsilva01: tACK facc352 on Ubuntu 20.04 brunoerg: tACK facc352648e4fe1ed9b406400b6e4a9d51f30349 on MacOS 11.6 Tree-SHA512: 046a40a066b4a3bd28a3077bd654fa8887442dd1f0ec6fd11671865809ef02376f126eb667a1320ebd67b6e372c78c00dbf8bd25d86ed86f1d9a25363103ed97
Diffstat (limited to 'test/functional/test_framework')
-rwxr-xr-xtest/functional/test_framework/test_framework.py17
-rw-r--r--test/functional/test_framework/util.py6
2 files changed, 15 insertions, 8 deletions
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index ec3561b1f2..84d94b34f7 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -413,7 +413,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# To ensure that all nodes are out of IBD, the most recent block
# must have a timestamp not too old (see IsInitialBlockDownload()).
self.log.debug('Generate a block with current time')
- block_hash = self.generate(self.nodes[0], 1)[0]
+ block_hash = self.generate(self.nodes[0], 1, sync_fun=self.no_op)[0]
block = self.nodes[0].getblock(blockhash=block_hash, verbosity=0)
for n in self.nodes:
n.submitblock(block)
@@ -627,20 +627,27 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.connect_nodes(1, 2)
self.sync_all()
- def generate(self, generator, *args, **kwargs):
+ def no_op(self):
+ pass
+
+ def generate(self, generator, *args, sync_fun=None, **kwargs):
blocks = generator.generate(*args, invalid_call=False, **kwargs)
+ sync_fun() if sync_fun else self.sync_all()
return blocks
- def generateblock(self, generator, *args, **kwargs):
+ def generateblock(self, generator, *args, sync_fun=None, **kwargs):
blocks = generator.generateblock(*args, invalid_call=False, **kwargs)
+ sync_fun() if sync_fun else self.sync_all()
return blocks
- def generatetoaddress(self, generator, *args, **kwargs):
+ def generatetoaddress(self, generator, *args, sync_fun=None, **kwargs):
blocks = generator.generatetoaddress(*args, invalid_call=False, **kwargs)
+ sync_fun() if sync_fun else self.sync_all()
return blocks
- def generatetodescriptor(self, generator, *args, **kwargs):
+ def generatetodescriptor(self, generator, *args, sync_fun=None, **kwargs):
blocks = generator.generatetodescriptor(*args, invalid_call=False, **kwargs)
+ sync_fun() if sync_fun else self.sync_all()
return blocks
def sync_blocks(self, nodes=None, wait=1, timeout=60):
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 0678e2e6fe..ca1ffd48de 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -463,10 +463,10 @@ def find_output(node, txid, amount, *, blockhash=None):
# Helper to create at least "count" utxos
# Pass in a fee that is sufficient for relay and mining new transactions.
-def create_confirmed_utxos(test_framework, fee, node, count):
+def create_confirmed_utxos(test_framework, fee, node, count, **kwargs):
to_generate = int(0.5 * count) + 101
while to_generate > 0:
- test_framework.generate(node, min(25, to_generate))
+ test_framework.generate(node, min(25, to_generate), **kwargs)
to_generate -= 25
utxos = node.listunspent()
iterations = count - len(utxos)
@@ -487,7 +487,7 @@ def create_confirmed_utxos(test_framework, fee, node, count):
node.sendrawtransaction(signed_tx)
while (node.getmempoolinfo()['size'] > 0):
- test_framework.generate(node, 1)
+ test_framework.generate(node, 1, **kwargs)
utxos = node.listunspent()
assert len(utxos) >= count