Skip to content

Commit

Permalink
Add tests for reaping-on-signal behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
yuvipanda committed Dec 26, 2018
1 parent bbc3d9e commit bf318b4
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
40 changes: 40 additions & 0 deletions tests/child_scripts/signalsupervisor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Start a child process that prints signals it receives
"""
import asyncio
import signal
import os
from functools import partial
import sys
from simpervisor import SupervisedProcess

signal_printer = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'signalprinter.py'
)

async def main():
count = int(sys.argv[1])
pids = []
for i in range(count):
proc = SupervisedProcess(f'signalprinter-{i}', *[
sys.executable,
signal_printer, '1'
])

await proc.start()
pids.append(proc.pid)

print(' '.join([str(pid) for pid in pids]), flush=True)



loop = asyncio.get_event_loop()
asyncio.ensure_future(main())
try:
loop.run_forever()
finally:
# Cleanup properly so we get a clean exit
loop.run_until_complete(asyncio.gather(*asyncio.Task.all_tasks()))
print('supervisor exiting cleanly')
loop.close()
49 changes: 49 additions & 0 deletions tests/test_signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import sys
import signal
import os
import pytest
from simpervisor import SupervisedProcess
import subprocess
import time
import errno


@pytest.mark.parametrize('childcount', [1, 5])
@pytest.mark.asyncio
async def test_sigtermreap(childcount):
"""
Test reaping subprocess after SIGTERM.
- Start a supervisor process that supervises a child.
- Send supervisor a SIGTERM
- Make sure child receives it & exits first before supervisor exiting
"""
signalsupervisor_file = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
'child_scripts',
'signalsupervisor.py'
)

proc = subprocess.Popen([sys.executable, signalsupervisor_file, str(childcount)], stdout=subprocess.PIPE)

# Give the signal handlers a bit of time to set up
time.sleep(0.5)

# Read the child's PID from signalsupervisor
child_pids = [int(l) for l in proc.stdout.readline().decode().split(' ')]

proc.send_signal(signal.SIGTERM)
proc.wait()

stdout, stderr = proc.communicate()

# Make sure the children are dead
for child_pid in child_pids:
with pytest.raises(OSError) as e:
os.kill(child_pid, 0)
assert e.value.errno == errno.ESRCH

# Test order of exit of child & parent
assert stdout.decode() == 'handler 0 received 15\n' * len(child_pids) + 'supervisor exiting cleanly\n'
# Test that our supervisor also exited cleanly
assert proc.returncode == 0

0 comments on commit bf318b4

Please sign in to comment.