44# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55"""Test the IPC (multiprocess) interface."""
66import asyncio
7- import http .client
8- import re
97
108from contextlib import ExitStack
119from test_framework .test_framework import BitcoinTestFramework
@@ -86,9 +84,9 @@ async def async_routine():
8684
8785 def run_unclean_disconnect_test (self ):
8886 """Test behavior when disconnecting during an IPC call that later
89- returns a non-null interface pointer. Currently this behavior causes a
90- crash as reported https://github.com/bitcoin/bitcoin/issues/34250, but a
91- followup will change this behavior. """
87+ returns a non-null interface pointer. This used to cause a crash as
88+ reported https://github.com/bitcoin/bitcoin/issues/34250, but now just
89+ results in a cancellation log message """
9290 node = self .nodes [0 ]
9391 self .log .info ("Running disconnect during BlockTemplate.waitNext" )
9492 timeout = self .rpc_timeout * 1000.0
@@ -110,28 +108,22 @@ async def async_routine():
110108 with node .assert_debug_log (expected_msgs = ["BlockTemplate.waitNext" , "IPC server post request" ], timeout = 2 ):
111109 promise = template .waitNext (ctx , waitoptions )
112110 await asyncio .sleep (0.1 )
113- disconnected_log_check .enter_context (node .assert_debug_log (expected_msgs = ["IPC server: socket disconnected" ], timeout = 2 ))
111+ disconnected_log_check .enter_context (node .assert_debug_log (expected_msgs = ["IPC server: socket disconnected" , "canceled while executing" ], timeout = 2 ))
114112 del promise
115113
116114 asyncio .run (capnp .run (async_routine ()))
117115
118116 # Wait for socket disconnected log message, then generate a block to
119- # cause the waitNext() call to return a new template. This will cause a
120- # crash and disconnect with error output .
121- disconnected_log_check . close ()
122- try :
117+ # cause the waitNext() call to return a new template. Look for a
118+ # canceled IPC log message after waitNext returns .
119+ with node . assert_debug_log ( expected_msgs = [ "interrupted (canceled)" ]):
120+ disconnected_log_check . close ()
123121 self .generate (node , 1 )
124- except (http .client .RemoteDisconnected , BrokenPipeError , ConnectionResetError ):
125- pass
126- node .wait_until_stopped (expected_ret_code = (- 11 , - 6 , 1 , 66 ), expected_stderr = re .compile ("" ))
127- self .start_node (0 )
128122
129123 def run_thread_busy_test (self ):
130124 """Test behavior when sending multiple calls to the same server thread
131125 which used to cause a crash as reported
132- https://github.com/bitcoin/bitcoin/issues/33923 and currently causes a
133- thread busy error. A future change will make this just queue the calls
134- for execution and not trigger any error"""
126+ https://github.com/bitcoin/bitcoin/issues/33923."""
135127 node = self .nodes [0 ]
136128 self .log .info ("Running thread busy test" )
137129 timeout = self .rpc_timeout * 1000.0
@@ -151,27 +143,26 @@ async def async_routine():
151143 waitoptions .feeThreshold = 1
152144
153145 # Make multiple waitNext calls where the first will start to
154- # execute, the second will be posted waiting to execute, and the
155- # third will fail to execute because the execution thread is busy.
146+ # execute, and the second and third will be posted waiting to
147+ # execute. Previously, the third call would fail calling
148+ # mp::Waiter::post() because the waiting function slot is occupied,
149+ # but now posts are queued.
156150 with node .assert_debug_log (expected_msgs = ["BlockTemplate.waitNext" , "IPC server post request" ], timeout = 2 ):
157151 promise1 = template .waitNext (ctx , waitoptions )
158152 await asyncio .sleep (0.1 )
159153 with node .assert_debug_log (expected_msgs = ["BlockTemplate.waitNext" , "IPC server post request" ], timeout = 2 ):
160154 promise2 = template .waitNext (ctx , waitoptions )
161155 await asyncio .sleep (0.1 )
162- try :
163- await template .waitNext (ctx , waitoptions )
164- except capnp .lib .capnp .KjException as e :
165- assert_equal (e .description , "remote exception: std::exception: thread busy" )
166- assert_equal (e .type , "FAILED" )
167- else :
168- raise AssertionError ("Expected thread busy exception" )
156+ with node .assert_debug_log (expected_msgs = ["BlockTemplate.waitNext" , "IPC server post request" ], timeout = 2 ):
157+ promise3 = template .waitNext (ctx , waitoptions )
158+ await asyncio .sleep (0.1 )
169159
170160 # Generate a new block to make the active waitNext calls return, then clean up.
171161 with node .assert_debug_log (expected_msgs = ["IPC server send response" ], timeout = 2 ):
172162 self .generate (node , 1 , sync_fun = self .no_op )
173163 await ((await promise1 ).result ).destroy (ctx )
174164 await ((await promise2 ).result ).destroy (ctx )
165+ await ((await promise3 ).result ).destroy (ctx )
175166 await template .destroy (ctx )
176167
177168 asyncio .run (capnp .run (async_routine ()))
0 commit comments