@@ -2079,6 +2079,88 @@ def test_openapi_json_schema_accessible(test_app):
20792079 logger .info ("OpenAPI /openapi.json endpoint is accessible" )
20802080
20812081
2082+ @pytest .mark .skipif (
2083+ _compat .IS_A2A_V1 ,
2084+ reason = (
2085+ "0.3.x-only: mocks server.apps.A2AStarletteApplication (gone in 1.x)"
2086+ ),
2087+ )
2088+ def test_a2a_setup_reaches_application_build (
2089+ mock_session_service ,
2090+ mock_artifact_service ,
2091+ mock_memory_service ,
2092+ mock_agent_loader ,
2093+ mock_eval_sets_manager ,
2094+ mock_eval_set_results_manager ,
2095+ temp_agents_dir_with_a2a ,
2096+ monkeypatch ,
2097+ ):
2098+ """Regression test for the A2A setup silently failing.
2099+
2100+ A function-local ``import json`` made ``json`` a local for the whole
2101+ ``get_fast_api_app`` function, so the earlier ``json.load(agent.json)`` in
2102+ the A2A loop raised ``UnboundLocalError``. The surrounding ``except`` swallowed
2103+ it, so no A2A routes were ever mounted. This asserts the loop gets past the
2104+ ``json.load`` call and actually builds the A2A application.
2105+ """
2106+ with (
2107+ patch ("signal.signal" , return_value = None ),
2108+ patch (
2109+ "google.adk.cli.fast_api.create_session_service_from_options" ,
2110+ return_value = mock_session_service ,
2111+ ),
2112+ patch (
2113+ "google.adk.cli.fast_api.create_artifact_service_from_options" ,
2114+ return_value = mock_artifact_service ,
2115+ ),
2116+ patch (
2117+ "google.adk.cli.fast_api.create_memory_service_from_options" ,
2118+ return_value = mock_memory_service ,
2119+ ),
2120+ patch (
2121+ "google.adk.cli.fast_api.AgentLoader" ,
2122+ return_value = mock_agent_loader ,
2123+ ),
2124+ patch (
2125+ "google.adk.cli.fast_api.LocalEvalSetsManager" ,
2126+ return_value = mock_eval_sets_manager ,
2127+ ),
2128+ patch (
2129+ "google.adk.cli.fast_api.LocalEvalSetResultsManager" ,
2130+ return_value = mock_eval_set_results_manager ,
2131+ ),
2132+ patch (
2133+ "google.adk.cli.fast_api._create_task_store_from_options" ,
2134+ return_value = MagicMock (),
2135+ ),
2136+ patch ("google.adk.a2a.executor.a2a_agent_executor.A2aAgentExecutor" ),
2137+ patch ("a2a.server.request_handlers.DefaultRequestHandler" ),
2138+ patch ("a2a.types.AgentCard" , return_value = MagicMock ()),
2139+ patch ("a2a.server.apps.A2AStarletteApplication" ) as mock_a2a_app ,
2140+ ):
2141+ mock_app_instance = MagicMock ()
2142+ mock_app_instance .routes .return_value = []
2143+ mock_a2a_app .return_value = mock_app_instance
2144+
2145+ monkeypatch .chdir (temp_agents_dir_with_a2a )
2146+
2147+ get_fast_api_app (
2148+ agents_dir = "." ,
2149+ web = True ,
2150+ session_service_uri = "" ,
2151+ artifact_service_uri = "" ,
2152+ memory_service_uri = "" ,
2153+ allow_origins = ["*" ],
2154+ a2a = True ,
2155+ host = "127.0.0.1" ,
2156+ port = 8000 ,
2157+ )
2158+
2159+ # If json.load raised UnboundLocalError, execution never reaches the
2160+ # A2AStarletteApplication construction and this mock is never called.
2161+ assert mock_a2a_app .called
2162+
2163+
20822164@pytest .mark .skipif (
20832165 _compat .IS_A2A_V1 ,
20842166 reason = (
0 commit comments