Skip to content

Commit 483fb8d

Browse files
committed
Merge bitcoin/bitcoin#27287: test: Replace threading with concurrent.futures
fa0696e test: Replace threading with concurrent.futures (MarcoFalke) Pull request description: `threading` has no easy way to get the return value or exception once the target function stops. Not checking the return value or exception can make tests more fragile and failures harder to debug. Fix this by checking the return value (or exception) by wrapping the function execution into a future and calling `result()` on it. Can be reviewed with `--ignore-all-space`. (There are still some uses of `threading` around, because some tests do expect an exception to be thrown and caught in the target function) ACKs for top commit: ishaanam: ACK fa0696e stickies-v: ACK fa0696e Tree-SHA512: d9ddf6b3c530cd8c485a030a3c84d4e03d3e9f9ea8240b050afcd566a884f5cabe816ac56910cec9ea9fa299239e5abb99e672dda05a74974f61bb68dc3c1d65
2 parents 8acfb1f + fa0696e commit 483fb8d

File tree

2 files changed

+30
-32
lines changed

2 files changed

+30
-32
lines changed

test/functional/wallet_importdescriptors.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
- `test_address()` is called to call getaddressinfo for an address on node1
1616
and test the values returned."""
1717

18-
import threading
18+
import concurrent.futures
1919

2020
from test_framework.authproxy import JSONRPCException
2121
from test_framework.blocktools import COINBASE_MATURITY
@@ -691,25 +691,24 @@ def run_test(self):
691691
descriptor["next_index"] = 0
692692

693693
encrypted_wallet.walletpassphrase("passphrase", 99999)
694-
t = threading.Thread(target=encrypted_wallet.importdescriptors, args=([descriptor],))
694+
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as thread:
695+
with self.nodes[0].assert_debug_log(expected_msgs=["Rescan started from block 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206... (slow variant inspecting all blocks)"], timeout=5):
696+
importing = thread.submit(encrypted_wallet.importdescriptors, requests=[descriptor])
695697

696-
with self.nodes[0].assert_debug_log(expected_msgs=[f'Rescan started from block 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206... (slow variant inspecting all blocks)'], timeout=5):
697-
t.start()
698+
# Set the passphrase timeout to 1 to test that the wallet remains unlocked during the rescan
699+
self.nodes[0].cli("-rpcwallet=encrypted_wallet").walletpassphrase("passphrase", 1)
698700

699-
# Set the passphrase timeout to 1 to test that the wallet remains unlocked during the rescan
700-
self.nodes[0].cli("-rpcwallet=encrypted_wallet").walletpassphrase("passphrase", 1)
701+
try:
702+
self.nodes[0].cli("-rpcwallet=encrypted_wallet").walletlock()
703+
except JSONRPCException as e:
704+
assert e.error["code"] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before locking the wallet." in e.error["message"]
701705

702-
try:
703-
self.nodes[0].cli("-rpcwallet=encrypted_wallet").walletlock()
704-
except JSONRPCException as e:
705-
assert e.error['code'] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before locking the wallet." in e.error['message']
706+
try:
707+
self.nodes[0].cli("-rpcwallet=encrypted_wallet").walletpassphrasechange("passphrase", "newpassphrase")
708+
except JSONRPCException as e:
709+
assert e.error["code"] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before changing the passphrase." in e.error["message"]
706710

707-
try:
708-
self.nodes[0].cli("-rpcwallet=encrypted_wallet").walletpassphrasechange("passphrase", "newpassphrase")
709-
except JSONRPCException as e:
710-
assert e.error['code'] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before changing the passphrase." in e.error['message']
711-
712-
t.join()
711+
assert_equal(importing.result(), [{"success": True}])
713712

714713
assert_equal(temp_wallet.getbalance(), encrypted_wallet.getbalance())
715714

test/functional/wallet_transactiontime_rescan.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""Test transaction time during old block rescanning
66
"""
77

8-
import threading
8+
import concurrent.futures
99
import time
1010

1111
from test_framework.authproxy import JSONRPCException
@@ -201,25 +201,24 @@ def run_test(self):
201201
encrypted_wallet.walletpassphrase("passphrase", 99999)
202202
encrypted_wallet.sethdseed(seed=hd_seed)
203203

204-
t = threading.Thread(target=encrypted_wallet.rescanblockchain)
204+
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as thread:
205+
with minernode.assert_debug_log(expected_msgs=["Rescan started from block 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206... (slow variant inspecting all blocks)"], timeout=5):
206+
rescanning = thread.submit(encrypted_wallet.rescanblockchain)
205207

206-
with minernode.assert_debug_log(expected_msgs=[f'Rescan started from block 0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206... (slow variant inspecting all blocks)'], timeout=5):
207-
t.start()
208+
# set the passphrase timeout to 1 to test that the wallet remains unlocked during the rescan
209+
minernode.cli("-rpcwallet=encrypted_wallet").walletpassphrase("passphrase", 1)
208210

209-
# set the passphrase timeout to 1 to test that the wallet remains unlocked during the rescan
210-
minernode.cli("-rpcwallet=encrypted_wallet").walletpassphrase("passphrase", 1)
211+
try:
212+
minernode.cli("-rpcwallet=encrypted_wallet").walletlock()
213+
except JSONRPCException as e:
214+
assert e.error["code"] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before locking the wallet." in e.error["message"]
211215

212-
try:
213-
minernode.cli("-rpcwallet=encrypted_wallet").walletlock()
214-
except JSONRPCException as e:
215-
assert e.error['code'] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before locking the wallet." in e.error['message']
216+
try:
217+
minernode.cli("-rpcwallet=encrypted_wallet").walletpassphrasechange("passphrase", "newpassphrase")
218+
except JSONRPCException as e:
219+
assert e.error["code"] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before changing the passphrase." in e.error["message"]
216220

217-
try:
218-
minernode.cli("-rpcwallet=encrypted_wallet").walletpassphrasechange("passphrase", "newpassphrase")
219-
except JSONRPCException as e:
220-
assert e.error['code'] == -4 and "Error: the wallet is currently being used to rescan the blockchain for related transactions. Please call `abortrescan` before changing the passphrase." in e.error['message']
221-
222-
t.join()
221+
assert_equal(rescanning.result(), {"start_height": 0, "stop_height": 803})
223222

224223
assert_equal(encrypted_wallet.getbalance(), temp_wallet.getbalance())
225224

0 commit comments

Comments
 (0)