Skip to content

Commit b580891

Browse files
xuanyang15copybara-github
authored andcommitted
refactor(tests): Refactor tests to explicitly handle JSON_SCHEMA_FOR_FUNC_DECL feature flag
Co-authored-by: Xuan Yang <xygoogle@google.com> PiperOrigin-RevId: 901366486
1 parent 36ab8f1 commit b580891

7 files changed

Lines changed: 995 additions & 707 deletions

File tree

tests/unittests/cli/test_cli_feature_options.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from google.adk.features._feature_registry import _WARNED_FEATURES
2323
from google.adk.features._feature_registry import FeatureName
2424
from google.adk.features._feature_registry import is_feature_enabled
25+
from google.adk.features._feature_registry import temporary_feature_override
2526
import pytest
2627

2728

@@ -218,17 +219,21 @@ def test_no_enable_features_flag(self):
218219
"""Command works without --enable_features flag."""
219220
enabled_features = []
220221

221-
@click.command()
222-
@feature_options()
223-
def test_cmd():
224-
enabled_features.append(
225-
is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL)
226-
)
222+
with temporary_feature_override(
223+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, False
224+
):
227225

228-
runner = CliRunner()
229-
result = runner.invoke(test_cmd, [], catch_exceptions=False)
230-
assert result.exit_code == 0
231-
assert enabled_features == [False]
226+
@click.command()
227+
@feature_options()
228+
def test_cmd():
229+
enabled_features.append(
230+
is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL)
231+
)
232+
233+
runner = CliRunner()
234+
result = runner.invoke(test_cmd, [], catch_exceptions=False)
235+
assert result.exit_code == 0
236+
assert enabled_features == [False]
232237

233238
def test_preserves_function_metadata(self):
234239
"""Decorator preserves the wrapped function's metadata."""

tests/unittests/tools/application_integration_tool/test_integration_connector_tool.py

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -99,36 +99,46 @@ def integration_tool_with_auth(mock_rest_api_tool):
9999
)
100100

101101

102-
def test_get_declaration(integration_tool):
103-
"""Tests the generation of the function declaration."""
104-
declaration = integration_tool._get_declaration()
105-
106-
assert isinstance(declaration, FunctionDeclaration)
107-
assert declaration.name == "test_integration_tool"
108-
assert declaration.description == "Test integration tool description."
109-
110-
# Check parameters schema
111-
params = declaration.parameters
112-
assert isinstance(params, Schema)
113-
print(f"params: {params}")
114-
assert params.type == Type.OBJECT
115-
116-
# Check properties (excluded fields should not be present)
117-
assert "user_id" in params.properties
118-
assert "connection_name" not in params.properties
119-
assert "host" not in params.properties
120-
assert "service_name" not in params.properties
121-
assert "entity" not in params.properties
122-
assert "operation" not in params.properties
123-
assert "action" not in params.properties
124-
assert "page_size" in params.properties
125-
assert "filter" in params.properties
126-
127-
# Check required fields (optional and excluded fields should not be required)
128-
assert "user_id" in params.required
129-
assert "page_size" not in params.required
130-
assert "filter" not in params.required
131-
assert "connection_name" not in params.required
102+
class TestIntegrationConnectorToolLegacy:
103+
104+
@pytest.fixture(autouse=True)
105+
def disable_feature_flag(self):
106+
"""Disable the JSON_SCHEMA_FOR_FUNC_DECL feature flag for legacy tests."""
107+
with temporary_feature_override(
108+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, False
109+
):
110+
yield
111+
112+
def test_get_declaration(self, integration_tool):
113+
"""Tests the generation of the function declaration."""
114+
declaration = integration_tool._get_declaration()
115+
116+
assert isinstance(declaration, FunctionDeclaration)
117+
assert declaration.name == "test_integration_tool"
118+
assert declaration.description == "Test integration tool description."
119+
120+
# Check parameters schema
121+
params = declaration.parameters
122+
assert isinstance(params, Schema)
123+
print(f"params: {params}")
124+
assert params.type == Type.OBJECT
125+
126+
# Check properties (excluded fields should not be present)
127+
assert "user_id" in params.properties
128+
assert "connection_name" not in params.properties
129+
assert "host" not in params.properties
130+
assert "service_name" not in params.properties
131+
assert "entity" not in params.properties
132+
assert "operation" not in params.properties
133+
assert "action" not in params.properties
134+
assert "page_size" in params.properties
135+
assert "filter" in params.properties
136+
137+
# Check required fields (optional and excluded fields should not be required)
138+
assert "user_id" in params.required
139+
assert "page_size" not in params.required
140+
assert "filter" not in params.required
141+
assert "connection_name" not in params.required
132142

