| """ |
| SSHOUT集成双模式测试 |
| 测试SSH模式和API模式的自动选择功能 |
| """ |
| |
| import pytest |
| from unittest.mock import MagicMock, patch |
| |
| import sys |
| import os |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../src')) |
| |
| from claude_agent.sshout import create_sshout_integration |
| from claude_agent.sshout.integration import SSHOUTIntegration |
| from claude_agent.sshout.api_client import SSHOUTApiIntegration |
| |
| |
| class TestSSHOUTDualModeIntegration: |
| """测试SSHOUT双模式集成功能""" |
| |
| def setup_method(self): |
| """测试设置""" |
| self.mock_agent = MagicMock() |
| |
| @patch('claude_agent.utils.config.get_config_manager') |
| @patch('claude_agent.sshout.api_client.os.path.exists', return_value=True) |
| def test_api_mode_selection(self, mock_exists, mock_get_config): |
| """测试API模式选择""" |
| # 配置mock |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'api', |
| 'mention_patterns': ['@Claude'], |
| 'server': { |
| 'hostname': 'test.example.com', |
| 'port': 22333, |
| 'username': 'testuser' |
| }, |
| 'ssh_key': { |
| 'private_key_path': '/fake/key/path', |
| 'timeout': 10 |
| } |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| # 测试创建API模式集成 |
| integration = create_sshout_integration(self.mock_agent) |
| |
| # 验证返回的是API集成实例 |
| assert isinstance(integration, SSHOUTApiIntegration) |
| |
| @patch('claude_agent.utils.config.get_config_manager') |
| @patch('claude_agent.sshout.integration.os.path.exists', return_value=True) |
| def test_ssh_mode_selection(self, mock_exists, mock_get_config): |
| """测试SSH模式选择""" |
| # 配置mock |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'ssh', |
| 'mention_patterns': ['@Claude'], |
| 'server': { |
| 'hostname': 'test.example.com', |
| 'port': 22333, |
| 'username': 'testuser' |
| }, |
| 'ssh_key': { |
| 'private_key_path': '/fake/key/path', |
| 'timeout': 10 |
| } |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| # 测试创建SSH模式集成 |
| integration = create_sshout_integration(self.mock_agent) |
| |
| # 验证返回的是SSH集成实例 |
| assert isinstance(integration, SSHOUTIntegration) |
| |
| @patch('claude_agent.utils.config.get_config_manager') |
| @patch('claude_agent.sshout.api_client.os.path.exists', return_value=True) |
| def test_default_to_api_mode(self, mock_exists, mock_get_config): |
| """测试默认使用API模式""" |
| # 配置mock,不指定connection_mode |
| mock_config_manager = MagicMock() |
| mock_config = { |
| # 没有connection_mode字段,应该默认为API |
| 'mention_patterns': ['@Claude'], |
| 'server': { |
| 'hostname': 'test.example.com', |
| 'port': 22333, |
| 'username': 'testuser' |
| }, |
| 'ssh_key': { |
| 'private_key_path': '/fake/key/path', |
| 'timeout': 10 |
| } |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| # 测试创建集成,应该默认为API模式 |
| integration = create_sshout_integration(self.mock_agent) |
| |
| # 验证返回的是API集成实例 |
| assert isinstance(integration, SSHOUTApiIntegration) |
| |
| @patch('claude_agent.utils.config.get_config_manager') |
| def test_invalid_connection_mode(self, mock_get_config): |
| """测试无效的连接模式""" |
| # 配置mock |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'invalid_mode', |
| 'mention_patterns': ['@Claude'], |
| 'server': { |
| 'hostname': 'test.example.com', |
| 'port': 22333, |
| 'username': 'testuser' |
| }, |
| 'ssh_key': { |
| 'private_key_path': '/fake/key/path', |
| 'timeout': 10 |
| } |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| # 测试应该抛出ValueError |
| with pytest.raises(ValueError, match="不支持的SSHOUT连接模式: invalid_mode"): |
| create_sshout_integration(self.mock_agent) |
| |
| def test_dual_mode_method_compatibility(self): |
| """测试双模式方法兼容性""" |
| # 测试API模式 |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| with patch('claude_agent.sshout.api_client.os.path.exists', return_value=True): |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'api', |
| 'mention_patterns': ['@Claude'], |
| 'server': {'hostname': 'test.com', 'port': 22333, 'username': 'user'}, |
| 'ssh_key': {'private_key_path': '/fake/key', 'timeout': 10} |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_config_manager.get.return_value = 5 |
| mock_get_config.return_value = mock_config_manager |
| |
| api_integration = create_sshout_integration(self.mock_agent) |
| |
| # 验证API模式特有的方法存在 |
| assert hasattr(api_integration, 'connect_to_sshout_api') |
| assert hasattr(api_integration, 'disconnect_from_sshout_api') |
| assert hasattr(api_integration, 'get_connection_status') |
| assert hasattr(api_integration, 'send_message') |
| |
| # 测试SSH模式 |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| with patch('claude_agent.sshout.integration.os.path.exists', return_value=True): |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'ssh', |
| 'mention_patterns': ['@Claude'], |
| 'server': {'hostname': 'test.com', 'port': 22333, 'username': 'user'}, |
| 'ssh_key': {'private_key_path': '/fake/key', 'timeout': 10} |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_config_manager.get.return_value = 5 |
| mock_get_config.return_value = mock_config_manager |
| |
| ssh_integration = create_sshout_integration(self.mock_agent) |
| |
| # 验证SSH模式特有的方法存在 |
| assert hasattr(ssh_integration, 'connect_to_sshout') |
| assert hasattr(ssh_integration, 'disconnect_from_sshout') |
| assert hasattr(ssh_integration, 'get_connection_status') |
| assert hasattr(ssh_integration, 'send_message') |
| |
| def test_connection_status_format_differences(self): |
| """测试连接状态格式差异""" |
| # 测试API模式状态格式 |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| with patch('claude_agent.sshout.api_client.os.path.exists', return_value=True): |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'api', |
| 'mention_patterns': ['@Claude'], |
| 'server': {'hostname': 'test.com', 'port': 22333, 'username': 'user'}, |
| 'ssh_key': {'private_key_path': '/fake/key', 'timeout': 10} |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| api_integration = create_sshout_integration(self.mock_agent) |
| api_status = api_integration.get_connection_status() |
| |
| # 验证API模式状态包含api_version字段 |
| assert 'api_version' in api_status |
| assert api_status['api_version'] == '1.0' |
| assert 'connected' in api_status |
| assert 'server' in api_status |
| assert 'message_count' in api_status |
| |
| # 测试SSH模式状态格式 |
| with patch('claude_agent.utils.config.get_config_manager') as mock_get_config: |
| with patch('claude_agent.sshout.integration.os.path.exists', return_value=True): |
| mock_config_manager = MagicMock() |
| mock_config = { |
| 'connection_mode': 'ssh', |
| 'mention_patterns': ['@Claude'], |
| 'server': {'hostname': 'test.com', 'port': 22333, 'username': 'user'}, |
| 'ssh_key': {'private_key_path': '/fake/key', 'timeout': 10} |
| } |
| mock_config_manager.get_sshout_config.return_value = mock_config |
| mock_get_config.return_value = mock_config_manager |
| |
| ssh_integration = create_sshout_integration(self.mock_agent) |
| ssh_status = ssh_integration.get_connection_status() |
| |
| # 验证SSH模式状态格式 |
| assert 'connected' in ssh_status |
| assert 'server' in ssh_status |
| assert 'message_count' in ssh_status |
| # SSH模式不应该有api_version字段 |
| assert 'api_version' not in ssh_status |
| |
| |
| if __name__ == '__main__': |
| pytest.main([__file__]) |