aboutsummaryrefslogtreecommitdiff
path: root/test/functional/feature_init.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/feature_init.py')
-rwxr-xr-xtest/functional/feature_init.py54
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"