Skip to content

Commit 8ef2177

Browse files
Jacksunweicopybara-github
authored andcommitted
test: Fixes adk cli options and method parameters mismatching and adds a unit test for future proof checking
The test will fail if `@option` list and method parameter don't match. Future proof test for #2328 PiperOrigin-RevId: 791022512
1 parent 97318bc commit 8ef2177

File tree

2 files changed

+188
-4
lines changed

2 files changed

+188
-4
lines changed

src/google/adk/cli/cli_tools_click.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,15 @@ def decorator(func):
676676
show_default=True,
677677
help="Optional. Whether to enable live reload for agents changes.",
678678
)
679+
@click.option(
680+
"--eval_storage_uri",
681+
type=str,
682+
help=(
683+
"Optional. The evals storage URI to store agent evals,"
684+
" supported URIs: gs://<bucket name>."
685+
),
686+
default=None,
687+
)
679688
@functools.wraps(func)
680689
@click.pass_context
681690
def wrapper(ctx, *args, **kwargs):
@@ -947,6 +956,19 @@ def cli_api_server(
947956
" version in the dev environment)"
948957
),
949958
)
959+
@click.option(
960+
"--a2a",
961+
is_flag=True,
962+
show_default=True,
963+
default=False,
964+
help="Optional. Whether to enable A2A endpoint.",
965+
)
966+
@click.option(
967+
"--allow_origins",
968+
help="Optional. Any additional origins to allow for CORS.",
969+
multiple=True,
970+
)
971+
# TODO: Add eval_storage_uri option back when evals are supported in Cloud Run.
950972
@adk_services_options()
951973
@deprecated_adk_services_options()
952974
def cli_deploy_cloud_run(
@@ -960,18 +982,15 @@ def cli_deploy_cloud_run(
960982
trace_to_cloud: bool,
961983
with_ui: bool,
962984
adk_version: str,
985+
log_level: str,
963986
verbosity: Optional[str],
964-
reload: bool = True,
965987
allow_origins: Optional[list[str]] = None,
966-
log_level: Optional[str] = None,
967988
session_service_uri: Optional[str] = None,
968989
artifact_service_uri: Optional[str] = None,
969990
memory_service_uri: Optional[str] = None,
970-
eval_storage_uri: Optional[str] = None,
971991
session_db_url: Optional[str] = None, # Deprecated
972992
artifact_storage_uri: Optional[str] = None, # Deprecated
973993
a2a: bool = False,
974-
reload_agents: bool = False,
975994
):
976995
"""Deploys an agent to Cloud Run.
977996
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Unit tests to check if any Click options and method parameters mismatch."""
16+
17+
import inspect
18+
from typing import MutableMapping
19+
from typing import Optional
20+
21+
import click
22+
from google.adk.cli.cli_tools_click import cli_api_server
23+
from google.adk.cli.cli_tools_click import cli_create_cmd
24+
from google.adk.cli.cli_tools_click import cli_deploy_agent_engine
25+
from google.adk.cli.cli_tools_click import cli_deploy_cloud_run
26+
from google.adk.cli.cli_tools_click import cli_deploy_gke
27+
from google.adk.cli.cli_tools_click import cli_eval
28+
from google.adk.cli.cli_tools_click import cli_run
29+
from google.adk.cli.cli_tools_click import cli_web
30+
from google.adk.cli.cli_tools_click import deploy
31+
from google.adk.cli.cli_tools_click import main
32+
33+
34+
def _get_command_by_name(
35+
commands: MutableMapping[str, click.Command], name
36+
) -> Optional[click.Command]:
37+
"""Return the command object with the given name from a commands dict."""
38+
return next((cmd for cmd in commands.values() if cmd.name == name), None)
39+
40+
41+
def _get_click_options(command) -> set[str]:
42+
"""Extract Click option names from a command."""
43+
options = []
44+
for param in command.params:
45+
if isinstance(param, (click.Option, click.Argument)):
46+
options.append(param.name)
47+
return set(options)
48+
49+
50+
def _get_method_parameters(func) -> set[str]:
51+
"""Extract parameter names from a method signature."""
52+
sig = inspect.signature(func)
53+
return set(sig.parameters.keys())
54+
55+
56+
def _check_options_in_parameters(
57+
command,
58+
func,
59+
command_name,
60+
ignore_params: Optional[set[str]] = None,
61+
):
62+
"""Check if all Click options are present in method parameters."""
63+
click_options = _get_click_options(command)
64+
method_params = _get_method_parameters(func)
65+
66+
if ignore_params:
67+
click_options -= ignore_params
68+
method_params -= ignore_params
69+
70+
option_only = click_options - method_params
71+
parameter_only = method_params - click_options
72+
73+
assert click_options == method_params, f"""\
74+
Click options and method parameters do not match for command: `{command_name}`.
75+
Click options: {click_options}
76+
Method parameters: {method_params}
77+
Options only: {option_only}
78+
Parameters only: {parameter_only}
79+
"""
80+
81+
82+
def test_adk_create():
83+
"""Test that cli_create_cmd has all required parameters."""
84+
create_command = _get_command_by_name(main.commands, "create")
85+
86+
assert create_command is not None, "Create command not found"
87+
_check_options_in_parameters(
88+
create_command, cli_create_cmd.callback, "create"
89+
)
90+
91+
92+
def test_adk_run():
93+
"""Test that cli_run has all required parameters."""
94+
run_command = _get_command_by_name(main.commands, "run")
95+
96+
assert run_command is not None, "Run command not found"
97+
_check_options_in_parameters(run_command, cli_run.callback, "run")
98+
99+
100+
def test_adk_eval():
101+
"""Test that cli_eval has all required parameters."""
102+
eval_command = _get_command_by_name(main.commands, "eval")
103+
104+
assert eval_command is not None, "Eval command not found"
105+
_check_options_in_parameters(eval_command, cli_eval.callback, "eval")
106+
107+
108+
def test_adk_web():
109+
"""Test that cli_web has all required parameters."""
110+
web_command = _get_command_by_name(main.commands, "web")
111+
112+
assert web_command is not None, "Web command not found"
113+
_check_options_in_parameters(
114+
web_command, cli_web.callback, "web", ignore_params={"verbose"}
115+
)
116+
117+
118+
def test_adk_api_server():
119+
"""Test that cli_api_server has all required parameters."""
120+
api_server_command = _get_command_by_name(main.commands, "api_server")
121+
122+
assert api_server_command is not None, "API server command not found"
123+
_check_options_in_parameters(
124+
api_server_command,
125+
cli_api_server.callback,
126+
"api_server",
127+
ignore_params={"verbose"},
128+
)
129+
130+
131+
def test_adk_deploy_cloud_run():
132+
"""Test that cli_deploy_cloud_run has all required parameters."""
133+
cloud_run_command = _get_command_by_name(deploy.commands, "cloud_run")
134+
135+
assert cloud_run_command is not None, "Cloud Run deploy command not found"
136+
_check_options_in_parameters(
137+
cloud_run_command,
138+
cli_deploy_cloud_run.callback,
139+
"deploy cloud_run",
140+
ignore_params={"verbose"},
141+
)
142+
143+
144+
def test_adk_deploy_agent_engine():
145+
"""Test that cli_deploy_agent_engine has all required parameters."""
146+
agent_engine_command = _get_command_by_name(deploy.commands, "agent_engine")
147+
148+
assert (
149+
agent_engine_command is not None
150+
), "Agent Engine deploy command not found"
151+
_check_options_in_parameters(
152+
agent_engine_command,
153+
cli_deploy_agent_engine.callback,
154+
"deploy agent_engine",
155+
)
156+
157+
158+
def test_adk_deploy_gke():
159+
"""Test that cli_deploy_gke has all required parameters."""
160+
gke_command = _get_command_by_name(deploy.commands, "gke")
161+
162+
assert gke_command is not None, "GKE deploy command not found"
163+
_check_options_in_parameters(
164+
gke_command, cli_deploy_gke.callback, "deploy gke"
165+
)

0 commit comments

Comments
 (0)