Merge lp:~cjwatson/rabbitfixture/fix-kill into lp:rabbitfixture

Proposed by Colin Watson
Status: Merged
Merged at revision: 52
Proposed branch: lp:~cjwatson/rabbitfixture/fix-kill
Merge into: lp:rabbitfixture
Diff against target: 103 lines (+35/-30)
1 file modified
rabbitfixture/server.py (+35/-30)
To merge this branch: bzr merge lp:~cjwatson/rabbitfixture/fix-kill
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+397242@code.launchpad.net

Commit message

Handle SIGCHLD in RabbitServerRunner.kill too.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) wrote :

looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'rabbitfixture/server.py'
--- rabbitfixture/server.py 2021-02-01 11:14:25 +0000
+++ rabbitfixture/server.py 2021-02-01 11:49:40 +0000
@@ -12,6 +12,7 @@
12 "RabbitServerResources",12 "RabbitServerResources",
13 ]13 ]
1414
15from contextlib import contextmanager
15import errno16import errno
16import logging17import logging
17import os18import os
@@ -309,6 +310,34 @@
309 else:310 else:
310 raise Exception("RabbitMQ server is not running.")311 raise Exception("RabbitMQ server is not running.")
311312
313 @contextmanager
314 def _handle_sigchld(self):
315 # The rabbitmq-server process we're trying to stop is our direct
316 # child process, so we need to handle SIGCHLD in order for the
317 # process to go away gracefully.
318 def sigchld_handler(signum, frame):
319 while True:
320 try:
321 pid, _ = os.waitpid(-1, os.WNOHANG)
322 if not pid:
323 break
324 except OSError as e:
325 if e.errno == errno.ECHILD:
326 break
327 raise
328
329 original_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler)
330 if original_sigchld is None:
331 logging.warning(
332 "Previous SIGCHLD handler was installed by non-Python code; "
333 "will restore to default action instead.")
334 original_sigchld = signal.SIG_DFL
335
336 try:
337 yield
338 finally:
339 signal.signal(signal.SIGCHLD, original_sigchld)
340
312 def kill(self):341 def kill(self):
313 """Kill the RabbitMQ server process.342 """Kill the RabbitMQ server process.
314343
@@ -319,10 +348,11 @@
319 It is also useful to test your code against scenarios where the server348 It is also useful to test your code against scenarios where the server
320 dies.349 dies.
321 """350 """
322 self._signal(signal.SIGKILL)351 with self._handle_sigchld():
323 time.sleep(0.5)352 self._signal(signal.SIGKILL)
324 if self.is_running():353 time.sleep(0.5)
325 raise Exception("RabbitMQ server just won't die.")354 if self.is_running():
355 raise Exception("RabbitMQ server just won't die.")
326356
327 def _spawn(self):357 def _spawn(self):
328 """Spawn the RabbitMQ server process."""358 """Spawn the RabbitMQ server process."""
@@ -387,29 +417,7 @@
387417
388 def _stop(self):418 def _stop(self):
389 """Stop the running server. Normally called by cleanups."""419 """Stop the running server. Normally called by cleanups."""
390 def handle_sigchld(signum, frame):420 with self._handle_sigchld():
391 while True:
392 try:
393 pid, _ = os.waitpid(-1, os.WNOHANG)
394 if not pid:
395 break
396 except OSError as e:
397 if e.errno == errno.ECHILD:
398 break
399 raise
400
401 original_sigchld = None
402 try:
403 # The rabbitmq-server process we're trying to stop is our direct
404 # child process, so we need to handle SIGCHLD in order for the
405 # process to go away gracefully.
406 original_sigchld = signal.signal(signal.SIGCHLD, handle_sigchld)
407 if original_sigchld is None:
408 logging.warning(
409 "Previous SIGCHLD handler was installed by non-Python "
410 "code; will restore to default action instead.")
411 original_sigchld = signal.SIG_DFL
412
413 try:421 try:
414 self._request_stop()422 self._request_stop()
415 # Wait for the node to go down...423 # Wait for the node to go down...
@@ -436,9 +444,6 @@
436 # Die!!!444 # Die!!!
437 if self.is_running():445 if self.is_running():
438 self.kill()446 self.kill()
439 finally:
440 if original_sigchld is not None:
441 signal.signal(signal.SIGCHLD, original_sigchld)
442447
443 def _signal(self, code):448 def _signal(self, code):
444 """Send a signal to the server process and all its children."""449 """Send a signal to the server process and all its children."""

Subscribers

People subscribed via source and target branches

to all changes: