diff options
author | Matthew Zipkin <pinheadmz@gmail.com> | 2023-06-21 10:41:09 -0400 |
---|---|---|
committer | Matthew Zipkin <pinheadmz@gmail.com> | 2023-09-14 12:02:01 -0400 |
commit | de8f9123afbecc3b4f59fa80af8148bc865d0588 (patch) | |
tree | 249466a9f9d2e424126ca1aa86d707856b459912 /test/functional | |
parent | 5c2185b3b624ce87320ec16412f98ab591a5860c (diff) |
test: cover read-only blockstore
Co-authored-by: Andrew Chow <github@achow101.com>
Diffstat (limited to 'test/functional')
-rwxr-xr-x | test/functional/feature_reindex_readonly.py | 64 | ||||
-rwxr-xr-x | test/functional/test_runner.py | 1 |
2 files changed, 65 insertions, 0 deletions
diff --git a/test/functional/feature_reindex_readonly.py b/test/functional/feature_reindex_readonly.py new file mode 100755 index 0000000000..9f1bb30023 --- /dev/null +++ b/test/functional/feature_reindex_readonly.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023-present The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test running bitcoind with -reindex from a read-only blockstore +- Start a node, generate blocks, then restart with -reindex after setting blk files to read-only +""" + +import platform +import stat +import subprocess +from test_framework.test_framework import BitcoinTestFramework + + +class BlockstoreReindexTest(BitcoinTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 1 + self.extra_args = [["-fastprune"]] + + def reindex_readonly(self): + self.log.debug("Generate block big enough to start second block file") + fastprune_blockfile_size = 0x10000 + opreturn = "6a" + nulldata = fastprune_blockfile_size * "ff" + self.generateblock(self.nodes[0], output=f"raw({opreturn}{nulldata})", transactions=[]) + self.stop_node(0) + + assert (self.nodes[0].chain_path / "blocks" / "blk00000.dat").exists() + assert (self.nodes[0].chain_path / "blocks" / "blk00001.dat").exists() + + self.log.debug("Make the first block file read-only") + filename = self.nodes[0].chain_path / "blocks" / "blk00000.dat" + filename.chmod(stat.S_IREAD) + + used_chattr = False + if platform.system() == "Linux": + try: + subprocess.run(['chattr', '+i', filename], capture_output=True, check=True) + used_chattr = True + self.log.info("Made file immutable with chattr") + except subprocess.CalledProcessError as e: + self.log.warning(str(e)) + if e.stdout: + self.log.warning(f"stdout: {e.stdout}") + if e.stderr: + self.log.warning(f"stderr: {e.stderr}") + + self.log.debug("Attempt to restart and reindex the node with the unwritable block file") + with self.nodes[0].assert_debug_log(expected_msgs=['FlushStateToDisk', 'failed to open file'], unexpected_msgs=[]): + self.nodes[0].assert_start_raises_init_error(extra_args=['-reindex', '-fastprune'], + expected_msg="Error: A fatal internal error occurred, see debug.log for details") + + if used_chattr: + subprocess.check_call(['chattr', '-i', filename]) + + filename.chmod(0o777) + + def run_test(self): + self.reindex_readonly() + + +if __name__ == '__main__': + BlockstoreReindexTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index db04bb8bdb..f44a5be19f 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -162,6 +162,7 @@ BASE_SCRIPTS = [ 'wallet_abandonconflict.py --legacy-wallet', 'wallet_abandonconflict.py --descriptors', 'feature_reindex.py', + 'feature_reindex_readonly.py', 'wallet_labels.py --legacy-wallet', 'wallet_labels.py --descriptors', 'p2p_compactblocks.py', |