Skip to content

test(inpath): improve Windows and unix test for inpath() #4933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
18 changes: 6 additions & 12 deletions cve_bin_tool/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,21 +312,15 @@ def inpath(binary: str) -> bool:
"""Check to see if something is available in the path.
Used to check if dependencies are installed before use."""
if sys.platform == "win32":
# Windows path handling
return any(
list(
map(
lambda dirname: (Path(dirname) / (binary + ".exe")).is_file(),
os.environ.get("PATH", "").split(";"),
)
)
(Path(dirname) / (binary + ".exe")).is_file()
for dirname in os.environ.get("PATH", "").split(";")
)
# Unix path handling
return any(
list(
map(
lambda dirname: (Path(dirname) / binary).is_file(),
os.environ.get("PATH", "").split(":"),
)
)
(Path(dirname) / binary).is_file()
for dirname in os.environ.get("PATH", "").split(":")
)


Expand Down
93 changes: 86 additions & 7 deletions test/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
CVE-bin-tool util tests
"""
import inspect
import os
import sys
from pathlib import Path
from typing import DefaultDict

from cve_bin_tool.cve_scanner import CVEScanner
Expand All @@ -14,13 +17,89 @@
class TestUtil:
"""Test the util functions"""

def test_inpath(self):
"""Test the check to see if a command line utility is installed
and in path before we try to run it."""
assert inpath("python")

def test_not_inpath(self):
assert not inpath("cve_bin_tool_test_for_not_in_path")
def test_inpath_windows(self, monkeypatch):
"""Test the Windows-specific code path in inpath function.

This test ensures inpath correctly finds executables in Windows PATH and
handles the Windows-specific executable extensions (.exe, etc.).
"""
# Set up Windows platform environment
monkeypatch.setattr(sys, "platform", "win32")

# Mock PATH with multiple directories (using proper pathsep for cross-platform testing)
test_path = rf"C:\test\dir1{os.pathsep}C:\test\dir2"
monkeypatch.setattr(os, "environ", {"PATH": test_path})

# Mock file existence to return True only for python.exe in our test directories
def mock_is_file(self):
path_parts = self.parts
file_name = path_parts[-1].lower()
parent_dir = str(self.parent).lower()

return file_name == "python.exe" and (
r"c:\test\dir1" in parent_dir or r"c:\test\dir2" in parent_dir
)

# Windows only checks if file exists, not if it's executable
def mock_access(path, mode):
return True

# Apply mocks
monkeypatch.setattr(Path, "is_file", mock_is_file)
monkeypatch.setattr(os, "access", mock_access)

# Verify inpath correctly finds python in Windows PATH
assert inpath("python") is True

# Test negative case - binary doesn't exist
monkeypatch.setattr(Path, "is_file", lambda self: False)
assert inpath("nonexistent") is False

def test_inpath_non_windows(self, monkeypatch):
"""Test the Unix/Linux-specific code path in inpath function.

This test verifies inpath correctly finds executables in Unix PATH and
checks for proper executable permissions using os.access.
"""
# Set up Unix platform environment
monkeypatch.setattr(sys, "platform", "linux")

# Mock PATH with multiple directories
test_path = f"/usr/bin{os.pathsep}/usr/local/bin"
monkeypatch.setattr(os, "environ", {"PATH": test_path})

# Mock file existence to return True only for /usr/bin/python
def mock_is_file(self):
return self == Path("/usr/bin/python")

# Mock executable permission check
def mock_access(path, mode):
return str(path) == "/usr/bin/python" and mode == os.X_OK

# Apply mocks
monkeypatch.setattr(Path, "is_file", mock_is_file)
monkeypatch.setattr(os, "access", mock_access)

# Verify inpath correctly finds python with executable permissions
assert inpath("python") is True

# Test negative case - binary exists but not executable permissions
monkeypatch.setattr(Path, "is_file", lambda self: False)
monkeypatch.setattr(os, "access", lambda path, mode: False)
assert inpath("nonexistent") is False

def test_inpath_empty_path(self, monkeypatch):
"""Test inpath behavior when PATH environment variable is empty.

This test ensures inpath gracefully handles the edge case of
an empty PATH environment variable.
"""
# Set empty PATH environment
monkeypatch.setattr(os, "environ", {"PATH": ""})

# inpath should return False when PATH is empty
assert inpath("python") is False
assert inpath("nonexistent") is False


class TestSignature:
Expand Down
Loading