github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/tini/test/reaping/stage_1.py (about)

     1  #!/usr/bin/env python3
     2  import os
     3  import sys
     4  import subprocess
     5  import time
     6  
     7  import psutil
     8  
     9  
    10  def in_group_or_reaped(pid):
    11      try:
    12          return os.getpgid(pid) == os.getpgid(0)
    13      except OSError:
    14          return True
    15  
    16  
    17  def main():
    18      stage_2 = os.path.join(os.path.dirname(__file__), "stage_2.py")
    19      subprocess.Popen([stage_2]).wait()
    20  
    21      # In tests, we assume this process is the direct child of init
    22      this_process = psutil.Process(os.getpid())
    23      init_process = this_process.parent()
    24  
    25      print("Reaping test: stage_1 is pid{0}, init is pid{1}".format(
    26          this_process.pid, init_process.pid))
    27  
    28      # The only child PID that should persist is this one.
    29      expected_pids = [this_process.pid]
    30  
    31      print("Expecting pids to remain: {0}".format(
    32          ", ".join(str(pid) for pid in expected_pids)))
    33  
    34      while 1:
    35          pids = [p.pid for p in init_process.children(recursive=True)]
    36          print("Has pids: {0}".format(", ".join(str(pid) for pid in pids)))
    37          for pid in pids:
    38              assert in_group_or_reaped(pid), "Child had unexpected pgid"
    39          if set(pids) == set(expected_pids):
    40              break
    41          time.sleep(1)
    42  
    43      # Now, check if there are any zombies. For each of the potential zombies,
    44      # we check that the pgid is ours.  NOTE: We explicitly test that this test
    45      # fails if subreaping is disabled, so we can be confident this doesn't turn
    46      # a failure into a success.
    47      for process in psutil.process_iter():
    48          if process.pid == this_process.pid:
    49              continue
    50          if not in_group_or_reaped(process.pid):
    51              continue
    52          print("Not reaped: pid {0}: {1}".format(process.pid, process.name()))
    53          sys.exit(1)
    54  
    55      sys.exit(0)
    56  
    57  
    58  if __name__ == "__main__":
    59      main()