Skip to content

Commit d27b9a2

Browse files
committed
test: fix feature_init.py file perturbation
Simultaneously opening the file in read and write mode would lead to opening of an empty file instead of perturbing the existing file. Also, revert to the previous state after each perturbation so that each perturbation is applied in isolation.
1 parent ad66ca1 commit d27b9a2

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

test/functional/feature_init.py

+19-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""Stress tests related to node initialization."""
66
import os
77
from pathlib import Path
8+
import shutil
89

910
from test_framework.test_framework import BitcoinTestFramework, SkipTest
1011
from test_framework.test_node import ErrorMatch
@@ -47,7 +48,7 @@ def sigterm_node():
4748

4849
def start_expecting_error(err_fragment):
4950
node.assert_start_raises_init_error(
50-
extra_args=['-txindex=1', '-blockfilterindex=1', '-coinstatsindex=1'],
51+
extra_args=['-txindex=1', '-blockfilterindex=1', '-coinstatsindex=1', '-checkblocks=200', '-checklevel=4'],
5152
expected_msg=err_fragment,
5253
match=ErrorMatch.PARTIAL_REGEX,
5354
)
@@ -101,9 +102,9 @@ def check_clean_start():
101102
}
102103

103104
files_to_perturb = {
104-
'blocks/index/*.ldb': 'Error opening block database.',
105+
'blocks/index/*.ldb': 'Error loading block database.',
105106
'chainstate/*.ldb': 'Error opening block database.',
106-
'blocks/blk*.dat': 'Error opening block database.',
107+
'blocks/blk*.dat': 'Corrupted block database detected.',
107108
}
108109

109110
for file_patt, err_fragment in files_to_delete.items():
@@ -124,18 +125,31 @@ def check_clean_start():
124125
check_clean_start()
125126
self.stop_node(0)
126127

128+
self.log.info("Test startup errors after perturbing certain essential files")
127129
for file_patt, err_fragment in files_to_perturb.items():
130+
shutil.copytree(node.chain_path / "blocks", node.chain_path / "blocks_bak")
131+
shutil.copytree(node.chain_path / "chainstate", node.chain_path / "chainstate_bak")
128132
target_files = list(node.chain_path.glob(file_patt))
129133

130134
for target_file in target_files:
131135
self.log.info(f"Perturbing file to ensure failure {target_file}")
132-
with open(target_file, "rb") as tf_read, open(target_file, "wb") as tf_write:
136+
with open(target_file, "rb") as tf_read:
133137
contents = tf_read.read()
134138
tweaked_contents = bytearray(contents)
135-
tweaked_contents[50:250] = b'1' * 200
139+
# Since the genesis block is not checked by -checkblocks, the
140+
# perturbation window must be chosen such that a higher block
141+
# in blk*.dat is affected.
142+
tweaked_contents[150:350] = b'1' * 200
143+
with open(target_file, "wb") as tf_write:
136144
tf_write.write(bytes(tweaked_contents))
137145

138146
start_expecting_error(err_fragment)
139147

148+
shutil.rmtree(node.chain_path / "blocks")
149+
shutil.rmtree(node.chain_path / "chainstate")
150+
shutil.move(node.chain_path / "blocks_bak", node.chain_path / "blocks")
151+
shutil.move(node.chain_path / "chainstate_bak", node.chain_path / "chainstate")
152+
153+
140154
if __name__ == '__main__':
141155
InitStressTest().main()

0 commit comments

Comments
 (0)