Skip to content

Commit c8fed4f

Browse files
committed
added tests for custom_agent
1 parent 88e3a36 commit c8fed4f

2 files changed

Lines changed: 369 additions & 0 deletions

File tree

tests/structs/agent_workspace/error.txt

Whitespace-only changes.

tests/structs/test_custom_agent.py

Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
import pytest
2+
import json
3+
from unittest.mock import Mock, patch, AsyncMock
4+
from loguru import logger
5+
from swarms.structs.custom_agent import CustomAgent, AgentResponse
6+
7+
try:
8+
import pytest_asyncio
9+
ASYNC_AVAILABLE = True
10+
except ImportError:
11+
ASYNC_AVAILABLE = False
12+
pytest_asyncio = None
13+
14+
15+
def create_test_custom_agent():
16+
return CustomAgent(
17+
name="TestAgent",
18+
description="Test agent for unit testing",
19+
base_url="https://api.test.com",
20+
endpoint="v1/test",
21+
headers={"Authorization": "Bearer test-token"},
22+
timeout=10.0,
23+
verify_ssl=True,
24+
)
25+
26+
27+
@pytest.fixture
28+
def sample_custom_agent():
29+
return create_test_custom_agent()
30+
31+
32+
def test_custom_agent_initialization():
33+
try:
34+
custom_agent_instance = CustomAgent(
35+
name="TestAgent",
36+
description="Test description",
37+
base_url="https://api.example.com",
38+
endpoint="v1/endpoint",
39+
headers={"Content-Type": "application/json"},
40+
timeout=30.0,
41+
verify_ssl=True,
42+
)
43+
assert custom_agent_instance.base_url == "https://api.example.com"
44+
assert custom_agent_instance.endpoint == "v1/endpoint"
45+
assert custom_agent_instance.timeout == 30.0
46+
assert custom_agent_instance.verify_ssl is True
47+
assert "Content-Type" in custom_agent_instance.default_headers
48+
logger.info("CustomAgent initialized successfully")
49+
except Exception as e:
50+
logger.error(f"Failed to initialize CustomAgent: {e}")
51+
raise
52+
53+
54+
def test_custom_agent_initialization_with_default_headers(sample_custom_agent):
55+
try:
56+
custom_agent_no_headers = CustomAgent(
57+
name="TestAgent",
58+
description="Test",
59+
base_url="https://api.test.com",
60+
endpoint="test",
61+
)
62+
assert "Content-Type" in custom_agent_no_headers.default_headers
63+
assert (
64+
custom_agent_no_headers.default_headers["Content-Type"]
65+
== "application/json"
66+
)
67+
logger.debug("Default Content-Type header added correctly")
68+
except Exception as e:
69+
logger.error(f"Failed to test default headers: {e}")
70+
raise
71+
72+
73+
def test_custom_agent_url_normalization():
74+
try:
75+
custom_agent_with_slashes = CustomAgent(
76+
name="TestAgent",
77+
description="Test",
78+
base_url="https://api.test.com/",
79+
endpoint="/v1/test",
80+
)
81+
assert custom_agent_with_slashes.base_url == "https://api.test.com"
82+
assert custom_agent_with_slashes.endpoint == "v1/test"
83+
logger.debug("URL normalization works correctly")
84+
except Exception as e:
85+
logger.error(f"Failed to test URL normalization: {e}")
86+
raise
87+
88+
89+
def test_prepare_headers(sample_custom_agent):
90+
try:
91+
prepared_headers = sample_custom_agent._prepare_headers()
92+
assert "Authorization" in prepared_headers
93+
assert prepared_headers["Authorization"] == "Bearer test-token"
94+
95+
additional_headers = {"X-Custom-Header": "custom-value"}
96+
prepared_headers_with_additional = (
97+
sample_custom_agent._prepare_headers(additional_headers)
98+
)
99+
assert prepared_headers_with_additional["X-Custom-Header"] == "custom-value"
100+
assert prepared_headers_with_additional["Authorization"] == "Bearer test-token"
101+
logger.debug("Header preparation works correctly")
102+
except Exception as e:
103+
logger.error(f"Failed to test prepare_headers: {e}")
104+
raise
105+
106+
107+
def test_prepare_payload_dict(sample_custom_agent):
108+
try:
109+
payload_dict = {"key": "value", "number": 123}
110+
prepared_payload = sample_custom_agent._prepare_payload(payload_dict)
111+
assert isinstance(prepared_payload, str)
112+
parsed = json.loads(prepared_payload)
113+
assert parsed["key"] == "value"
114+
assert parsed["number"] == 123
115+
logger.debug("Dictionary payload prepared correctly")
116+
except Exception as e:
117+
logger.error(f"Failed to test prepare_payload with dict: {e}")
118+
raise
119+
120+
121+
def test_prepare_payload_string(sample_custom_agent):
122+
try:
123+
payload_string = '{"test": "value"}'
124+
prepared_payload = sample_custom_agent._prepare_payload(payload_string)
125+
assert prepared_payload == payload_string
126+
logger.debug("String payload prepared correctly")
127+
except Exception as e:
128+
logger.error(f"Failed to test prepare_payload with string: {e}")
129+
raise
130+
131+
132+
def test_prepare_payload_bytes(sample_custom_agent):
133+
try:
134+
payload_bytes = b'{"test": "value"}'
135+
prepared_payload = sample_custom_agent._prepare_payload(payload_bytes)
136+
assert prepared_payload == payload_bytes
137+
logger.debug("Bytes payload prepared correctly")
138+
except Exception as e:
139+
logger.error(f"Failed to test prepare_payload with bytes: {e}")
140+
raise
141+
142+
143+
def test_parse_response_success(sample_custom_agent):
144+
try:
145+
mock_response = Mock()
146+
mock_response.status_code = 200
147+
mock_response.text = '{"message": "success"}'
148+
mock_response.headers = {"content-type": "application/json"}
149+
mock_response.json.return_value = {"message": "success"}
150+
151+
parsed_response = sample_custom_agent._parse_response(mock_response)
152+
assert isinstance(parsed_response, AgentResponse)
153+
assert parsed_response.status_code == 200
154+
assert parsed_response.success is True
155+
assert parsed_response.json_data == {"message": "success"}
156+
assert parsed_response.error_message is None
157+
logger.debug("Successful response parsed correctly")
158+
except Exception as e:
159+
logger.error(f"Failed to test parse_response success: {e}")
160+
raise
161+
162+
163+
def test_parse_response_error(sample_custom_agent):
164+
try:
165+
mock_response = Mock()
166+
mock_response.status_code = 404
167+
mock_response.text = "Not Found"
168+
mock_response.headers = {"content-type": "text/plain"}
169+
170+
parsed_response = sample_custom_agent._parse_response(mock_response)
171+
assert isinstance(parsed_response, AgentResponse)
172+
assert parsed_response.status_code == 404
173+
assert parsed_response.success is False
174+
assert parsed_response.error_message == "HTTP 404"
175+
logger.debug("Error response parsed correctly")
176+
except Exception as e:
177+
logger.error(f"Failed to test parse_response error: {e}")
178+
raise
179+
180+
181+
def test_extract_content_openai_format(sample_custom_agent):
182+
try:
183+
openai_response = {
184+
"choices": [
185+
{
186+
"message": {
187+
"content": "This is the response content"
188+
}
189+
}
190+
]
191+
}
192+
extracted_content = sample_custom_agent._extract_content(openai_response)
193+
assert extracted_content == "This is the response content"
194+
logger.debug("OpenAI format content extracted correctly")
195+
except Exception as e:
196+
logger.error(f"Failed to test extract_content OpenAI format: {e}")
197+
raise
198+
199+
200+
def test_extract_content_anthropic_format(sample_custom_agent):
201+
try:
202+
anthropic_response = {
203+
"content": [
204+
{"text": "First part "},
205+
{"text": "second part"}
206+
]
207+
}
208+
extracted_content = sample_custom_agent._extract_content(anthropic_response)
209+
assert extracted_content == "First part second part"
210+
logger.debug("Anthropic format content extracted correctly")
211+
except Exception as e:
212+
logger.error(f"Failed to test extract_content Anthropic format: {e}")
213+
raise
214+
215+
216+
def test_extract_content_generic_format(sample_custom_agent):
217+
try:
218+
generic_response = {"text": "Generic response text"}
219+
extracted_content = sample_custom_agent._extract_content(generic_response)
220+
assert extracted_content == "Generic response text"
221+
logger.debug("Generic format content extracted correctly")
222+
except Exception as e:
223+
logger.error(f"Failed to test extract_content generic format: {e}")
224+
raise
225+
226+
227+
@patch("swarms.structs.custom_agent.httpx.Client")
228+
def test_run_success(mock_client_class, sample_custom_agent):
229+
try:
230+
mock_response = Mock()
231+
mock_response.status_code = 200
232+
mock_response.text = '{"choices": [{"message": {"content": "Success"}}]}'
233+
mock_response.json.return_value = {
234+
"choices": [{"message": {"content": "Success"}}]
235+
}
236+
mock_response.headers = {"content-type": "application/json"}
237+
238+
mock_client_instance = Mock()
239+
mock_client_instance.__enter__ = Mock(return_value=mock_client_instance)
240+
mock_client_instance.__exit__ = Mock(return_value=None)
241+
mock_client_instance.post.return_value = mock_response
242+
mock_client_class.return_value = mock_client_instance
243+
244+
test_payload = {"message": "test"}
245+
result = sample_custom_agent.run(test_payload)
246+
247+
assert result == "Success"
248+
logger.info("Run method executed successfully")
249+
except Exception as e:
250+
logger.error(f"Failed to test run success: {e}")
251+
raise
252+
253+
254+
@patch("swarms.structs.custom_agent.httpx.Client")
255+
def test_run_error_response(mock_client_class, sample_custom_agent):
256+
try:
257+
mock_response = Mock()
258+
mock_response.status_code = 500
259+
mock_response.text = "Internal Server Error"
260+
261+
mock_client_instance = Mock()
262+
mock_client_instance.__enter__ = Mock(return_value=mock_client_instance)
263+
mock_client_instance.__exit__ = Mock(return_value=None)
264+
mock_client_instance.post.return_value = mock_response
265+
mock_client_class.return_value = mock_client_instance
266+
267+
test_payload = {"message": "test"}
268+
result = sample_custom_agent.run(test_payload)
269+
270+
assert "Error: HTTP 500" in result
271+
logger.debug("Error response handled correctly")
272+
except Exception as e:
273+
logger.error(f"Failed to test run error response: {e}")
274+
raise
275+
276+
277+
@patch("swarms.structs.custom_agent.httpx.Client")
278+
def test_run_request_error(mock_client_class, sample_custom_agent):
279+
try:
280+
import httpx
281+
282+
mock_client_instance = Mock()
283+
mock_client_instance.__enter__ = Mock(return_value=mock_client_instance)
284+
mock_client_instance.__exit__ = Mock(return_value=None)
285+
mock_client_instance.post.side_effect = httpx.RequestError("Connection failed")
286+
mock_client_class.return_value = mock_client_instance
287+
288+
test_payload = {"message": "test"}
289+
result = sample_custom_agent.run(test_payload)
290+
291+
assert "Request error" in result
292+
logger.debug("Request error handled correctly")
293+
except Exception as e:
294+
logger.error(f"Failed to test run request error: {e}")
295+
raise
296+
297+
298+
@pytest.mark.skipif(not ASYNC_AVAILABLE, reason="pytest-asyncio not installed")
299+
@pytest.mark.asyncio
300+
@patch("swarms.structs.custom_agent.httpx.AsyncClient")
301+
async def test_run_async_success(mock_async_client_class, sample_custom_agent):
302+
try:
303+
mock_response = Mock()
304+
mock_response.status_code = 200
305+
mock_response.text = '{"content": [{"text": "Async Success"}]}'
306+
mock_response.json.return_value = {
307+
"content": [{"text": "Async Success"}]
308+
}
309+
mock_response.headers = {"content-type": "application/json"}
310+
311+
mock_client_instance = AsyncMock()
312+
mock_client_instance.__aenter__ = AsyncMock(return_value=mock_client_instance)
313+
mock_client_instance.__aexit__ = AsyncMock(return_value=None)
314+
mock_client_instance.post = AsyncMock(return_value=mock_response)
315+
mock_async_client_class.return_value = mock_client_instance
316+
317+
test_payload = {"message": "test"}
318+
result = await sample_custom_agent.run_async(test_payload)
319+
320+
assert result == "Async Success"
321+
logger.info("Run_async method executed successfully")
322+
except Exception as e:
323+
logger.error(f"Failed to test run_async success: {e}")
324+
raise
325+
326+
327+
@pytest.mark.skipif(not ASYNC_AVAILABLE, reason="pytest-asyncio not installed")
328+
@pytest.mark.asyncio
329+
@patch("swarms.structs.custom_agent.httpx.AsyncClient")
330+
async def test_run_async_error_response(mock_async_client_class, sample_custom_agent):
331+
try:
332+
mock_response = Mock()
333+
mock_response.status_code = 400
334+
mock_response.text = "Bad Request"
335+
336+
mock_client_instance = AsyncMock()
337+
mock_client_instance.__aenter__ = AsyncMock(return_value=mock_client_instance)
338+
mock_client_instance.__aexit__ = AsyncMock(return_value=None)
339+
mock_client_instance.post = AsyncMock(return_value=mock_response)
340+
mock_async_client_class.return_value = mock_client_instance
341+
342+
test_payload = {"message": "test"}
343+
result = await sample_custom_agent.run_async(test_payload)
344+
345+
assert "Error: HTTP 400" in result
346+
logger.debug("Async error response handled correctly")
347+
except Exception as e:
348+
logger.error(f"Failed to test run_async error response: {e}")
349+
raise
350+
351+
352+
def test_agent_response_dataclass():
353+
try:
354+
agent_response_instance = AgentResponse(
355+
status_code=200,
356+
content="Success",
357+
headers={"content-type": "application/json"},
358+
json_data={"key": "value"},
359+
success=True,
360+
error_message=None,
361+
)
362+
assert agent_response_instance.status_code == 200
363+
assert agent_response_instance.content == "Success"
364+
assert agent_response_instance.success is True
365+
assert agent_response_instance.error_message is None
366+
logger.debug("AgentResponse dataclass created correctly")
367+
except Exception as e:
368+
logger.error(f"Failed to test AgentResponse dataclass: {e}")
369+
raise

0 commit comments

Comments
 (0)