Skip to content

Commit 104f59d

Browse files
committed
fix(cli): remove shadowing local json import breaking A2A setup
1 parent 07455ee commit 104f59d

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

tests/unittests/cli/test_fast_api.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,88 @@ def test_openapi_json_schema_accessible(test_app):
21292129
logger.info("OpenAPI /openapi.json endpoint is accessible")
21302130

21312131

2132+
@pytest.mark.skipif(
2133+
_compat.IS_A2A_V1,
2134+
reason=(
2135+
"0.3.x-only: mocks server.apps.A2AStarletteApplication (gone in 1.x)"
2136+
),
2137+
)
2138+
def test_a2a_setup_reaches_application_build(
2139+
mock_session_service,
2140+
mock_artifact_service,
2141+
mock_memory_service,
2142+
mock_agent_loader,
2143+
mock_eval_sets_manager,
2144+
mock_eval_set_results_manager,
2145+
temp_agents_dir_with_a2a,
2146+
monkeypatch,
2147+
):
2148+
"""Regression test for the A2A setup silently failing.
2149+
2150+
A function-local ``import json`` made ``json`` a local for the whole
2151+
``get_fast_api_app`` function, so the earlier ``json.load(agent.json)`` in
2152+
the A2A loop raised ``UnboundLocalError``. The surrounding ``except`` swallowed
2153+
it, so no A2A routes were ever mounted. This asserts the loop gets past the
2154+
``json.load`` call and actually builds the A2A application.
2155+
"""
2156+
with (
2157+
patch("signal.signal", return_value=None),
2158+
patch(
2159+
"google.adk.cli.fast_api.create_session_service_from_options",
2160+
return_value=mock_session_service,
2161+
),
2162+
patch(
2163+
"google.adk.cli.fast_api.create_artifact_service_from_options",
2164+
return_value=mock_artifact_service,
2165+
),
2166+
patch(
2167+
"google.adk.cli.fast_api.create_memory_service_from_options",
2168+
return_value=mock_memory_service,
2169+
),
2170+
patch(
2171+
"google.adk.cli.fast_api.AgentLoader",
2172+
return_value=mock_agent_loader,
2173+
),
2174+
patch(
2175+
"google.adk.cli.fast_api.LocalEvalSetsManager",
2176+
return_value=mock_eval_sets_manager,
2177+
),
2178+
patch(
2179+
"google.adk.cli.fast_api.LocalEvalSetResultsManager",
2180+
return_value=mock_eval_set_results_manager,
2181+
),
2182+
patch(
2183+
"google.adk.cli.fast_api._create_task_store_from_options",
2184+
return_value=MagicMock(),
2185+
),
2186+
patch("google.adk.a2a.executor.a2a_agent_executor.A2aAgentExecutor"),
2187+
patch("a2a.server.request_handlers.DefaultRequestHandler"),
2188+
patch("a2a.types.AgentCard", return_value=MagicMock()),
2189+
patch("a2a.server.apps.A2AStarletteApplication") as mock_a2a_app,
2190+
):
2191+
mock_app_instance = MagicMock()
2192+
mock_app_instance.routes.return_value = []
2193+
mock_a2a_app.return_value = mock_app_instance
2194+
2195+
monkeypatch.chdir(temp_agents_dir_with_a2a)
2196+
2197+
get_fast_api_app(
2198+
agents_dir=".",
2199+
web=True,
2200+
session_service_uri="",
2201+
artifact_service_uri="",
2202+
memory_service_uri="",
2203+
allow_origins=["*"],
2204+
a2a=True,
2205+
host="127.0.0.1",
2206+
port=8000,
2207+
)
2208+
2209+
# If json.load raised UnboundLocalError, execution never reaches the
2210+
# A2AStarletteApplication construction and this mock is never called.
2211+
assert mock_a2a_app.called
2212+
2213+
21322214
@pytest.mark.skipif(
21332215
_compat.IS_A2A_V1,
21342216
reason=(

0 commit comments

Comments
 (0)