diff options
Diffstat (limited to 'test/functional/feature_init.py')
-rwxr-xr-x | test/functional/feature_init.py | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/test/functional/feature_init.py b/test/functional/feature_init.py index 4a2f7ecf42..8a936fc0a5 100755 --- a/test/functional/feature_init.py +++ b/test/functional/feature_init.py @@ -4,10 +4,13 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Tests related to node initialization.""" from pathlib import Path +import os import platform import shutil +import signal +import subprocess -from test_framework.test_framework import BitcoinTestFramework, SkipTest +from test_framework.test_framework import BitcoinTestFramework from test_framework.test_node import ( BITCOIN_PID_FILENAME_DEFAULT, ErrorMatch, @@ -33,20 +36,17 @@ class InitTest(BitcoinTestFramework): - test terminating initialization after seeing a certain log line. - test removing certain essential files to test startup error paths. """ - # TODO: skip Windows for now since it isn't clear how to SIGTERM. - # - # Windows doesn't support `process.terminate()`. - # and other approaches (like below) don't work: - # - # os.kill(node.process.pid, signal.CTRL_C_EVENT) - if platform.system() == 'Windows': - raise SkipTest("can't SIGTERM on Windows") - self.stop_node(0) node = self.nodes[0] def sigterm_node(): - node.process.terminate() + if platform.system() == 'Windows': + # Don't call Python's terminate() since it calls + # TerminateProcess(), which unlike SIGTERM doesn't allow + # bitcoind to perform any shutdown logic. + os.kill(node.process.pid, signal.CTRL_BREAK_EVENT) + else: + node.process.terminate() node.process.wait() def start_expecting_error(err_fragment): @@ -86,10 +86,16 @@ class InitTest(BitcoinTestFramework): if self.is_wallet_compiled(): lines_to_terminate_after.append(b'Verifying wallet') + args = ['-txindex=1', '-blockfilterindex=1', '-coinstatsindex=1'] for terminate_line in lines_to_terminate_after: - self.log.info(f"Starting node and will exit after line {terminate_line}") + self.log.info(f"Starting node and will terminate after line {terminate_line}") with node.busy_wait_for_debug_log([terminate_line]): - node.start(extra_args=['-txindex=1', '-blockfilterindex=1', '-coinstatsindex=1']) + if platform.system() == 'Windows': + # CREATE_NEW_PROCESS_GROUP is required in order to be able + # to terminate the child without terminating the test. + node.start(extra_args=args, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) + else: + node.start(extra_args=args) self.log.debug("Terminating node after terminate line was found") sigterm_node() @@ -102,12 +108,22 @@ class InitTest(BitcoinTestFramework): 'blocks/index/*.ldb': 'Error opening block database.', 'chainstate/*.ldb': 'Error opening coins database.', 'blocks/blk*.dat': 'Error loading block database.', + 'indexes/txindex/MANIFEST*': 'LevelDB error: Corruption: CURRENT points to a non-existent file', + # Removing these files does not result in a startup error: + # 'indexes/blockfilter/basic/*.dat', 'indexes/blockfilter/basic/db/*.*', 'indexes/coinstats/db/*.*', + # 'indexes/txindex/*.log', 'indexes/txindex/CURRENT', 'indexes/txindex/LOCK' } files_to_perturb = { 'blocks/index/*.ldb': 'Error loading block database.', 'chainstate/*.ldb': 'Error opening coins database.', 'blocks/blk*.dat': 'Corrupted block database detected.', + 'indexes/blockfilter/basic/db/*.*': 'LevelDB error: Corruption', + 'indexes/coinstats/db/*.*': 'LevelDB error: Corruption', + 'indexes/txindex/*.log': 'LevelDB error: Corruption', + 'indexes/txindex/CURRENT': 'LevelDB error: Corruption', + # Perturbing these files does not result in a startup error: + # 'indexes/blockfilter/basic/*.dat', 'indexes/txindex/MANIFEST*', 'indexes/txindex/LOCK' } for file_patt, err_fragment in files_to_delete.items(): @@ -129,9 +145,10 @@ class InitTest(BitcoinTestFramework): self.stop_node(0) self.log.info("Test startup errors after perturbing certain essential files") + dirs = ["blocks", "chainstate", "indexes"] for file_patt, err_fragment in files_to_perturb.items(): - shutil.copytree(node.chain_path / "blocks", node.chain_path / "blocks_bak") - shutil.copytree(node.chain_path / "chainstate", node.chain_path / "chainstate_bak") + for dir in dirs: + shutil.copytree(node.chain_path / dir, node.chain_path / f"{dir}_bak") target_files = list(node.chain_path.glob(file_patt)) for target_file in target_files: @@ -145,10 +162,9 @@ class InitTest(BitcoinTestFramework): start_expecting_error(err_fragment) - shutil.rmtree(node.chain_path / "blocks") - shutil.rmtree(node.chain_path / "chainstate") - shutil.move(node.chain_path / "blocks_bak", node.chain_path / "blocks") - shutil.move(node.chain_path / "chainstate_bak", node.chain_path / "chainstate") + for dir in dirs: + shutil.rmtree(node.chain_path / dir) + shutil.move(node.chain_path / f"{dir}_bak", node.chain_path / dir) def init_pid_test(self): BITCOIN_PID_FILENAME_CUSTOM = "my_fancy_bitcoin_pid_file.foobar" |