Skip to main content
Glama
test_cli.py9.41 kB
""" Test cases for the CLI module. """ from unittest.mock import MagicMock, patch import pytest from tools.orchestration.cli import ( create_sample_config, list_available_servers, main, start_servers_by_names, start_servers_interactive, ) class TestCLI: """Test CLI functionality.""" @patch("tools.orchestration.cli.ConfigLoader") def test_create_sample_config_success(self, mock_config_loader): """Test successful configuration creation.""" mock_loader = MagicMock() mock_loader.create_sample_config.return_value = True mock_config_loader.return_value = mock_loader with patch("builtins.print") as mock_print: create_sample_config() mock_loader.create_sample_config.assert_called_once_with("servers.yaml") mock_print.assert_any_call( "[OK] Sample configuration created at: config/servers.yaml" ) @patch("tools.orchestration.cli.ConfigLoader") def test_create_sample_config_failure(self, mock_config_loader): """Test configuration creation failure.""" mock_loader = MagicMock() mock_loader.create_sample_config.return_value = False mock_config_loader.return_value = mock_loader with patch("builtins.print") as mock_print: create_sample_config() mock_print.assert_any_call("[ERROR] Failed to create sample configuration") @patch("tools.orchestration.server_registry.get_registry") @patch("tools.orchestration.cli.ConfigLoader") def test_list_available_servers(self, mock_config_loader, mock_get_registry): """Test listing available servers.""" # Mock registry mock_registry = MagicMock() mock_registry.get_server_info.return_value = { "mock": { "version": "1.0.0", "description": "Mock server", "required_dependencies": [], "required_apps": [], } } mock_get_registry.return_value = mock_registry # Mock config loader mock_loader = MagicMock() mock_config = MagicMock() mock_config.name = "test-server" mock_config.description = "Test server" mock_config.transport = "http" mock_config.host = "localhost" mock_config.port = 8001 mock_config.path = "/mcp" mock_config.config = {"type": "mock"} mock_loader.load_servers_config.return_value = [mock_config] mock_config_loader.return_value = mock_loader with patch("builtins.print") as mock_print: list_available_servers() # Verify print calls assert any("Mock server" in str(call) for call in mock_print.call_args_list) @pytest.mark.xfail( reason="stdin handling in pytest environment - known test infrastructure issue" ) @patch("tools.orchestration.cli.start_multiple_servers_sync") @patch("tools.orchestration.cli.ServerSelector") def test_start_servers_interactive_no_configs( self, mock_selector, mock_start_servers ): """Test interactive server start with no configurations.""" mock_selector_instance = MagicMock() mock_selector_instance.load_available_servers.return_value = [] mock_selector.return_value = mock_selector_instance with patch("builtins.print") as mock_print: start_servers_interactive() mock_print.assert_any_call("[ERROR] No server configurations found.") @patch("tools.orchestration.cli.shutdown_all_sync") @patch("tools.orchestration.cli.wait_for_shutdown_sync") @patch("tools.orchestration.cli.get_server_urls_sync") @patch("tools.orchestration.cli.start_multiple_servers_sync") @patch("tools.orchestration.cli.ServerSelector") def test_start_servers_interactive_success( self, mock_selector, mock_start_servers, mock_get_urls, mock_wait, mock_shutdown ): """Test successful interactive server start.""" # Mock selector mock_selector_instance = MagicMock() mock_config = MagicMock() mock_config.name = "test-server" mock_selector_instance.load_available_servers.return_value = [mock_config] mock_selector_instance.select_servers_interactive.return_value = [mock_config] mock_selector.return_value = mock_selector_instance # Mock sync functions mock_start_servers.return_value = {"test-server": True} mock_get_urls.return_value = {"test-server": "http://localhost:8001"} mock_wait.side_effect = KeyboardInterrupt with patch("builtins.print"): try: start_servers_interactive() except KeyboardInterrupt: pass # Check that start_multiple_servers was called with the expected arguments mock_start_servers.assert_called_once() @patch("tools.orchestration.cli.ConfigLoader") def test_start_servers_by_names_no_configs(self, mock_config_loader): """Test starting servers by name when no configs exist.""" mock_loader = MagicMock() mock_loader.load_servers_config.return_value = [] mock_config_loader.return_value = mock_loader with patch("builtins.print") as mock_print: start_servers_by_names(["test-server"]) mock_print.assert_any_call("[ERROR] No server configurations found.") @patch("tools.orchestration.cli.shutdown_all_sync") @patch("tools.orchestration.cli.wait_for_shutdown_sync") @patch("tools.orchestration.cli.get_server_urls_sync") @patch("tools.orchestration.cli.start_multiple_servers_sync") @patch("tools.orchestration.cli.ConfigLoader") def test_start_servers_by_names_success( self, mock_config_loader, mock_start_servers, mock_get_urls, mock_wait, mock_shutdown, ): """Test successfully starting servers by name.""" # Mock config mock_config = MagicMock() mock_config.name = "test-server" mock_loader = MagicMock() mock_loader.load_servers_config.return_value = [mock_config] mock_config_loader.return_value = mock_loader # Mock sync functions mock_start_servers.return_value = {"test-server": True} mock_get_urls.return_value = {"test-server": "http://localhost:8001"} mock_wait.side_effect = KeyboardInterrupt try: start_servers_by_names(["test-server"]) except KeyboardInterrupt: pass def test_main_init_command(self): """Test main function with init command.""" with patch("tools.orchestration.cli.create_sample_config") as mock_create: with patch("sys.argv", ["cli.py", "init"]): main() mock_create.assert_called_once() def test_main_list_command(self): """Test main function with list command.""" with patch("tools.orchestration.cli.list_available_servers") as mock_list: with patch("sys.argv", ["cli.py", "list"]): main() mock_list.assert_called_once() def test_main_start_command_no_servers(self): """Test main function with start command and no server names.""" with patch("tools.orchestration.cli.start_servers_interactive") as mock_start: with patch("sys.argv", ["cli.py", "start"]): main() mock_start.assert_called_once() def test_main_start_command_with_servers(self): """Test main function with start command and server names.""" with patch("tools.orchestration.cli.start_servers_by_names") as mock_start: with patch("sys.argv", ["cli.py", "start", "server1", "server2"]): main() mock_start.assert_called_once_with(["server1", "server2"], show_logs=True) def test_main_verbose_flag(self): """Test main function with verbose flag.""" with patch("tools.orchestration.cli.configure_logging") as mock_config: with patch("tools.orchestration.cli.create_sample_config"): with patch("sys.argv", ["cli.py", "init", "--verbose"]): main() mock_config.assert_called_with(level="DEBUG") class TestCLIIntegration: """Integration tests for CLI functionality.""" def test_argument_parsing(self): """Test that arguments are parsed correctly.""" from tools.orchestration.cli import main # Test that main can handle different argument combinations test_cases = [ ["init"], ["list"], ["start"], ["start", "server1"], ["init", "--verbose"], ] for args in test_cases: with patch("sys.argv", ["cli.py"] + args): with patch("tools.orchestration.cli.create_sample_config"): with patch("tools.orchestration.cli.list_available_servers"): with patch("tools.orchestration.cli.start_servers_interactive"): with patch( "tools.orchestration.cli.start_servers_by_names" ): try: main() except SystemExit: pass # Expected for help/error cases

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/lightfastai/lightfast-mcp'

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