Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions plugins/ndf/scripts/lib/procs.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,19 @@ def pid_is_zombie(pid: int) -> bool:


def cmdline_contains(pid: int, expected: str) -> bool | None:
"""pid の起動の引数(空白でつないだもの)が `expected` を含むか(大文字と小文字を区別しない)。読めなければ None。"""
"""pid の起動の引数(空白でつないだもの)が `expected` を含むか(大文字と小文字を区別しない)。読めなければ None。

空の引数も読めないとみなす。終了の途中(ゾンビになる前)の pid は、psutil が例外でなく `[]` を返す。
False(別のプロセス)と取ると、すぐ終わる CLI を監視が PIDFILE_BAD で止める(CI の不定の失敗)。
"""
p = _process(pid)
if p is None:
return None
try:
return expected.lower() in " ".join(p.cmdline()).lower()
args = p.cmdline()
except psutil.Error:
return None
return expected.lower() in " ".join(args).lower() if args else None


def parent_and_name(pid: int) -> tuple[int, str] | None:
Expand Down
11 changes: 11 additions & 0 deletions plugins/ndf/scripts/tests/test_lib_procs.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ def test_zombie_counts_as_dead_and_missing_pids_are_quiet():
assert procs.wait_gone(p.pid, timeout=0.1)


def test_empty_cmdline_of_an_exiting_process_is_unreadable(monkeypatch):
"""終了の途中(ゾンビになる前)の pid は psutil が空の引数を返す。別のプロセス(False)と取らない。"""

class Exiting:
def cmdline(self):
return []

monkeypatch.setattr(procs, "_process", lambda pid: Exiting())
assert procs.cmdline_contains(12345, "claude") is None


def test_memory_and_cgroup(tmp_path: Path):
avail, total = procs.memory_available()
assert 0 < avail <= total
Expand Down
Loading