Skip to content

Commit c6a7b3d

Browse files
Refactor test cases in test_app.py and test_agent_registry.py to remove platform-specific skip markers and enhance mock setup for cross-platform compatibility.
1 parent 90f9d77 commit c6a7b3d

2 files changed

Lines changed: 71 additions & 64 deletions

File tree

src/tests/backend/test_app.py

Lines changed: 71 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,8 @@
55
import pytest
66
import sys
77
import os
8-
import platform
98
from unittest.mock import patch, MagicMock, AsyncMock, Mock
109

11-
# Skip on Linux due to platform-specific Mock/issubclass issues
12-
skip_on_linux = pytest.mark.skipif(
13-
platform.system() == "Linux",
14-
reason="Skipping on Linux due to Mock/issubclass compatibility issues"
15-
)
16-
1710
# Add src to path
1811
src_path = os.path.join(os.path.dirname(__file__), '..', '..', '..')
1912
src_path = os.path.abspath(src_path)
@@ -39,39 +32,69 @@
3932
os.environ.setdefault("AZURE_OPENAI_RAI_DEPLOYMENT_NAME", "test-rai-deployment")
4033

4134

42-
@pytest.fixture(autouse=True)
43-
def setup_environment(monkeypatch):
44-
"""Set up environment variables and mocks."""
45-
# Mock router BEFORE any imports
46-
mock_router = MagicMock()
47-
mock_router.routes = []
48-
sys.modules['backend.v4.api.router'] = MagicMock(app_v4=mock_router)
35+
@pytest.fixture(scope="module", autouse=True)
36+
def setup_mocks():
37+
"""Set up mocks for backend.app imports."""
38+
# Save original modules
39+
original_router = sys.modules.get('backend.v4.api.router')
40+
original_agent_registry = sys.modules.get('backend.v4.config.agent_registry')
41+
42+
# Create APIRouter mock that doesn't trigger isinstance/issubclass
43+
from fastapi import APIRouter
44+
mock_app_v4 = APIRouter()
45+
mock_app_v4.routes = []
46+
47+
# Mock the router module
48+
class MockRouterModule:
49+
app_v4 = mock_app_v4
4950

50-
# Mock middleware
51-
sys.modules['backend.middleware.health_check'] = MagicMock()
51+
sys.modules['backend.v4.api.router'] = MockRouterModule()
5252

5353
# Mock agent registry
54-
mock_agent_registry = MagicMock()
55-
mock_agent_registry.cleanup_all_agents = AsyncMock()
56-
sys.modules['backend.v4.config.agent_registry'] = MagicMock(agent_registry=mock_agent_registry)
54+
class MockAgentRegistry:
55+
async def cleanup_all_agents(self):
56+
pass
57+
58+
class MockAgentRegistryModule:
59+
agent_registry = MockAgentRegistry()
5760

58-
# Mock Azure monitor
61+
sys.modules['backend.v4.config.agent_registry'] = MockAgentRegistryModule()
62+
63+
# Mock Azure monitor and import
5964
with patch('azure.monitor.opentelemetry.configure_azure_monitor'):
60-
yield
65+
# Now import backend.app
66+
import backend.app
67+
globals()['app'] = backend.app.app
68+
globals()['lifespan'] = backend.app.lifespan
69+
globals()['user_browser_language_endpoint'] = backend.app.user_browser_language_endpoint
70+
71+
yield
72+
73+
# Cleanup - restore original modules
74+
if original_router is not None:
75+
sys.modules['backend.v4.api.router'] = original_router
76+
elif 'backend.v4.api.router' in sys.modules:
77+
del sys.modules['backend.v4.api.router']
78+
79+
if original_agent_registry is not None:
80+
sys.modules['backend.v4.config.agent_registry'] = original_agent_registry
81+
elif 'backend.v4.config.agent_registry' in sys.modules:
82+
del sys.modules['backend.v4.config.agent_registry']
83+
84+
# Remove backend.app from cache so it can be reimported fresh
85+
if 'backend.app' in sys.modules:
86+
del sys.modules['backend.app']
6187

