Skip to main content
Glama
smat-dev

Jinni: Bring Your Project Into Context

by smat-dev
test_utils_wsl.py9.77 kB
# tests/test_utils_wsl.py import sys import os import platform import pytest from pathlib import Path from unittest.mock import patch, MagicMock import subprocess import re from types import SimpleNamespace from jinni.utils import ( _translate_wsl_path, _find_wslpath, _build_unc_path, _get_default_wsl_distro, ensure_no_nul, ) # Add project root to sys.path to allow importing 'jinni' project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) # Conditional import based on platform if platform.system() == "Windows": from jinni.utils import ( _translate_wsl_path, _find_wslpath, _build_unc_path, _get_default_wsl_distro, ) # --- Test Setup --- # Mark all tests in this module to be skipped if not on Windows pytestmark = pytest.mark.skipif(platform.system() != "Windows", reason="WSL tests require Windows host") # ---------- paths used everywhere ---------- CI_WSL_EXISTING_FILE_POSIX = "/home/runner/testproj/hello.txt" CI_WSL_EXISTING_DIR_POSIX = "/home/runner/testproj" CI_WSL_NONEXISTENT_POSIX = "/home/runner/no/such/path/exists" # ---------- figure out which distro we should reference ---------- CI_WSL_DISTRO = _get_default_wsl_distro() or "Ubuntu" # ---------- helpers / expected UNC ---------- EXPECTED_UNC_FILE = _build_unc_path(CI_WSL_DISTRO, CI_WSL_EXISTING_FILE_POSIX) EXPECTED_UNC_DIR = _build_unc_path(CI_WSL_DISTRO, CI_WSL_EXISTING_DIR_POSIX) # ---------- regex that really matches a WSL UNC prefix ---------- UNC_PREFIX_RE = re.compile(r"^\\\\wsl\$\\[^\\]+\\", re.IGNORECASE) EXPECTED_TAIL_FILE = r"\home\runner\testproj\hello.txt" EXPECTED_TAIL_DIR = r"\home\runner\testproj" # --- Test Cases --- @pytest.fixture(autouse=True) def clear_caches(): """Fixture to clear LRU caches before each test.""" # Ensure functions exist before trying to clear cache (only relevant on Windows) if platform.system() == "Windows": _find_wslpath.cache_clear() _get_default_wsl_distro.cache_clear() # We don't directly import _cached_wsl_to_unc, but it's called by _translate_wsl_path # Need to import it specifically for cache clearing if that level is needed, # but clearing the top-level callers might suffice. # Let's assume clearing callers is enough for now. # If tests show interference, we might need `from jinni.utils import _cached_wsl_to_unc` # and `_cached_wsl_to_unc.cache_clear()` here. def test_translate_valid_posix_path_file(): """POSIX file path → UNC (fallback).""" with patch.dict(os.environ, {}, clear=False): translated = _translate_wsl_path(CI_WSL_EXISTING_FILE_POSIX) assert UNC_PREFIX_RE.match(translated) assert translated.lower().endswith(EXPECTED_TAIL_FILE) def test_translate_valid_posix_path_dir(): """POSIX directory path → UNC (fallback).""" with patch.dict(os.environ, {}, clear=False): translated = _translate_wsl_path(CI_WSL_EXISTING_DIR_POSIX) assert UNC_PREFIX_RE.match(translated) assert translated.lower().endswith(EXPECTED_TAIL_DIR) assert translated.lower().startswith(r"\\wsl$".lower()) def test_translate_nonexistent_posix_path(): """Test translation of a non-existent POSIX path. Should attempt wslpath, fail existence check, then try manual fallback. Manual fallback should also fail existence check, raising RuntimeError. """ # We expect this to fail the Path(unc).exists() check inside _cached_wsl_to_unc # AND fail the Path(candidate_unc_path).exists() check in the manual fallback. translated = _translate_wsl_path(CI_WSL_NONEXISTENT_POSIX) assert UNC_PREFIX_RE.match(translated) def test_translate_valid_uri_file(): """Test translation of a valid vscode-remote URI for an existing file.""" uri = f"vscode-remote://wsl+{CI_WSL_DISTRO}{CI_WSL_EXISTING_FILE_POSIX}" translated = _translate_wsl_path(uri) assert translated.lower() == EXPECTED_UNC_FILE.lower() def test_translate_valid_uri_localhost_file(): """Test translation of a valid vscode-remote wsl.localhost URI.""" uri = f"vscode-remote://wsl.localhost/{CI_WSL_DISTRO}{CI_WSL_EXISTING_FILE_POSIX}" translated = _translate_wsl_path(uri) assert translated.lower() == EXPECTED_UNC_FILE.lower() def test_translate_valid_uri_alternate_scheme_file(): """Test translation of a valid vscode://vscode-remote URI.""" uri = f"vscode://vscode-remote/wsl+{CI_WSL_DISTRO}{CI_WSL_EXISTING_FILE_POSIX}" translated = _translate_wsl_path(uri) assert translated.lower() == EXPECTED_UNC_FILE.lower() def test_translate_invalid_uri_missing_distro(): """Test translation of vscode-remote URI missing the distro name.""" uri = f"vscode-remote://wsl+{CI_WSL_EXISTING_FILE_POSIX}" # Missing distro with pytest.raises(ValueError, match="missing distro name"): # Different error type _translate_wsl_path(uri) def test_translate_invalid_uri_localhost_missing_distro(): # Double '//' after the authority → truly missing distro uri = f"vscode-remote://wsl.localhost//{CI_WSL_EXISTING_FILE_POSIX.lstrip('/')}" with pytest.raises(ValueError, match="missing distro name"): _translate_wsl_path(uri) def test_translate_non_wsl_uri(): """Test that non-WSL URIs are returned unchanged.""" uri = "file:///C:/Users/test/file.txt" assert _translate_wsl_path(uri) == uri def test_translate_windows_path(): """Test that standard Windows paths are returned unchanged.""" path = "C:\\Users\\test\\file.txt" assert _translate_wsl_path(path) == path def test_translate_unc_path(): """Unchanged if the input is already a UNC.""" assert _translate_wsl_path(EXPECTED_UNC_FILE) == EXPECTED_UNC_FILE def test_translate_posix_path_hard_default(monkeypatch): """When no distro information is available we default to Ubuntu.""" # simulate missing env‑var and empty `wsl -l -q` monkeypatch.delenv("JINNI_ASSUME_WSL_DISTRO", raising=False) monkeypatch.setattr("jinni.utils._get_default_wsl_distro", lambda: "Ubuntu") # should not raise from jinni import utils translated = utils._translate_wsl_path("/home/foo.txt") assert UNC_PREFIX_RE.match(translated) assert translated.lower().endswith(r"\home\foo.txt") # --- Tests for wslpath failure / manual fallback --- @patch('jinni.utils._find_wslpath', return_value=None) def test_translate_posix_no_wslpath_fallback_success(mock_find_wslpath): """Test manual fallback when wslpath isn't found, default distro works.""" with patch('jinni.utils._get_default_wsl_distro', return_value=CI_WSL_DISTRO): translated = _translate_wsl_path(CI_WSL_EXISTING_FILE_POSIX) assert translated.lower() == EXPECTED_UNC_FILE.lower() mock_find_wslpath.assert_called_once() @patch('jinni.utils._find_wslpath', return_value=None) @patch('jinni.utils._get_default_wsl_distro', return_value=None) def test_translate_posix_no_wslpath_no_distro_fails(mock_get_distro, mock_find_wslpath): """Test failure when wslpath and default distro are unavailable.""" with pytest.raises(RuntimeError, match=r"Cannot map POSIX path.*to Windows"): _translate_wsl_path(CI_WSL_EXISTING_FILE_POSIX) mock_find_wslpath.assert_called_once() mock_get_distro.assert_called_once() # Mock subprocess.check_output used by _cached_wsl_to_unc @patch('subprocess.check_output') def test_translate_posix_wslpath_fails_fallback_success(mock_check_output): """Test fallback when wslpath exists but fails (e.g., returns error).""" mock_check_output.side_effect = subprocess.CalledProcessError(1, 'wslpath', stderr='Forced error') with patch('jinni.utils._get_default_wsl_distro', return_value=CI_WSL_DISTRO): with patch('jinni.utils._find_wslpath', return_value="/fake/wslpath"): translated = _translate_wsl_path(CI_WSL_EXISTING_FILE_POSIX) # Should fall back to manual construction assert translated.lower() == EXPECTED_UNC_FILE.lower() # both -u and -w attempted assert mock_check_output.call_count >= 2 mock_check_output.assert_any_call(['/fake/wslpath', '-u', '--', CI_WSL_EXISTING_FILE_POSIX], text=True, stderr=subprocess.PIPE, timeout=5) mock_check_output.assert_any_call(['/fake/wslpath', '-w', '--', CI_WSL_EXISTING_FILE_POSIX], text=True, stderr=subprocess.PIPE, timeout=5) @patch('subprocess.check_output') @patch('jinni.utils._get_default_wsl_distro', return_value=None) def test_translate_posix_wslpath_fails_no_distro_fails(mock_get_distro, mock_check_output): """Test failure when wslpath fails and default distro is unavailable.""" mock_check_output.side_effect = subprocess.CalledProcessError(1, 'wslpath', stderr='Forced error') with patch('jinni.utils._find_wslpath', return_value="/fake/wslpath"): with pytest.raises(RuntimeError, match=r"Cannot map POSIX path.*to Windows"): _translate_wsl_path(CI_WSL_EXISTING_FILE_POSIX) assert mock_check_output.call_count >= 2 # Should still try both flags mock_get_distro.assert_called_once() # Should attempt manual fallback def test__get_default_wsl_distro_fallback(monkeypatch): """When WSL is absent we should still return 'Ubuntu' as a last resort.""" monkeypatch.setattr("subprocess.run", lambda *a, **kw: SimpleNamespace(returncode=1, stdout="")) assert _get_default_wsl_distro() == "Ubuntu" # --- Test ensure_no_nul utility --- def test_ensure_no_nul_wsl(): # Should not raise ensure_no_nul("abc", "test-field") # Should raise ValueError on NUL import pytest with pytest.raises(ValueError): ensure_no_nul("a\x00b", "test-field")

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/smat-dev/jinni'

If you have feedback or need assistance with the MCP directory API, please join our Discord server