Esempio n. 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!"
Esempio n. 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
    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
Esempio n. 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!"
Esempio n. 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?!"
Esempio n. 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
Esempio n. 7
0
 def test_process_from_path(self):
     """Test the :func:`proc.core.Process.from_path()` constructor."""
     process = Process.from_path('/proc/self')
     # The following tests verify properties based on information available
     # from the Python standard library.
     assert process.pid == os.getpid(), "Unexpected process ID!"
     assert process.ppid == os.getppid(), "Unexpected parent process ID!"
     assert process.pgrp == os.getpgrp(), "Unexpected process group ID!"
     assert process.user_ids.real == os.getuid(), "Unexpected real user ID!"
     assert process.group_ids.real == os.getgid(
     ), "Unexpected real group ID!"
     assert process.cwd == os.getcwd(), "Unexpected working directory!"
     # The following assertion may fail at some point, but I chose it above
     # using uid_to_name(os.getuid()) because the latter isn't testing
     # anything useful at all ...
     assert process.user == getpass.getuser(
     ), "Unexpected username based on real user ID!"
     # We really can't make much assumptions about the name of the real
     # group ID so we'll just check whether it's available.
     assert process.group, "Expected process to have real group ID with group name!"
     # The following tests are based on common sense, here's hoping they
     # don't bite me in the ass later on :-).
     assert process.state == 'R', "Unexpected process state!"
     assert process.runtime < 600, "Test process running for >= 10 minutes?!"
     assert process.rss > parse_size(
         '10 MB'), "Resident set size (RSS) less than 10 MB?!"
     assert process.vsize > process.rss, "Virtual memory usage less than its resident set size (RSS)?!"
     assert executable(process.cmdline[0]) or which(process.cmdline[0]), \
         "First token in process command line isn't executable?!"
     assert executable(
         process.exe
     ), "Process executable pathname (based on /proc/[pid]/stat) invalid?!"
     assert executable(
         process.exe_path
     ), "Process executable pathname (fall back option) invalid?!"
     if not (os.environ.get('TRAVIS') and process.exe_name == 'pypy'):
         # https://travis-ci.org/xolox/python-proc/jobs/395176218
         assert which(
             process.exe_name
         ), "Process executable base name (fall back option) not available on $PATH?!"
     assert process.is_alive, "The current process is not running?! :-P"
     # Python's standard library doesn't seem to expose process session IDs
     # so all I can test reliably is that the session ID is an integer...
     assert isinstance(process.session,
                       int), "Process session ID not available!"
Esempio n. 8
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?!"
Esempio n. 9
0
 def process(self):
     return Process.from_pid(self.pid) if self.pid else None