6288

63-
@skip_on_linux
64-
def test_app_initialization(setup_environment):
89+
def test_app_initialization():
6590
"""Test that FastAPI app initializes correctly."""
6691
from backend.app import app
6792
assert app is not None
6893
assert hasattr(app, 'routes')
6994

7095

71-
@skip_on_linux
72-
def test_app_has_cors_middleware(setup_environment):
96+
def test_app_has_cors_middleware():
7397
"""Test that CORS middleware is configured."""
74-
from backend.app import app
7598
from starlette.middleware.cors import CORSMiddleware
7699
# Check if CORS middleware is in the middleware stack
77100
has_cors = any(
@@ -81,10 +104,9 @@ def test_app_has_cors_middleware(setup_environment):
81104
assert has_cors, "CORS middleware not found in app.user_middleware"
82105

83106

84-
@skip_on_linux
85-
def test_user_browser_language_endpoint(setup_environment):
107+
def test_user_browser_language_endpoint():
86108
"""Test the user browser language endpoint exists."""
87-
from backend.app import app, user_browser_language_endpoint
109+
from backend.app import user_browser_language_endpoint
88110
from backend.common.models.messages_af import UserLanguage
89111

90112
# Verify endpoint function exists and is callable
@@ -95,8 +117,7 @@ def test_user_browser_language_endpoint(setup_environment):
95117
assert test_lang.language == "en-US"
96118

97119

98-
@skip_on_linux
99-
def test_user_browser_language_endpoint_different_languages(setup_environment):
120+
def test_user_browser_language_endpoint_different_languages():
100121
"""Test UserLanguage model with different languages."""
101122
from backend.common.models.messages_af import UserLanguage
102123

@@ -106,45 +127,37 @@ def test_user_browser_language_endpoint_different_languages(setup_environment):
106127
assert test_lang.language == lang
107128

108129

109-
@skip_on_linux
110130
@pytest.mark.asyncio
111-
async def test_lifespan_context(setup_environment):
131+
async def test_lifespan_context():
112132
"""Test the lifespan context manager."""
113-
from backend.app import lifespan, app
133+
from backend.app import lifespan
114134

115135
async with lifespan(app):
116136
pass
117137

118138

119-
@skip_on_linux
120-
def test_app_includes_v4_router(setup_environment):
139+
def test_app_includes_v4_router():
121140
"""Test that V4 router is included."""
122-
from backend.app import app
123141
assert len(app.routes) > 0
124142

125143

126-
@skip_on_linux
127-
def test_logging_configured(setup_environment):
144+
def test_logging_configured():
128145
"""Test that logging is configured."""
129146
import logging
130-
from backend.app import app
131147

132148
logger = logging.getLogger("backend")
133149
assert logger is not None
134150

135151

136-
@skip_on_linux
137-
def test_fastapi_app_configuration(setup_environment):
152+
def test_fastapi_app_configuration():
138153
"""Test FastAPI app is properly configured."""
139-
from backend.app import app
140154

141155
# Verify app has lifespan
142156
assert app.router.lifespan_context is not None
143157

144158

145-
@skip_on_linux
146159
@pytest.mark.asyncio
147-
async def test_user_browser_language_endpoint_function(setup_environment):
160+
async def test_user_browser_language_endpoint_function():
148161
"""Test the user_browser_language_endpoint function directly."""
149162
from backend.app import user_browser_language_endpoint
150163
from backend.common.models.messages_af import UserLanguage
@@ -161,30 +174,36 @@ async def test_user_browser_language_endpoint_function(setup_environment):
161174
assert result == {"status": "Language received successfully"}
162175

163176

164-
@skip_on_linux
165177
@pytest.mark.asyncio
166-
async def test_lifespan_exception_handling(setup_environment):
178+
async def test_lifespan_exception_handling():
167179
"""Test lifespan context manager exception handling during cleanup."""
168-
from backend.app import lifespan, app
180+
from backend.app import lifespan
169181
from backend.v4.config.agent_registry import agent_registry
170182

183+
# Save original method
184+
original_cleanup = agent_registry.cleanup_all_agents
185+
171186
# Make cleanup raise an exception
172-
agent_registry.cleanup_all_agents.side_effect = Exception("Test cleanup error")
187+
async def mock_cleanup():
188+
raise Exception("Test cleanup error")
189+
190+
agent_registry.cleanup_all_agents = mock_cleanup
173191

174192
# Should not raise, exception should be caught
175193
try:
176194
async with lifespan(app):
177195
pass
178196
except Exception:
179197
pytest.fail("Lifespan should handle cleanup exceptions gracefully")
198+
finally:
199+
# Restore original method
200+
agent_registry.cleanup_all_agents = original_cleanup
180201

181202

182-
@skip_on_linux
183-
def test_applicationinsights_not_configured(setup_environment):
203+
def test_applicationinsights_not_configured():
184204
"""Test that app handles missing Application Insights gracefully."""
185205
# This test checks that the app can start even without AppInsights
186206
# The warning log on line 59 was already executed during module import
187-
from backend.app import app
188207
assert app is not None
189208

190209

src/tests/backend/v4/config/test_agent_registry.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,12 @@
88
import asyncio
99
import logging
1010
import os
11-
import platform
1211
import sys
1312
import threading
1413
import unittest
1514
from unittest.mock import AsyncMock, MagicMock, patch
1615
from weakref import WeakSet
1716

18-
# Skip decorator for Linux-specific failures
19-
skip_on_linux = unittest.skipIf(
20-
platform.system() == "Linux",
21-
"Skipping on Linux due to logging/mocking compatibility issues"
22-
)
23-
2417
# Add the backend directory to the Python path
2518
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'backend'))
2619

