-
Notifications
You must be signed in to change notification settings - Fork 164
Expand file tree
/
Copy pathconftest.py
More file actions
157 lines (131 loc) · 4.72 KB
/
conftest.py
File metadata and controls
157 lines (131 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python3
"""
Pytest configuration and shared fixtures for MetasploitMCP tests.
"""
import pytest
import sys
import os
from unittest.mock import Mock, patch
# Add the project root to Python path
sys.path.insert(0, os.path.dirname(__file__))
def pytest_configure(config):
"""Configure pytest with custom settings."""
# Mock external dependencies that might not be available
mock_modules = [
'uvicorn',
'fastapi',
'mcp.server.fastmcp',
'mcp.server.sse',
'pymetasploit3.msfrpc',
'starlette.applications',
'starlette.routing',
'mcp.server.session'
]
for module in mock_modules:
if module not in sys.modules:
sys.modules[module] = Mock()
def pytest_collection_modifyitems(config, items):
"""Modify test collection to add markers automatically."""
for item in items:
# Add unit marker to test_options_parsing and test_helpers
if "test_options_parsing" in item.nodeid or "test_helpers" in item.nodeid:
item.add_marker(pytest.mark.unit)
# Add integration marker to integration tests
if "test_tools_integration" in item.nodeid:
item.add_marker(pytest.mark.integration)
# Mark network tests
if "network" in item.name.lower():
item.add_marker(pytest.mark.network)
# Mark slow tests
if any(keyword in item.name.lower() for keyword in ["slow", "timeout", "long"]):
item.add_marker(pytest.mark.slow)
@pytest.fixture(scope="session")
def mock_msf_environment():
"""Session-scoped fixture that provides a complete mock MSF environment."""
class MockMsfRpcClient:
def __init__(self):
self.modules = Mock()
self.core = Mock()
self.sessions = Mock()
self.jobs = Mock()
self.consoles = Mock()
# Default return values
self.core.version = {'version': '6.3.0'}
self.modules.exploits = []
self.modules.payloads = []
self.sessions.list.return_value = {}
self.jobs.list.return_value = {}
class MockMsfConsole:
def __init__(self, cid='test-console'):
self.cid = cid
def read(self):
return {'data': '', 'prompt': 'msf6 > ', 'busy': False}
def write(self, command):
return True
class MockMsfRpcError(Exception):
pass
# Apply mocks
with patch.dict('sys.modules', {
'pymetasploit3.msfrpc': Mock(
MsfRpcClient=MockMsfRpcClient,
MsfConsole=MockMsfConsole,
MsfRpcError=MockMsfRpcError
)
}):
yield {
'client_class': MockMsfRpcClient,
'console_class': MockMsfConsole,
'error_class': MockMsfRpcError
}
@pytest.fixture
def mock_logger():
"""Fixture providing a mock logger."""
with patch('MetasploitMCP.logger') as mock_log:
yield mock_log
@pytest.fixture
def temp_payload_dir(tmp_path):
"""Fixture providing a temporary directory for payload saves."""
payload_dir = tmp_path / "payloads"
payload_dir.mkdir()
with patch('MetasploitMCP.PAYLOAD_SAVE_DIR', str(payload_dir)):
yield str(payload_dir)
@pytest.fixture
def mock_asyncio_to_thread():
"""Fixture to mock asyncio.to_thread for testing."""
async def mock_to_thread(func, *args, **kwargs):
return func(*args, **kwargs)
with patch('asyncio.to_thread', side_effect=mock_to_thread):
yield
@pytest.fixture
def capture_logs(caplog):
"""Fixture to capture and provide log output."""
import logging
caplog.set_level(logging.DEBUG)
return caplog
# Command line options
def pytest_addoption(parser):
"""Add custom command line options."""
parser.addoption(
"--run-slow",
action="store_true",
default=False,
help="Run slow tests"
)
parser.addoption(
"--run-network",
action="store_true",
default=False,
help="Run tests that require network access"
)
def pytest_runtest_setup(item):
"""Setup hook to skip tests based on markers and options."""
if "slow" in item.keywords and not item.config.getoption("--run-slow"):
pytest.skip("Skipping slow test (use --run-slow to run)")
if "network" in item.keywords and not item.config.getoption("--run-network"):
pytest.skip("Skipping network test (use --run-network to run)")
# Test environment setup
@pytest.fixture(autouse=True)
def reset_msf_client():
"""Automatically reset the global MSF client between tests."""
with patch('MetasploitMCP._msf_client_instance', None):
yield