test: add coverage for loading a wallet in a non-writable directory

Previously, wallets in non-writable directories were loaded,
leading to crashes on any subsequent write.
This commit is contained in:
furszy
2026-01-03 12:37:45 -05:00
parent 0218966c0d
commit 08925d5ee7

View File

@@ -6,12 +6,17 @@
Verify that a bitcoind node can maintain list of wallets loading on startup
"""
import os
import shutil
import stat
import uuid
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
is_dir_writable,
)
@@ -38,6 +43,27 @@ class WalletStartupTest(BitcoinTestFramework):
shutil.move(self.nodes[0].wallets_path / wallet_name / "wallet.dat", self.nodes[0].wallets_path / "wallet.dat")
(self.nodes[0].wallets_path / wallet_name).rmdir()
def test_load_unwritable_wallet(self, node):
self.log.info("Test wallet load failure due to non-writable directory")
wallet_name = "bad_permissions"
node.createwallet(wallet_name)
node.unloadwallet(wallet_name)
dir_path = node.wallets_path / wallet_name
original_dir_perms = dir_path.stat().st_mode
os.chmod(dir_path, original_dir_perms & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
if is_dir_writable(dir_path):
self.log.warning("Skipping load non-writable directory test: unable to enforce read-only permissions")
else:
# Ensure we don't load a wallet located in a non-writable directory.
# The node will crash later on if we cannot write to disk.
assert_raises_rpc_error(-4, f"SQLiteDatabase: Failed to open database in directory '{str(dir_path)}': directory is not writable", node.loadwallet, wallet_name)
# Reset directory permissions for cleanup
dir_path.chmod(original_dir_perms)
def run_test(self):
self.log.info('Should start without any wallets')
assert_equal(self.nodes[0].listwallets(), [])
@@ -67,5 +93,7 @@ class WalletStartupTest(BitcoinTestFramework):
self.restart_node(0)
assert_equal(set(self.nodes[0].listwallets()), set(('w2', 'w3')))
self.test_load_unwritable_wallet(self.nodes[0])
if __name__ == '__main__':
WalletStartupTest(__file__).main()