qa: Test scanning errors individually
What changed, and why it matters
This commit only changes a test file. It reorganizes existing wallet-scanning tests so each error condition is checked separately, rather than lumping them together. There is no change to the actual Bitcoin Core wallet code, so it does not fix or introduce a security issue in the software users run.
No action needed; this is a test-quality refactor. Reviewers may optionally verify that the new tests still exercise the intended wallet directory scanning error paths.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff modifies test/functional/wallet_multiwallet.py. It splits a previously combined test scenario into two independent test methods: test_scanning_sub_dir now checks the ‘permission denied’ case on its own with before/after baseline assertions, and a new test_scanning_symlink_levels checks the ‘too many levels of symbolic links’ case. A symlink setup is moved from the shared setup into the new symlink test. No production code is altered.
Changed components
test/functional/wallet_multiwallet.pyInspect captured patch +19 / −3
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 505138eb..b550a804 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -78,6 +78,7 @@ class MultiWalletTest(BitcoinTestFramework):
self.test_scanning_main_dir_access(node)
empty_wallet, empty_created_wallet, wallet_names, in_wallet_dir = self.test_mixed_wallets(node)
self.test_scanning_sub_dir(node, in_wallet_dir)
+ self.test_scanning_symlink_levels(node, in_wallet_dir)
self.test_init(node, wallet_names)
self.test_balances_and_fees(node, wallet_names, in_wallet_dir)
w1, w2 = self.test_loading(node, wallet_names)
@@ -114,9 +115,6 @@ class MultiWalletTest(BitcoinTestFramework):
os.symlink('..', wallet_dir(node, 'recursive_dir_symlink'))
- os.mkdir(wallet_dir(node, 'self_walletdat_symlink'))
- os.symlink('wallet.dat', wallet_dir(node, 'self_walletdat_symlink/wallet.dat'))
-
# rename wallet.dat to make sure plain wallet file paths (as opposed to
# directory paths) can be loaded
# create another dummy wallet for use in testing backups later
@@ -159,6 +157,12 @@ class MultiWalletTest(BitcoinTestFramework):
def test_scanning_sub_dir(self, node, in_wallet_dir):
self.log.info("Test scanning for sub directories")
+ # Baseline, no errors.
+ with node.assert_debug_log(expected_msgs=[], unexpected_msgs=["Error while scanning wallet dir"]):
+ walletlist = node.listwalletdir()['wallets']
+ assert_equal(sorted(map(lambda w: w['name'], walletlist)), sorted(in_wallet_dir))
+
+ # "Permission denied" error.
os.mkdir(wallet_dir(node, 'no_access'))
os.chmod(wallet_dir(node, 'no_access'), 0)
try:
@@ -167,6 +171,18 @@ class MultiWalletTest(BitcoinTestFramework):
finally:
# Need to ensure access is restored for cleanup
os.chmod(wallet_dir(node, 'no_access'), stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
+
+ # Verify that we no longer emit errors after restoring permissions
+ with node.assert_debug_log(expected_msgs=[], unexpected_msgs=["Error while scanning wallet dir"]):
+ walletlist = node.listwalletdir()['wallets']
+ assert_equal(sorted(map(lambda w: w['name'], walletlist)), sorted(in_wallet_dir))
+
+ def test_scanning_symlink_levels(self, node, in_wallet_dir):
+ self.log.info("Test for errors from too many levels of symbolic links")
+ os.mkdir(wallet_dir(node, 'self_walletdat_symlink'))
+ os.symlink('wallet.dat', wallet_dir(node, 'self_walletdat_symlink/wallet.dat'))
+ with node.assert_debug_log(expected_msgs=["Error while scanning wallet dir"]):
+ walletlist = node.listwalletdir()['wallets']
assert_equal(sorted(map(lambda w: w['name'], walletlist)), sorted(in_wallet_dir))
def test_init(self, node, wallet_names):
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.