Skip to main content
Glama
test_binary_discovery.py5.98 kB
""" Functional tests for binary discovery and execution. Tests real Claude Code binary discovery and execution. """ import pytest import asyncio import os import sys import shutil from pathlib import Path from shannon_mcp.managers.binary import BinaryManager class TestBinaryDiscovery: """Test actual binary discovery functionality.""" @pytest.mark.asyncio async def test_discover_system_binaries(self): """Test discovering Claude Code binaries on the system.""" manager = BinaryManager() # Discover binaries in real system paths binaries = await manager.discover_binaries() # Log discovered binaries print(f"\nDiscovered {len(binaries)} Claude Code binaries:") for binary in binaries: print(f" - {binary['path']} (version: {binary.get('version', 'unknown')})") # Verify binary structure for binary in binaries: assert 'path' in binary assert 'name' in binary assert os.path.exists(binary['path']) assert os.access(binary['path'], os.X_OK) @pytest.mark.asyncio async def test_nvm_path_discovery(self): """Test discovering Claude Code in NVM paths.""" manager = BinaryManager() # Check if NVM is installed nvm_dir = Path.home() / ".nvm" if nvm_dir.exists(): binaries = await manager.discover_nvm_binaries() print(f"\nDiscovered {len(binaries)} binaries in NVM:") for binary in binaries: print(f" - {binary['path']}") assert "nvm" in binary['path'].lower() @pytest.mark.asyncio async def test_version_detection(self): """Test Claude Code version detection.""" manager = BinaryManager() # Find any Claude Code binary binaries = await manager.discover_binaries() if not binaries: pytest.skip("No Claude Code binary found on system") # Test version detection for first binary binary = binaries[0] version = await manager.get_binary_version(binary['path']) print(f"\nVersion detection for {binary['path']}: {version}") if version: # Version should follow semantic versioning assert '.' in version parts = version.split('.') assert len(parts) >= 2 @pytest.mark.asyncio async def test_binary_validation(self): """Test validating Claude Code binaries.""" manager = BinaryManager() binaries = await manager.discover_binaries() if not binaries: pytest.skip("No Claude Code binary found on system") # Validate each discovered binary for binary in binaries[:3]: # Test first 3 to save time is_valid = await manager.validate_binary(binary['path']) print(f"\nValidation for {binary['path']}: {is_valid}") if is_valid: # Valid binary should respond to --help result = await manager.execute_binary( binary['path'], ["--help"] ) assert result[0] == 0 # Exit code 0 assert result[1] # Should have stdout @pytest.mark.asyncio async def test_binary_capabilities(self): """Test detecting binary capabilities.""" manager = BinaryManager() binaries = await manager.discover_binaries() if not binaries: pytest.skip("No Claude Code binary found on system") binary = binaries[0] # Test common Claude Code commands test_commands = [ ["--version"], ["--help"], ["--list-models"], ] for cmd in test_commands: try: result = await manager.execute_binary(binary['path'], cmd) print(f"\nCommand {cmd}: Exit code {result[0]}") assert result[0] in [0, 1] # Should exit cleanly except Exception as e: print(f"\nCommand {cmd} not supported: {e}") @pytest.mark.asyncio async def test_binary_caching(self): """Test binary discovery caching.""" manager = BinaryManager() # First discovery start = asyncio.get_event_loop().time() binaries1 = await manager.discover_binaries() time1 = asyncio.get_event_loop().time() - start # Second discovery (should use cache) start = asyncio.get_event_loop().time() binaries2 = await manager.discover_binaries(use_cache=True) time2 = asyncio.get_event_loop().time() - start print(f"\nFirst discovery: {time1:.3f}s") print(f"Cached discovery: {time2:.3f}s") # Cache should be faster assert len(binaries1) == len(binaries2) if len(binaries1) > 0: assert time2 < time1 @pytest.mark.asyncio async def test_preferred_binary_selection(self): """Test selecting preferred Claude Code binary.""" manager = BinaryManager() binaries = await manager.discover_binaries() if len(binaries) < 2: pytest.skip("Need multiple binaries for preference testing") # Test different selection criteria criteria = [ {"prefer_version": "latest"}, {"prefer_path": "/usr/local/bin"}, {"require_version": ">=1.0.0"}, ] for criterion in criteria: selected = await manager.get_preferred_binary(**criterion) print(f"\nSelected with {criterion}: {selected['path'] if selected else 'None'}") if selected: assert 'path' in selected assert os.path.exists(selected['path'])

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/krzemienski/shannon-mcp'

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