@@ -127,7 +120,6 @@ class AgentNoName:
127120
metadata = self.registry._agent_metadata[agent_id]
128121
self.assertEqual(metadata['name'], 'Unknown')
129122

130-
@skip_on_linux
131123
@patch('backend.v4.config.agent_registry.logging.getLogger')
132124
def test_register_agent_logging(self, mock_get_logger):
133125
"""Test logging during agent registration."""
@@ -168,7 +160,6 @@ def test_register_same_agent_multiple_times(self):
168160
# But metadata might be updated
169161
self.assertEqual(len(self.registry._agent_metadata), 1)
170162

171-
@skip_on_linux
172163
@patch('backend.v4.config.agent_registry.logging.getLogger')
173164
def test_register_agent_exception_handling(self, mock_get_logger):
174165
"""Test exception handling during agent registration."""
@@ -210,7 +201,6 @@ def test_unregister_nonexistent_agent(self):
210201
self.assertEqual(len(self.registry._all_agents), 0)
211202
self.assertEqual(len(self.registry._agent_metadata), 0)
212203

213-
@skip_on_linux
214204
@patch('backend.v4.config.agent_registry.logging.getLogger')
215205
def test_unregister_agent_logging(self, mock_get_logger):
216206
"""Test logging during agent unregistration."""
@@ -231,7 +221,6 @@ def test_unregister_agent_logging(self, mock_get_logger):
231221
self.assertIn("Unregistered agent", log_message)
232222
self.assertIn("MockAgent", log_message)
233223

234-
@skip_on_linux
235224
@patch('backend.v4.config.agent_registry.logging.getLogger')
236225
def test_unregister_agent_exception_handling(self, mock_get_logger):
237226
"""Test exception handling during agent unregistration."""
@@ -511,7 +500,6 @@ def test_global_registry_instance(self):
511500
"""Test that global registry instance is available."""
512501
self.assertIsInstance(agent_registry, AgentRegistry)
513502

514-
@skip_on_linux
515503
def test_global_registry_singleton_behavior(self):
516504
"""Test that the global registry behaves as expected."""
517505
# Import the global instance

0 commit comments

Comments
 (0)