In the course of coming up with a test plan for #23280, I thought it would be neat to include a Python snippet showing how I tested the initialization process. I quickly realized I was reinventing the functional test framework… so here’s a new test.
This change bangs init around like the Fonz hitting a jukebox. It adds some interesting (read: lazy and random) coverage for the initialization process by
- interrupting init with SIGTERM after certain log statements,
- interrupting init at random points, and
- starting init with some essential data missing (block files, block indices, etc.) to test init error paths.
As far as I can tell, some of these code paths are uncovered otherwise (namely the startup errors).
Incidentally, I think I may have uncovered some kind of a bug or race condition with indexing initialization based on an intermittent failure in this testcase. This test sometimes fails after shutting down immediately after loadblk thread start:
02021-10-15T21:14:51.295000Z TestFramework (INFO): Starting node and will exit after line 'loadblk thread start'
1  36   │ 2021-10-15T21:14:51.296000Z TestFramework.node0 (DEBUG): bitcoind started, waiting for RPC to come up
2  37   │ 2021-10-15T21:14:51.493000Z TestFramework (INFO): terminating node after 110 log lines seen
3  38   │ 2021-10-15T21:14:51.625000Z TestFramework (INFO): Starting node and will exit after line 'txindex thread start'
4  39   │ 2021-10-15T21:14:51.625000Z TestFramework.node0 (DEBUG): bitcoind started, waiting for RPC to come up
5  ------> [[ FAILURE HERE ]] 2021-10-15T21:15:21.626000Z TestFramework (WARNING): missed line {bail_line}; bailing now after {num_lines} lines
and then fails to start up afterwards. Combined logs showing Error: txindex best block of the index goes beyond pruned data, when the node under test is not pruned:
 0  node0 2021-10-15T21:16:51.848439Z [shutoff] [validationinterface.cpp:244] [ChainStateFlushed] Enqueuing ChainStateFlushed: block hash=1014bc4ff4917602ae53d10e9dfe230af4b7d52a6cdaa8a47798b9c288180907
 1   node0 2021-10-15T21:16:51.848954Z [shutoff] [init.cpp:302] [Shutdown] Shutdown: done
 2   test  2021-10-15T21:16:51.882000Z TestFramework (ERROR): Unexpected exception caught during testing
 3				     Traceback (most recent call last):
 4				       File "/home/james/src/bitcoin/test/functional/test_framework/test_framework.py", line 132, in main
 5					 self.run_test()
 6				       File "/home/james/src/bitcoin/./test/functional/stress_init.py", line 87, in run_test
 7					 check_clean_start()
 8				       File "/home/james/src/bitcoin/./test/functional/stress_init.py", line 60, in check_clean_start
 9					 node.wait_for_rpc_connection()
10				       File "/home/james/src/bitcoin/test/functional/test_framework/test_node.py", line 224, in wait_for_rpc_connection
11					 raise FailedToStartError(self._node_msg(
12				     test_framework.test_node.FailedToStartError: [node 0] bitcoind exited with status 1 during initialization
13   test  2021-10-15T21:16:51.882000Z TestFramework (DEBUG): Closing down network thread
14   test  2021-10-15T21:16:51.933000Z TestFramework (INFO): Stopping nodes
15   test  2021-10-15T21:16:51.933000Z TestFramework.node0 (DEBUG): Stopping node
16
17   node0 stderr Error: txindex best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)
18   node0 stderr Error: txindex best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)
19   node0 stderr Error: txindex best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)
20   node0 stderr Error: txindex best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)
21   node0 stderr Error: txindex best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)