예제 #1
0
 def check_process_termination(self, method):
     """Helper method for process termination tests."""
     timer = Timer()
     # We use Executor to launch an external process.
     with ExternalCommand('sleep', '60', check=False) as cmd:
         # Verify that proc.unix.UnixProcess.is_running (which is normally
         # overridden by proc.core.Process.is_running) works as expected,
         # even though this property isn't actively used in the `proc'
         # package because we want to deal with not-yet-reclaimed
         # processes and zombie processes which is very much a Linux
         # specific thing (hence the override).
         unix_process = UnixProcess(pid=cmd.pid)
         assert unix_process.is_running, "UnixProcess.is_running is broken!"
         # We don't use Executor to control the process, instead we take the
         # process ID and use it to create a Process object that doesn't
         # know about Python's subprocess module.
         linux_process = Process.from_pid(cmd.pid)
         # We terminate the process using a positive but very low timeout so
         # that all of the code involved gets a chance to run, but without
         # significantly slowing down the test suite.
         getattr(linux_process, method)(timeout=0.1)
         # Now we can verify our assertions.
         assert not linux_process.is_running, "Child still running despite graceful termination request!"
         assert timer.elapsed_time < 10, "It look too long to terminate the child!"
         # Now comes a hairy bit of Linux implementation details that most
         # people can thankfully ignore (blissful ignorance :-). Parent
         # processes are responsible for reclaiming child processes and
         # until this happens the /proc/[pid] entry remains, which means
         # the `kill -0' trick used by UnixProcess to detect running
         # processes doesn't work as expected. Basically this means we
         # _must_ make sure that waitpid() is called before we can expect
         # UnixProcess.is_running to behave as expected.
         cmd.wait()
         # Now that we've called waitpid() things should work as expected.
         assert not unix_process.is_running, "UnixProcess.is_running is broken!"
예제 #2
0
 def test_environ(self):
     """Test that parsing of process environments works as expected."""
     unique_value = str(random.random())
     with ExternalCommand(
             'sleep', '30',
             environment=dict(unique_value=unique_value)) as sleep_cmd:
         sleep_proc = Process.from_pid(sleep_cmd.pid)
         assert sleep_proc.environ['unique_value'] == unique_value
예제 #3
0
    def process(self):
        """
        The :class:`proc.core.Process` object for this worker process (or :data:`None`).

        If :attr:`pid` is set then the value of :attr:`process` defaults to the
        result of :func:`proc.core.Process.from_pid()`. If the worker process
        disappears before the process information is requested :attr:`process`
        will be :data:`None`.
        """
        return Process.from_pid(self.pid) if self.pid else None
예제 #4
0
 def test_wait_for_processes(self):
     """Test the :func:`proc.cron.wait_for_processes()` function."""
     children = [
         subprocess.Popen(['sleep',
                           str(int(5 + random.random() * 5))])
         for i in range(5)
     ]
     wait_for_processes([Process.from_pid(c.pid) for c in children])
     assert sum(c.poll() is None for c in children) == 0, \
         "wait_for_processes() returned before all processes ended!"
예제 #5
0
 def test_is_alive(self):
     """Test the :func:`proc.core.Process.is_alive` property."""
     # Spawn a child that will live for a minute.
     with ExternalCommand('sleep', '60', check=False) as child:
         # Construct a process object for the child.
         process = Process.from_pid(child.pid)
         # Make sure the process object agrees the child is alive.
         assert process.is_alive, "Child died before Process.is_alive was called?!"
         # Kill the child process and give it a moment to terminate
         # (significantly less time then the process is normally expected to
         # run, otherwise there's no point in the test below).
         child.terminate(timeout=10)
         # Make sure the process object agrees the child is dead.
         assert not process.is_alive, "Child is still alive even though we killed it?!"
예제 #6
0
    def verify_app(self, s):
        creds = s.getsockopt(
            SOL_SOCKET, self.SO_PEERCRED, struct.calcsize('3i'))
        pid, uid, gid = struct.unpack('3i', creds)

        proc = Process.from_pid(pid)
        file_hash = filehash.file_sha1(proc.exe)
        connected_app = SingleApp(proc.exe, file_hash)

        if (self.client_apps and connected_app in self.client_apps)  \
                or self.extra_approver(connected_app):
            return True, connected_app

        return False, None
예제 #7
0
 def test_suspend_and_resume_signals(self):
     """Test the sending of ``SIGSTOP``, ``SIGCONT`` and ``SIGTERM`` signals."""
     # Spawn a child that will live for a minute.
     with ExternalCommand('sleep', '60', check=False) as cmd:
         process = Process.from_pid(cmd.pid)
         # Suspend the execution of the child process using SIGSTOP.
         process.suspend()
         # Test that the child process doesn't respond to SIGTERM once suspended.
         process.terminate(wait=False)
         assert process.is_running, "Child responded to signal even though it was suspended?!"
         # Resume the execution of the child process using SIGCONT.
         process.resume()
         # Test that the child process responds to signals again after
         # having been resumed, but give it a moment to terminate
         # (significantly less time then the process is normally expected
         # to run, otherwise there's no point in the test below).
         process.kill(wait=True, timeout=5)
         assert not process.is_running, "Child didn't respond to signal even though it was resumed?!"
예제 #8
0
 def process(self):
     return Process.from_pid(self.pid) if self.pid else None