From 2484f1a951ac85ca5364265447109ca463475685 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Wed, 2 Nov 2016 21:55:19 +0100 Subject: [PATCH] Reaping test: remove no sleep assumption The reaping test assumes that all the `sleep` processes on the system are created by us, which is an incorrect assumption, and creates problems now that we run in a more "complete" system in CI (i.e. not in a minimal container). This solves the issue by not assuming that random sleep processes are related to us: instead, we look at whether these processes are in our process group. This also includes a little clean up of the reaping stage 1. --- test/reaping/stage_1.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/test/reaping/stage_1.py b/test/reaping/stage_1.py index 10d87ab..82d62d3 100755 --- a/test/reaping/stage_1.py +++ b/test/reaping/stage_1.py @@ -8,33 +8,50 @@ import time import psutil +def in_group_or_reaped(pid): + try: + return os.getpgid(pid) == os.getpgid(0) + except OSError: + return True + + def main(): - p = subprocess.Popen([os.path.join(os.path.dirname(__file__), "stage_2.py")]) - p.wait() + stage_2 = os.path.join(os.path.dirname(__file__), "stage_2.py") + subprocess.Popen([stage_2]).wait() # In tests, we assume this process is the direct child of init this_process = psutil.Process(os.getpid()) init_process = this_process.parent() - print("Reaping test: stage_1 is pid{0}, init is pid{1}".format(this_process.pid, init_process.pid)) + print("Reaping test: stage_1 is pid{0}, init is pid{1}".format( + this_process.pid, init_process.pid)) # The only child PID that should persist is this one. expected_pids = [this_process.pid] - print("Expecting pids to remain: {0}".format(", ".join(str(pid) for pid in expected_pids))) + print("Expecting pids to remain: {0}".format( + ", ".join(str(pid) for pid in expected_pids))) while 1: pids = [p.pid for p in init_process.children(recursive=True)] print("Has pids: {0}".format(", ".join(str(pid) for pid in pids))) + for pid in pids: + assert in_group_or_reaped(pid), "Child had unexpected pgid" if set(pids) == set(expected_pids): break time.sleep(1) - # Now, check if there are any zombies + # Now, check if there are any zombies. For each of the potential zombies, + # we check that the pgid is ours. NOTE: We explicitly test that this test + # fails if subreaping is disabled, so we can be confident this doesn't turn + # a failure into a success. for process in psutil.process_iter(): - if process.name() == "sleep": - print("At least one 'sleep' process was still alive or not reaped! (pid{0})".format(process.pid)) - sys.exit(1) + if process.pid == this_process.pid: + continue + if not in_group_or_reaped(process.pid): + continue + print("Not reaped: pid {0}: {1}".format(process.pid, process.name())) + sys.exit(1) sys.exit(0)