133143

134144
@pytest.mark.asyncio
@@ -258,21 +268,27 @@ async def test_run_with_auth_async(
258268
assert result == {"status": "success", "data": "mock_data"}
259269

260270

261-
def test_get_declaration_with_json_schema_feature_enabled(integration_tool):
262-
"""Tests the generation of the function declaration with JSON schema feature enabled."""
263-
with temporary_feature_override(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, True):
264-
declaration = integration_tool._get_declaration()
271+
class TestIntegrationConnectorToolWithJsonSchema:
265272

266-
assert isinstance(declaration, FunctionDeclaration)
267-
assert declaration.name == "test_integration_tool"
268-
assert declaration.description == "Test integration tool description."
269-
assert declaration.parameters is None
270-
assert declaration.parameters_json_schema == {
271-
"type": "object",
272-
"properties": {
273-
"user_id": {"type": "string", "description": "User ID"},
274-
"page_size": {"type": "integer"},
275-
"filter": {"type": "string"},
276-
},
277-
"required": ["user_id"],
278-
}
273+
def test_get_declaration_with_json_schema_feature_enabled(
274+
self, integration_tool
275+
):
276+
"""Tests the generation of the function declaration with JSON schema feature enabled."""
277+
with temporary_feature_override(
278+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, True
279+
):
280+
declaration = integration_tool._get_declaration()
281+
282+
assert isinstance(declaration, FunctionDeclaration)
283+
assert declaration.name == "test_integration_tool"
284+
assert declaration.description == "Test integration tool description."
285+
assert declaration.parameters is None
286+
assert declaration.parameters_json_schema == {
287+
"type": "object",
288+
"properties": {
289+
"user_id": {"type": "string", "description": "User ID"},
290+
"page_size": {"type": "integer"},
291+
"filter": {"type": "string"},
292+
},
293+
"required": ["user_id"],
294+
}

tests/unittests/tools/mcp_tool/test_mcp_tool.py

Lines changed: 89 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -63,66 +63,24 @@ def __init__(
6363
self.outputSchema = outputSchema
6464

6565

66-
class TestMCPTool:
67-
"""Test suite for MCPTool class."""
66+
class TestMCPToolLegacy:
67+
"""Legacy tests for MCPTool."""
68+
69+
@pytest.fixture(autouse=True)
70+
def disable_feature_flag(self):
71+
with temporary_feature_override(
72+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, False
73+
):
74+
yield
6875

6976
def setup_method(self):
70-
"""Set up test fixtures."""
7177
self.mock_mcp_tool = MockMCPTool()
7278
self.mock_session_manager = Mock(spec=MCPSessionManager)
7379
self.mock_session = AsyncMock()
7480
self.mock_session_manager.create_session = AsyncMock(
7581
return_value=self.mock_session
7682
)
7783

78-
def test_init_basic(self):
79-
"""Test basic initialization without auth."""
80-
tool = MCPTool(
81-
mcp_tool=self.mock_mcp_tool,
82-
mcp_session_manager=self.mock_session_manager,
83-
)
84-
85-
assert tool.name == "test_tool"
86-
assert tool.description == "Test tool description"
87-
assert tool._mcp_tool == self.mock_mcp_tool
88-
assert tool._mcp_session_manager == self.mock_session_manager
89-
90-
def test_init_with_auth(self):
91-
"""Test initialization with authentication."""
92-
# Create real auth scheme instances instead of mocks
93-
from fastapi.openapi.models import OAuth2
94-
95-
auth_scheme = OAuth2(flows={})
96-
auth_credential = AuthCredential(
97-
auth_type=AuthCredentialTypes.OAUTH2,
98-
oauth2=OAuth2Auth(client_id="test_id", client_secret="test_secret"),
99-
)
100-
101-
tool = MCPTool(
102-
mcp_tool=self.mock_mcp_tool,
103-
mcp_session_manager=self.mock_session_manager,
104-
auth_scheme=auth_scheme,
105-
auth_credential=auth_credential,
106-
)
107-
108-
# The auth config is stored in the parent class _credentials_manager
109-
assert tool._credentials_manager is not None
110-
assert tool._credentials_manager._auth_config.auth_scheme == auth_scheme
111-
assert (
112-
tool._credentials_manager._auth_config.raw_auth_credential
113-
== auth_credential
114-
)
115-
116-
def test_init_with_empty_description(self):
117-
"""Test initialization with empty description."""
118-
mock_tool = MockMCPTool(description=None)
119-
tool = MCPTool(
120-
mcp_tool=mock_tool,
121-
mcp_session_manager=self.mock_session_manager,
122-
)
123-
124-
assert tool.description == ""
125-
12684
def test_get_declaration(self):
12785
"""Test function declaration generation."""
12886
tool = MCPTool(
@@ -137,6 +95,25 @@ def test_get_declaration(self):
13795
assert declaration.description == "Test tool description"
13896
assert declaration.parameters is not None
13997

98+
99+
class TestMCPToolWithJsonSchema:
100+
"""Tests for MCPTool with JSON_SCHEMA_FOR_FUNC_DECL enabled."""
101+
102+
@pytest.fixture(autouse=True)
103+
def enable_feature_flag(self):
104+
with temporary_feature_override(
105+
FeatureName.JSON_SCHEMA_FOR_FUNC_DECL, True
106+
):
107+
yield
108+
109+
def setup_method(self):
110+
self.mock_mcp_tool = MockMCPTool()
111+
self.mock_session_manager = Mock(spec=MCPSessionManager)
112+
self.mock_session = AsyncMock()
113+
self.mock_session_manager.create_session = AsyncMock(
114+
return_value=self.mock_session
115+
)
116+
140117
def test_get_declaration_with_json_schema_for_func_decl_enabled(self):
141118
"""Test function declaration generation with json schema for func decl enabled."""
142119
tool = MCPTool(
@@ -202,6 +179,67 @@ def test_get_declaration_with_empty_output_schema_and_json_schema_for_func_decl_
202179
assert declaration.response is None
203180
assert not declaration.response_json_schema
204181

182+
183+
class TestMCPTool:
184+
"""Test suite for MCPTool class."""
185+
186+
def setup_method(self):
187+
"""Set up test fixtures."""
188+
self.mock_mcp_tool = MockMCPTool()
189+
self.mock_session_manager = Mock(spec=MCPSessionManager)
190+
self.mock_session = AsyncMock()
191+
self.mock_session_manager.create_session = AsyncMock(
192+
return_value=self.mock_session
193+
)
194+
195+
def test_init_basic(self):
196+
"""Test basic initialization without auth."""
197+
tool = MCPTool(
198+
mcp_tool=self.mock_mcp_tool,
199+
mcp_session_manager=self.mock_session_manager,
200+
)
201+
202+
assert tool.name == "test_tool"
203+
assert tool.description == "Test tool description"
204+
assert tool._mcp_tool == self.mock_mcp_tool
205+
assert tool._mcp_session_manager == self.mock_session_manager
206+
207+
def test_init_with_auth(self):
208+
"""Test initialization with authentication."""
209+
# Create real auth scheme instances instead of mocks
210+
from fastapi.openapi.models import OAuth2
211+
212+
auth_scheme = OAuth2(flows={})
213+
auth_credential = AuthCredential(
214+
auth_type=AuthCredentialTypes.OAUTH2,
215+
oauth2=OAuth2Auth(client_id="test_id", client_secret="test_secret"),
216+
)
217+
218+
tool = MCPTool(
219+
mcp_tool=self.mock_mcp_tool,
220+
mcp_session_manager=self.mock_session_manager,
221+
auth_scheme=auth_scheme,
222+
auth_credential=auth_credential,
223+
)
224+
225+
# The auth config is stored in the parent class _credentials_manager
226+
assert tool._credentials_manager is not None
227+
assert tool._credentials_manager._auth_config.auth_scheme == auth_scheme
228+
assert (
229+
tool._credentials_manager._auth_config.raw_auth_credential
230+
== auth_credential
231+
)
232+
233+
def test_init_with_empty_description(self):
234+
"""Test initialization with empty description."""
235+
mock_tool = MockMCPTool(description=None)
236+
tool = MCPTool(
237+
mcp_tool=mock_tool,
238+
mcp_session_manager=self.mock_session_manager,
239+
)
240+
241+
assert tool.description == ""
242+
205243
@pytest.mark.asyncio
206244
async def test_run_async_impl_no_auth(self):
207245
"""Test running tool without authentication."""

0 commit comments

Comments
 (0)