@@ -134,10 +134,10 @@ def test_cancel_event():
134134
135135def test_cancellable_sleep ():
136136 """Check the module-level cancellable sleep."""
137- with pytest . raises ( exc . NoInvocationContextError ):
138- ic . cancellable_sleep ( 1 )
139- with pytest . raises ( exc . NoInvocationContextError ):
140- ic .cancellable_sleep (None )
137+ # with no invocation context, the function should wait
138+ # and there should be no error.
139+ with assert_takes_time ( 0.02 , 0.04 ):
140+ ic .cancellable_sleep (0.02 )
141141
142142 with ic .fake_invocation_context ():
143143 event = ic .get_cancel_event ()
@@ -146,20 +146,30 @@ def test_cancellable_sleep():
146146 with assert_takes_time (0.02 , 0.04 ):
147147 ic .cancellable_sleep (0.02 )
148148
149- # passing `None` should return immediately.
150- with assert_takes_time (None , 0.002 ):
151- ic .cancellable_sleep (None )
152-
153149 # check an exception gets raised and reset if appropriate
154150 event .set ()
155151 with pytest .raises (exc .InvocationCancelledError ):
156152 ic .cancellable_sleep (1 )
157153 assert not event .is_set ()
158154
155+
156+ def test_raise_if_cancelled ():
157+ """Check the module-level cancellable sleep."""
158+ # the function should return immediately.
159+ with assert_takes_time (None , 0.002 ):
160+ ic .raise_if_cancelled ()
161+
162+ with ic .fake_invocation_context ():
163+ event = ic .get_cancel_event ()
164+
165+ # the function should return immediately.
166+ with assert_takes_time (None , 0.002 ):
167+ ic .raise_if_cancelled ()
168+
159169 # check an exception gets raised and reset if appropriate
160170 event .set ()
161171 with pytest .raises (exc .InvocationCancelledError ):
162- ic .cancellable_sleep ( None )
172+ ic .raise_if_cancelled ( )
163173 assert not event .is_set ()
164174
165175
@@ -179,19 +189,6 @@ def test_invocation_logger():
179189 assert logger .name .endswith (str (id ))
180190
181191
182- def run_function_in_thread_and_propagate_cancellation (func , * args ):
183- """Run a function in a ThreadWithInvocationID."""
184- t = ic .ThreadWithInvocationID (target = func , args = args )
185- t .start ()
186- try :
187- t .join_and_propagate_cancel (0.005 )
188- except exc .InvocationCancelledError :
189- # We still want to return the finished thread if it's
190- # cancelled.
191- pass
192- return t
193-
194-
195192def test_thread_with_invocation_id ():
196193 """Test our custom thread subclass makes a new ID and can be cancelled."""
197194 ids = []
@@ -204,6 +201,9 @@ def test_thread_with_invocation_id():
204201 assert t .exception is None
205202 assert t .result is None
206203
204+
205+ def test_thread_with_invocation_id_cancel ():
206+ """Test the custom thread subclass responds to cancellation."""
207207 # Check cancellable sleep works in the thread
208208 t = ic .ThreadWithInvocationID (target = ic .cancellable_sleep , args = [1 ])
209209 assert isinstance (t .invocation_id , uuid .UUID )
@@ -213,20 +213,43 @@ def test_thread_with_invocation_id():
213213 t .join ()
214214 assert isinstance (t .exception , exc .InvocationCancelledError )
215215
216- # Check we capture the return value
216+
217+ def test_thread_with_invocation_id_return_value ():
218+ """Check we capture the return value when running in a ThreadWithInvocationID."""
217219 t = ic .ThreadWithInvocationID (target = lambda : True )
218220 t .start ()
219221 t .join ()
220222 assert t .exception is None
221223 assert t .result is True
222224
225+
226+ def run_function_in_thread_and_propagate_cancellation (func , * args ):
227+ """Run a function in a ThreadWithInvocationID."""
228+ t = ic .ThreadWithInvocationID (target = func , args = args )
229+ t .start ()
230+ try :
231+ t .join_and_propagate_cancel (1 )
232+ except exc .InvocationCancelledError :
233+ # We still want to return the finished thread if it's
234+ # cancelled.
235+ pass
236+ return t
237+
238+
239+ def test_thread_with_invocation_id_cancellation_propagates ():
240+ """Check that a cancel event can propagate to our thread.
241+
242+ ``join_and_propagate_cancellation`` should cancel the spawned thread if
243+ the parent thread is cancelled while it's waiting for the spawned thread
244+ to join.
245+ """
223246 # Check we can propagate cancellation.
224247 # First, we run `cancellable_sleep` and check it doesn't cancel
225248 with ic .fake_invocation_context ():
226249 # First test our function - there is only one thread here, and we
227250 # check it finishes and doesn't error.
228251 t = run_function_in_thread_and_propagate_cancellation (
229- ic .cancellable_sleep , 0.001
252+ ic .cancellable_sleep , 0.02
230253 )
231254 assert isinstance (t , ic .ThreadWithInvocationID )
232255 assert not t .is_alive ()
0 commit comments