def test_pid_0_exists_or_not() -> None: # Make sure that all interfaces report that PID 0 either # exists or doesn't exist. if pypsutil.pid_exists(0): # PID 0 shows up assert 0 in pypsutil.pids() pypsutil.Process(0) for proc in pypsutil.process_iter(): if proc.pid == 0: break else: raise ValueError("PID 0 not found") for proc in pypsutil.process_iter_available(): if proc.pid == 0: break else: raise ValueError("PID 0 not found") else: # PID 0 doesn't show up assert 0 not in pypsutil.pids() with pytest.raises(pypsutil.NoSuchProcess): pypsutil.Process(0) for proc in pypsutil.process_iter(): assert proc.pid != 0 for proc in pypsutil.process_iter_available(): assert proc.pid != 0
def test_num_threads_cur() -> None: with managed_background_thread(): nthreads = threading.active_count() assert nthreads >= 2 assert pypsutil.Process().num_threads() == nthreads proc = pypsutil.Process() with proc.oneshot(): assert proc.num_threads() == nthreads
def test_open_files_bad_fdinfo(tmp_path: pathlib.Path) -> None: populate_directory( str(tmp_path), { "2": { "stat": "2 (kthreadd) S 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 20 0 1 0 9 0 0 " "18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 " "0", "fd": { "0": ["/bin/sh"], "1": ["/bin/ls"], "2": ["/bin/cat"], }, "fdinfo": { "0": "pos: 10\nmnt_id: 33\nflags: 02\n", "1": "pos: 10\nmnt_id: 33\n", }, }, }, ) # Only file 0 shows up because 1 and 2 have bad fdinfo entries with replace_info_directories(procfs=str(tmp_path)): assert pypsutil.Process(2).open_files() == [ pypsutil.ProcessOpenFile(path="/bin/sh", fd=0, position=10, flags=os.O_RDWR) ]
def test_priority() -> None: proc = pypsutil.Process() assert proc.getpriority() == proc.getpriority() # Should succeed proc.setpriority(proc.getpriority())
def test_parents() -> None: proc = pypsutil.Process() for parent in proc.parents(): proc = proc.parent() # type: ignore assert proc == parent assert proc.parent() is None
def test_basic_info_pid_0() -> None: try: proc = pypsutil.Process(0) except pypsutil.NoSuchProcess: pytest.skip("PID 0 does not appear") assert proc.pgid() == 0 assert proc.sid() == 0
def test_proc_cpu_times_self() -> None: proc = pypsutil.Process() cpu_times: pypsutil.ProcessCPUTimes = proc.cpu_times() os_times = os.times() assert math.isclose(cpu_times.user, os_times.user, abs_tol=0.05) assert math.isclose(cpu_times.system, os_times.system, abs_tol=0.05)
def test_sigmasks_simple() -> None: proc = pypsutil.Process() sigmasks = proc.sigmasks() assert signal.SIGINT in sigmasks.caught check_sigmasks(sigmasks)
def test_proc_ctx_switches_self() -> None: pre_ru = resource.getrusage(resource.RUSAGE_SELF) ctx = pypsutil.Process().num_ctx_switches() post_ru = resource.getrusage(resource.RUSAGE_SELF) pre_rctx = pre_ru.ru_nvcsw + pre_ru.ru_nivcsw post_rctx = post_ru.ru_nvcsw + post_ru.ru_nivcsw assert pre_rctx <= ctx <= post_rctx
def test_proc_getrlimit() -> None: proc = pypsutil.Process() assert proc.getrlimit(resource.RLIMIT_NOFILE) == resource.getrlimit(resource.RLIMIT_NOFILE) with proc.oneshot(): assert proc.getrlimit(resource.RLIMIT_NOFILE) == resource.getrlimit( resource.RLIMIT_NOFILE )
def test_gids() -> None: proc = pypsutil.Process() if hasattr(os, "getresgid"): assert proc.gids() == os.getresgid() # pylint: disable=no-member else: rgid, egid, _ = proc.gids() assert rgid == os.getgid() assert egid == os.getegid()
def get_dead_process() -> pypsutil.Process: subproc = subprocess.Popen([sys.executable, "-c", "exit()"]) try: proc = pypsutil.Process(subproc.pid) finally: subproc.wait() return proc
def get_dead_process() -> pypsutil.Process: subproc = subprocess.Popen( # pylint: disable=consider-using-with [sys.executable, "-c", "exit()"]) try: proc = pypsutil.Process(subproc.pid) finally: subproc.wait() return proc
def test_priority_pid_0() -> None: try: proc = pypsutil.Process(0) except pypsutil.NoSuchProcess: pytest.skip("PID 0 does not appear") # If it does, we shouldn't be able to send it signals with pytest.raises(pypsutil.AccessDenied): proc.send_signal(signal.SIGINT)
def test_memory_percent() -> None: proc = pypsutil.Process() proc_meminfo = proc.memory_info() sys_meminfo = pypsutil.virtual_memory() proc_rss_pct = proc.memory_percent() assert math.isclose(proc_meminfo.rss * 100.0 / sys_meminfo.total, proc_rss_pct, abs_tol=0.1)
def test_memory_percent_error() -> None: proc = get_dead_process() with pytest.raises(pypsutil.NoSuchProcess): proc.memory_percent("rss") proc = pypsutil.Process() with pytest.raises(ValueError, match="memory type"): proc.memory_percent("__class__") with pytest.raises(ValueError, match="memory type"): proc.memory_percent("BADTYPE")
def managed_child_process(args: List[str], **kwargs: Any) -> Iterator[pypsutil.Process]: subproc = subprocess.Popen(args, **kwargs) psproc = pypsutil.Process(subproc.pid) try: yield psproc finally: if psproc.is_running(): subproc.terminate() subproc.wait()
def test_memory_maps_grouped() -> None: # pylint: disable=no-member mmaps = { os.path.realpath(mmap.path): mmap for mmap in pypsutil.Process().memory_maps_grouped() } exe_mmap = mmaps[os.path.realpath(sys.executable)] exe_stat = os.stat(sys.executable) assert exe_stat.st_ino == exe_mmap.ino assert exe_stat.st_dev == exe_mmap.dev
def test_proc_rlimit() -> None: limits = resource.getrlimit(resource.RLIMIT_NOFILE) proc = pypsutil.Process() assert proc.rlimit(resource.RLIMIT_NOFILE) == limits assert proc.rlimit(resource.RLIMIT_NOFILE, limits) == limits with proc.oneshot(): assert proc.rlimit(resource.RLIMIT_NOFILE) == limits assert proc.rlimit(resource.RLIMIT_NOFILE, limits) == limits
def test_repr() -> None: cur_proc = pypsutil.Process() assert repr( cur_proc ) == "Process(pid={}, name={!r}, status={!r}, started={!r})".format( cur_proc.pid, cur_proc.name(), cur_proc.status().value, # type: ignore[attr-defined] format_create_time(cur_proc.create_time()), )
def managed_zombie_process() -> Iterator[pypsutil.Process]: subproc = subprocess.Popen([sys.executable, "-c", "exit()"]) psproc = pypsutil.Process(subproc.pid) while psproc.status() != pypsutil.ProcessStatus.ZOMBIE: time.sleep(0.01) try: yield psproc finally: subproc.wait()
def test_priority_pid_0() -> None: try: proc = pypsutil.Process(0) except pypsutil.NoSuchProcess: pytest.skip("PID 0 does not appear") else: # If it does, we should be able to get its priority prio = proc.getpriority() # But not set it with pytest.raises(pypsutil.AccessDenied): proc.setpriority(prio)
def test_proc_connections() -> None: existing_conn_fds = { conn.fd for conn in pypsutil.Process().connections("all") } with open_testing_sockets() as test_socks: conns = pypsutil.Process().connections("all") verify_connections( test_socks, [conn for conn in conns if conn.fd not in existing_conn_fds]) with open_testing_sockets(families=[socket.AF_INET]) as test_socks: conns = pypsutil.Process().connections("inet") verify_connections( test_socks, [conn for conn in conns if conn.fd not in existing_conn_fds]) with open_testing_sockets(families=[socket.AF_INET, socket.AF_INET6], types=[socket.SOCK_DGRAM]) as test_socks: conns = pypsutil.Process().connections("udp") verify_connections( test_socks, [conn for conn in conns if conn.fd not in existing_conn_fds]) with open_testing_sockets(families=[socket.AF_UNIX]) as test_socks: conns = pypsutil.Process().connections("unix") verify_connections( test_socks, [conn for conn in conns if conn.fd not in existing_conn_fds]) conns = pypsutil.Process().connections("unix") verify_connections( {}, [conn for conn in conns if conn.fd not in existing_conn_fds])
def test_iter_fds_epoll(tmp_path: pathlib.Path) -> None: # pylint: disable=invalid-name,no-member proc = pypsutil.Process() os.mkfifo(tmp_path / "fifo") with select.epoll() as epoll, managed_pipe() as (r, w), open( tmp_path / "fifo", "r", opener=lambda path, flags: os.open(path, flags | os.O_NONBLOCK )) as fifo: epoll.register(r, select.EPOLLIN) epoll.register(w, select.EPOLLOUT) epoll.register(fifo.fileno(), select.EPOLLIN) epoll = epoll.fileno() fifo = fifo.fileno() pfds = {pfd.fd: pfd for pfd in proc.iter_fds()} st = os.fstat(epoll) assert pfds[epoll].rdev in (st.st_rdev, None) assert pfds[epoll].dev in (st.st_dev, None) assert pfds[epoll].ino in (st.st_ino, None) assert pfds[epoll].position == 0 assert pfds[epoll].flags & os.O_CLOEXEC == os.O_CLOEXEC assert not pfds[epoll].path assert pfds[epoll].fdtype == pypsutil.ProcessFdType.EPOLL assert pfds[r].fdtype == pypsutil.ProcessFdType.PIPE assert pfds[w].fdtype == pypsutil.ProcessFdType.PIPE tfds = pfds[epoll].extra_info["tfds"] assert tfds[r]["pos"] == 0 assert tfds[r][ "events"] == select.EPOLLIN | select.EPOLLERR | select.EPOLLHUP assert tfds[r]["ino"] == pfds[r].ino assert tfds[w]["pos"] == 0 assert tfds[w][ "events"] == select.EPOLLOUT | select.EPOLLERR | select.EPOLLHUP assert tfds[w]["ino"] == pfds[w].ino assert tfds[fifo]["pos"] == 0 assert tfds[fifo][ "events"] == select.EPOLLIN | select.EPOLLERR | select.EPOLLHUP assert tfds[fifo]["ino"] == pfds[fifo].ino
def managed_child_process(args: List[str], **kwargs: Any) -> Iterator[pypsutil.Process]: _rewrite_kwargs(kwargs) subproc = subprocess.Popen(args, **kwargs) # pylint: disable=consider-using-with psproc = pypsutil.Process(subproc.pid) try: yield psproc finally: if psproc.is_running(): subproc.terminate() subproc.wait()
def test_eq() -> None: # pylint: disable=comparison-with-itself cur_proc = pypsutil.Process() dead_proc = get_dead_process() # Make sure it works properly when comparing to other Process objects assert cur_proc == cur_proc assert dead_proc == dead_proc assert cur_proc != dead_proc # Comparing to other types returns False assert cur_proc != 0 assert cur_proc != ""
def test_fsugid() -> None: assert hasattr(pypsutil.Process, "fsuid") and hasattr( pypsutil.Process, "fsgid") libc = pypsutil._ffi.load_libc() # pylint: disable=protected-access proc = pypsutil.Process() assert proc.fsuid() == libc.setfsuid(-1) assert proc.fsgid() == libc.setfsgid(-1) with proc.oneshot(): assert proc.fsuid() == libc.setfsuid(-1) assert proc.fsgid() == libc.setfsgid(-1)
def test_threads_oneshot() -> None: proc = pypsutil.Process() with proc.oneshot(): # On some platforms, this will store the information needed to calculate num_threads() # in the cache assert proc.num_threads() == len(proc.threads()) assert len(proc.threads()) == threading.active_count() # Now spawn a thread with managed_background_thread(): # Make sure the cached num_threads() value (if applicable) doesn't mess up threads() # If the cached value is used improperly, threads() could hang or return invalid # results assert len(proc.threads()) == threading.active_count()
def test_thread_ids_cur() -> None: proc = pypsutil.Process() with managed_background_thread(): try: threads = proc.threads() except pypsutil.AccessDenied: pytest.skip("Cannot list threads") else: assert len(threads) >= 2 assert len(threads) == proc.num_threads() assert len(threads) == threading.active_count() assert {thread.native_id for thread in threading.enumerate()} == { thread.id for thread in threads }
def test_basic_info() -> None: proc = pypsutil.Process() assert proc.pid == os.getpid() assert proc.ppid() == os.getppid() assert proc.pgid() == os.getpgrp() assert proc.sid() == os.getsid(0) assert proc.status() == pypsutil.ProcessStatus.RUNNING assert proc.parent().pid == os.getppid() # type: ignore assert proc.create_time() <= time.time() assert proc.create_time() >= pypsutil.boot_time() assert os.path.samefile(proc.cwd(), os.getcwd())