@@ -228,59 +228,70 @@ def mock_start_new_thread(func, *args, **kwargs):
228228 list (executor .map (mul , [(2 , 3 )] * 10 ))
229229 executor .shutdown ()
230230
231- def test_process_pool_executor_terminate_workers (self ):
232- manager = multiprocessing .Manager ()
233- q = manager .Queue ()
231+ def test_process_pool_executor_terminate_kill_workers (self ):
232+ for function_name in ('terminate_workers' , 'kill_workers' ):
233+ manager = multiprocessing .Manager ()
234+ q = manager .Queue ()
234235
235- with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
236- executor .submit (_put_sleep_put , q )
236+ with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
237+ executor .submit (_put_sleep_put , q )
237238
238- # We should get started, but not finished since we'll terminate the workers just after
239- self .assertEqual (q .get (timeout = 1 ), 'started' )
239+ # We should get started, but not finished since we'll terminate the workers just after
240+ self .assertEqual (q .get (timeout = 1 ), 'started' )
240241
241- executor . terminate_workers ()
242+ getattr ( executor , function_name ) ()
242243
243- self .assertRaises (queue .Empty , q .get , timeout = 1 )
244+ self .assertRaises (queue .Empty , q .get , timeout = 1 )
244245
245- def test_process_pool_executor_terminate_workers_dead_workers (self ):
246- with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
247- future = executor .submit (os ._exit , 1 )
248- self .assertRaises (BrokenProcessPool , future .result )
246+ def test_process_pool_executor_terminate_kill_workers_dead_workers (self ):
247+ for function_name in ('terminate_workers' , 'kill_workers' ):
248+ with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
249+ future = executor .submit (os ._exit , 1 )
250+ self .assertRaises (BrokenProcessPool , future .result )
249251
250- @unittest .mock .patch ('concurrent.futures.process.os.kill' )
251- def test_process_pool_executor_terminate_workers_not_started_yet (self , mock_kill ):
252- with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
253- # The worker has not been started yet, terminate_workers should basically no-op
254- executor .terminate_workers ()
252+ # even though the pool is broken, this shouldn't raise
253+ getattr (executor , function_name )()
255254
256- mock_kill .assert_not_called ()
255+ def test_process_pool_executor_terminate_kill_workers_not_started_yet (self ):
256+ for function_name in ('terminate_workers' , 'kill_workers' ):
257257
258- def test_process_pool_executor_terminate_workers_stops_pool (self ):
259- with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
260- executor .submit (time .sleep , 0 ).result ()
258+ context_with_mocked_process = multiprocessing .get_context ()
259+ with unittest .mock .patch .object (context_with_mocked_process , 'Process' ) as mock_process :
261260
262- executor .terminate_workers ()
261+ with futures .ProcessPoolExecutor (max_workers = 1 , mp_context = context_with_mocked_process ) as executor :
262+ # The worker has not been started yet, terminate/kill_workers should basically no-op
263+ getattr (executor , function_name )()
264+
265+ mock_process .return_value .kill .assert_not_called ()
266+ mock_process .return_value .terminate .assert_not_called ()
263267
264- self .assertRaises (RuntimeError , executor .submit , time .sleep , 0 )
268+ def test_process_pool_executor_terminate_kill_workers_stops_pool (self ):
269+ for function_name in ('terminate_workers' , 'kill_workers' ):
270+ with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
271+ executor .submit (time .sleep , 0 ).result ()
265272
266- @unittest .mock .patch ('concurrent.futures.process.os.kill' )
267- def test_process_pool_executor_terminate_workers_passes_signal (self , mock_kill ):
273+ getattr (executor , function_name )()
274+
275+ self .assertRaises (RuntimeError , executor .submit , time .sleep , 0 )
276+
277+ def test_process_pool_executor_terminate_workers (self ):
268278 with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
269- future = executor .submit (time .sleep , 0 )
270- future .result ()
279+ executor ._terminate_or_kill_workers = unittest .mock .Mock ()
280+ executor .terminate_workers ()
281+
282+ executor ._terminate_or_kill_workers .assert_called_once_with (operation = futures .process ._TerminateOrKillOperation .TERMINATE )
271283
272- worker_process = list (executor ._processes .values ())[0 ]
273- executor .terminate_workers (signal .SIGABRT )
284+ def test_process_pool_executor_kill_workers (self ):
285+ with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
286+ executor ._terminate_or_kill_workers = unittest .mock .Mock ()
287+ executor .kill_workers ()
274288
275- mock_kill . assert_called_once_with (worker_process . pid , signal . SIGABRT )
289+ executor . _terminate_or_kill_workers . assert_called_once_with (operation = futures . process . _TerminateOrKillOperation . KILL )
276290
277- def test_process_pool_executor_terminate_workers_passes_even_bad_signals (self ):
291+ def test_process_pool_executor_terminate_or_kill_workers_invalid_operation (self ):
278292 with futures .ProcessPoolExecutor (max_workers = 1 ) as executor :
279- future = executor .submit (time .sleep , 0 )
280- future .result ()
293+ self .assertRaises (ValueError , executor ._terminate_or_kill_workers , operation = 'invalid operation' ),
281294
282- # 'potatoes' isn't a valid signal, so os.kill will raise a TypeError
283- self .assertRaises (TypeError , executor .terminate_workers , 'potatoes' )
284295
285296
286297create_executor_tests (globals (), ProcessPoolExecutorTest ,
0 commit comments