22
33"""Unit tests for tools endpoint."""
44
5+ from pathlib import Path
6+
57import pytest
8+ from pydantic import SecretStr , AnyHttpUrl
69from fastapi import HTTPException
710from llama_stack_client import APIConnectionError , AuthenticationError , BadRequestError
811from pytest_mock import MockerFixture , MockType
1720 ModelContextProtocolServer ,
1821 ServiceConfiguration ,
1922 UserDataCollection ,
23+ TLSConfiguration ,
24+ CORSConfiguration ,
2025)
2126from models .responses import ToolsResponse
2227
@@ -29,9 +34,40 @@ def mock_configuration() -> Configuration:
2934 """Create a mock configuration with MCP servers."""
3035 return Configuration (
3136 name = "test" ,
32- service = ServiceConfiguration (),
33- llama_stack = LlamaStackConfiguration (url = "http://localhost:8321" ),
34- user_data_collection = UserDataCollection (feedback_enabled = False ),
37+ service = ServiceConfiguration (
38+ tls_config = TLSConfiguration (
39+ tls_certificate_path = Path ("tests/configuration/server.crt" ),
40+ tls_key_path = Path ("tests/configuration/server.key" ),
41+ tls_key_password = Path ("tests/configuration/password" ),
42+ ),
43+ cors = CORSConfiguration (
44+ allow_origins = ["foo_origin" , "bar_origin" , "baz_origin" ],
45+ allow_credentials = False ,
46+ allow_methods = ["foo_method" , "bar_method" , "baz_method" ],
47+ allow_headers = ["foo_header" , "bar_header" , "baz_header" ],
48+ ),
49+ host = "localhost" ,
50+ port = 1234 ,
51+ base_url = "." ,
52+ auth_enabled = False ,
53+ workers = 1 ,
54+ color_log = True ,
55+ access_log = True ,
56+ root_path = "/." ,
57+ ),
58+ llama_stack = LlamaStackConfiguration (
59+ url = AnyHttpUrl ("http://localhost:8321" ),
60+ api_key = SecretStr ("xyzzy" ),
61+ use_as_library_client = False ,
62+ library_client_config_path = "." ,
63+ timeout = 10 ,
64+ ),
65+ user_data_collection = UserDataCollection (
66+ transcripts_enabled = False ,
67+ feedback_enabled = False ,
68+ transcripts_storage = "." ,
69+ feedback_storage = "." ,
70+ ),
3571 mcp_servers = [
3672 ModelContextProtocolServer (
3773 name = "filesystem-tools" ,
@@ -44,7 +80,10 @@ def mock_configuration() -> Configuration:
4480 url = "http://localhost:3001" ,
4581 ),
4682 ],
47- ) # type: ignore
83+ customization = None ,
84+ authorization = None ,
85+ deployment_environment = "." ,
86+ )
4887
4988
5089@pytest .fixture
@@ -150,7 +189,9 @@ async def test_tools_endpoint_success(
150189 mock_auth = MOCK_AUTH
151190
152191 # Call the endpoint
153- response = await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
192+ response = await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
193+ mock_request , mock_auth
194+ )
154195
155196 # Verify response
156197 assert isinstance (response , ToolsResponse )
@@ -182,10 +223,44 @@ async def test_tools_endpoint_no_mcp_servers(mocker: MockerFixture) -> None:
182223 # Mock configuration with no MCP servers - wrap in AppConfig
183224 mock_config = Configuration (
184225 name = "test" ,
185- service = ServiceConfiguration (),
186- llama_stack = LlamaStackConfiguration (url = "http://localhost:8321" ),
187- user_data_collection = UserDataCollection (feedback_enabled = False ),
226+ service = ServiceConfiguration (
227+ tls_config = TLSConfiguration (
228+ tls_certificate_path = Path ("tests/configuration/server.crt" ),
229+ tls_key_path = Path ("tests/configuration/server.key" ),
230+ tls_key_password = Path ("tests/configuration/password" ),
231+ ),
232+ cors = CORSConfiguration (
233+ allow_origins = ["foo_origin" , "bar_origin" , "baz_origin" ],
234+ allow_credentials = False ,
235+ allow_methods = ["foo_method" , "bar_method" , "baz_method" ],
236+ allow_headers = ["foo_header" , "bar_header" , "baz_header" ],
237+ ),
238+ host = "localhost" ,
239+ port = 1234 ,
240+ base_url = "." ,
241+ auth_enabled = False ,
242+ workers = 1 ,
243+ color_log = True ,
244+ access_log = True ,
245+ root_path = "/." ,
246+ ),
247+ llama_stack = LlamaStackConfiguration (
248+ url = AnyHttpUrl ("http://localhost:8321" ),
249+ api_key = SecretStr ("xyzzy" ),
250+ use_as_library_client = False ,
251+ library_client_config_path = "." ,
252+ timeout = 10 ,
253+ ),
254+ user_data_collection = UserDataCollection (
255+ transcripts_enabled = False ,
256+ feedback_enabled = False ,
257+ transcripts_storage = "." ,
258+ feedback_storage = "." ,
259+ ),
188260 mcp_servers = [],
261+ customization = None ,
262+ authorization = None ,
263+ deployment_environment = "." ,
189264 )
190265 app_config = AppConfig ()
191266 app_config ._configuration = mock_config
@@ -207,9 +282,9 @@ async def test_tools_endpoint_no_mcp_servers(mocker: MockerFixture) -> None:
207282 mock_auth = MOCK_AUTH
208283
209284 # Call the endpoint
210- response = await tools .tools_endpoint_handler .__wrapped__ (
285+ response = await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
211286 mock_request , mock_auth
212- ) # type: ignore
287+ )
213288
214289 # Verify response
215290 assert isinstance (response , ToolsResponse )
@@ -252,7 +327,9 @@ async def test_tools_endpoint_api_connection_error(
252327
253328 # Call the endpoint - should raise HTTPException when APIConnectionError occurs
254329 with pytest .raises (HTTPException ) as exc_info :
255- await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
330+ await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
331+ mock_request , mock_auth
332+ )
256333
257334 assert exc_info .value .status_code == 503
258335 detail = exc_info .value .detail
@@ -288,7 +365,9 @@ async def test_tools_endpoint_partial_failure( # pylint: disable=redefined-oute
288365 mock_auth = MOCK_AUTH
289366
290367 with pytest .raises (HTTPException ) as exc_info :
291- await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
368+ await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
369+ mock_request , mock_auth
370+ )
292371
293372 assert exc_info .value .status_code == 503
294373 detail = exc_info .value .detail
@@ -339,7 +418,9 @@ async def test_tools_endpoint_toolgroup_not_found( # pylint: disable=redefined-
339418 mock_auth = MOCK_AUTH
340419
341420 # Call the endpoint - should continue processing and return tools from successful toolgroups
342- response = await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
421+ response = await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
422+ mock_request , mock_auth
423+ )
343424
344425 # Verify response - should have only one tool from the first successful toolgroup
345426 assert isinstance (response , ToolsResponse )
@@ -401,7 +482,9 @@ async def test_tools_endpoint_builtin_toolgroup(
401482 mock_auth = MOCK_AUTH
402483
403484 # Call the endpoint
404- response = await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
485+ response = await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
486+ mock_request , mock_auth
487+ )
405488
406489 # Verify response
407490 assert isinstance (response , ToolsResponse )
@@ -416,16 +499,50 @@ async def test_tools_endpoint_mixed_toolgroups(mocker: MockerFixture) -> None:
416499 # Mock configuration with MCP servers - wrap in AppConfig
417500 mock_config = Configuration (
418501 name = "test" ,
419- service = ServiceConfiguration (),
420- llama_stack = LlamaStackConfiguration (url = "http://localhost:8321" ),
421- user_data_collection = UserDataCollection (feedback_enabled = False ),
502+ service = ServiceConfiguration (
503+ tls_config = TLSConfiguration (
504+ tls_certificate_path = Path ("tests/configuration/server.crt" ),
505+ tls_key_path = Path ("tests/configuration/server.key" ),
506+ tls_key_password = Path ("tests/configuration/password" ),
507+ ),
508+ cors = CORSConfiguration (
509+ allow_origins = ["foo_origin" , "bar_origin" , "baz_origin" ],
510+ allow_credentials = False ,
511+ allow_methods = ["foo_method" , "bar_method" , "baz_method" ],
512+ allow_headers = ["foo_header" , "bar_header" , "baz_header" ],
513+ ),
514+ host = "localhost" ,
515+ port = 1234 ,
516+ base_url = "." ,
517+ auth_enabled = False ,
518+ workers = 1 ,
519+ color_log = True ,
520+ access_log = True ,
521+ root_path = "/." ,
522+ ),
523+ llama_stack = LlamaStackConfiguration (
524+ url = AnyHttpUrl ("http://localhost:8321" ),
525+ api_key = SecretStr ("xyzzy" ),
526+ use_as_library_client = False ,
527+ library_client_config_path = "." ,
528+ timeout = 10 ,
529+ ),
530+ user_data_collection = UserDataCollection (
531+ transcripts_enabled = False ,
532+ feedback_enabled = False ,
533+ transcripts_storage = "." ,
534+ feedback_storage = "." ,
535+ ),
422536 mcp_servers = [
423537 ModelContextProtocolServer (
424538 name = "filesystem-tools" ,
425539 provider_id = "model-context-protocol" ,
426540 url = "http://localhost:3000" ,
427541 ),
428542 ],
543+ customization = None ,
544+ authorization = None ,
545+ deployment_environment = "." ,
429546 )
430547 app_config = AppConfig ()
431548 app_config ._configuration = mock_config
@@ -486,7 +603,9 @@ async def test_tools_endpoint_mixed_toolgroups(mocker: MockerFixture) -> None:
486603 mock_auth = MOCK_AUTH
487604
488605 # Call the endpoint
489- response = await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
606+ response = await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
607+ mock_request , mock_auth
608+ )
490609
491610 # Verify response - should have both tools with correct server sources
492611 assert isinstance (response , ToolsResponse )
@@ -674,7 +793,9 @@ async def test_tools_endpoint_authentication_error_with_mcp_endpoint(
674793 mock_auth = MOCK_AUTH
675794
676795 with pytest .raises (HTTPException ) as exc_info :
677- await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
796+ await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
797+ mock_request , mock_auth
798+ )
678799
679800 assert exc_info .value .status_code == 401
680801 assert exc_info .value .headers is not None
@@ -714,7 +835,9 @@ async def test_tools_endpoint_authentication_error_without_mcp_endpoint(
714835 mock_auth = MOCK_AUTH
715836
716837 with pytest .raises (HTTPException ) as exc_info :
717- await tools .tools_endpoint_handler .__wrapped__ (mock_request , mock_auth )
838+ await tools .tools_endpoint_handler .__wrapped__ ( # pyright: ignore
839+ mock_request , mock_auth
840+ )
718841
719842 assert exc_info .value .status_code == 401
720843 detail = exc_info .value .detail
0 commit comments