@@ -93,15 +93,19 @@ def gunicorn_server(app_module):
9393 '--access-logfile' , '-' ,
9494 '--error-logfile' , '-' ,
9595 '--log-level' , 'info' ,
96+ '--timeout' , '30' ,
97+ '--graceful-timeout' , '30' ,
9698 app_name
9799 ]
98100
101+ # Use setsid to create new process group for proper signal handling
99102 proc = subprocess .Popen (
100103 cmd ,
101104 cwd = app_dir ,
102105 stdout = subprocess .PIPE ,
103106 stderr = subprocess .PIPE ,
104- env = {** os .environ , 'PYTHONPATH' : app_dir }
107+ env = {** os .environ , 'PYTHONPATH' : app_dir },
108+ preexec_fn = os .setsid
105109 )
106110
107111 # Wait for server to start
@@ -113,13 +117,19 @@ def gunicorn_server(app_module):
113117
114118 yield proc , port
115119
116- # Cleanup
120+ # Cleanup - use process group kill for better cleanup
117121 if proc .poll () is None :
118- proc .terminate ()
122+ try :
123+ os .killpg (os .getpgid (proc .pid ), signal .SIGTERM )
124+ except (ProcessLookupError , OSError ):
125+ pass
119126 try :
120127 proc .wait (timeout = 5 )
121128 except subprocess .TimeoutExpired :
122- proc .kill ()
129+ try :
130+ os .killpg (os .getpgid (proc .pid ), signal .SIGKILL )
131+ except (ProcessLookupError , OSError ):
132+ pass
123133 proc .wait ()
124134
125135
@@ -141,8 +151,11 @@ def test_graceful_shutdown_sigterm(self, gunicorn_server):
141151 response = make_request ('127.0.0.1' , port )
142152 assert b'Hello, World!' in response
143153
144- # Send SIGTERM
145- proc .send_signal (signal .SIGTERM )
154+ # Send SIGTERM to the process group for reliable signal delivery
155+ try :
156+ os .killpg (os .getpgid (proc .pid ), signal .SIGTERM )
157+ except (ProcessLookupError , OSError ):
158+ proc .send_signal (signal .SIGTERM )
146159
147160 # Wait for process to exit
148161 try :
@@ -160,8 +173,11 @@ def test_graceful_shutdown_sigint(self, gunicorn_server):
160173 response = make_request ('127.0.0.1' , port )
161174 assert b'Hello, World!' in response
162175
163- # Send SIGINT
164- proc .send_signal (signal .SIGINT )
176+ # Send SIGINT to the process group for reliable signal delivery
177+ try :
178+ os .killpg (os .getpgid (proc .pid ), signal .SIGINT )
179+ except (ProcessLookupError , OSError ):
180+ proc .send_signal (signal .SIGINT )
165181
166182 # Wait for process to exit
167183 try :
@@ -179,7 +195,7 @@ def test_sighup_reload(self, gunicorn_server):
179195 response = make_request ('127.0.0.1' , port )
180196 assert b'Hello, World!' in response
181197
182- # Send SIGHUP
198+ # Send SIGHUP to the master process (not process group - only master handles reload)
183199 proc .send_signal (signal .SIGHUP )
184200
185201 # Wait a moment for reload
0 commit comments