Files
wehub-resource-sync f3d80b4628
Auto Release / auto-release (push) Failing after 1s
CI / lint (push) Failing after 0s
CI / screenshot-quality (push) Failing after 3s
CI / pr-policy (push) Has been skipped
CI / test (3.11) (push) Failing after 0s
CI / test (3.12) (push) Failing after 0s
CI / test (3.13) (push) Failing after 3s
CI / coverage (push) Failing after 1s
Legibility / legibility (push) Failing after 3s
chore: import upstream snapshot with attribution
2026-07-13 12:31:48 +08:00

308 lines
14 KiB
Python

"""Tests for AWS Bedrock support in Claude target detection."""
import os
from unittest.mock import patch
from claude_tap.cli_clients import (
CLIENT_CONFIGS,
_detect_claude_target,
_is_aws_native_bedrock_url,
)
class TestIsAwsNativeBedrockUrl:
def test_aws_native_endpoint(self):
assert _is_aws_native_bedrock_url("https://bedrock-runtime.us-east-1.amazonaws.com") is True
def test_aws_fips_endpoint(self):
assert _is_aws_native_bedrock_url("https://bedrock-runtime-fips.us-west-2.amazonaws.com") is True
def test_aws_vpce_endpoint(self):
assert _is_aws_native_bedrock_url("https://vpce-xxx.bedrock-runtime.us-east-1.vpce.amazonaws.com") is True
def test_aws_china_endpoint(self):
assert _is_aws_native_bedrock_url("https://bedrock-runtime.cn-north-1.amazonaws.com.cn") is True
def test_aws_api_aws_endpoint(self):
assert _is_aws_native_bedrock_url("https://bedrock-mantle.us-east-1.api.aws") is True
def test_aws_mantle_amazonaws_endpoint(self):
assert _is_aws_native_bedrock_url("https://bedrock-mantle.us-east-1.amazonaws.com") is True
def test_api_gateway_not_native(self):
assert _is_aws_native_bedrock_url("https://abc123.execute-api.us-east-1.amazonaws.com/bedrock") is False
def test_custom_gateway(self):
assert _is_aws_native_bedrock_url("https://ai-gateway.internal.example.com/bedrock") is False
def test_custom_company_proxy(self):
assert _is_aws_native_bedrock_url("https://ai-gateway.internal.company.com/bedrock") is False
def test_empty_string(self):
assert _is_aws_native_bedrock_url("") is False
def test_malformed_url(self):
assert _is_aws_native_bedrock_url("https://[") is False
class TestDetectClaudeTargetBedrock:
def test_custom_bedrock_gateway_takes_priority(self):
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://ai-gateway.internal.example.com/bedrock",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
with patch.dict(os.environ, env, clear=False):
assert _detect_claude_target() == "https://ai-gateway.internal.example.com/bedrock"
def test_bedrock_gateway_ignored_when_bedrock_mode_is_off(self):
env = {
"CLAUDE_CODE_USE_BEDROCK": "0",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://ai-gateway.internal.example.com/bedrock",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
with patch.dict(os.environ, env, clear=False):
assert _detect_claude_target() == "https://custom.example.com"
def test_aws_native_bedrock_skipped_falls_to_base_url(self):
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-runtime.us-east-1.amazonaws.com",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
with patch.dict(os.environ, env, clear=False):
assert _detect_claude_target() == "https://custom.example.com"
def test_aws_native_bedrock_skipped_falls_to_default(self):
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-runtime.us-east-1.amazonaws.com",
}
with patch.dict(os.environ, env, clear=False):
os.environ.pop("ANTHROPIC_BASE_URL", None)
with patch("claude_tap.cli_clients._read_settings_env_base_url", return_value=None):
assert _detect_claude_target() == "https://api.anthropic.com"
def test_api_aws_bedrock_skipped_falls_to_base_url(self):
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-mantle.us-east-1.api.aws",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
with patch.dict(os.environ, env, clear=False):
assert _detect_claude_target() == "https://custom.example.com"
def test_custom_bedrock_gateway_from_settings_takes_priority(self):
values = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://ai-gateway.internal.example.com/bedrock",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
def fake_read(_path, env_key):
return values.get(env_key)
with patch.dict(os.environ, {}, clear=False):
for key in values:
os.environ.pop(key, None)
with patch("claude_tap.cli_clients._read_settings_env_base_url", side_effect=fake_read):
assert _detect_claude_target() == "https://ai-gateway.internal.example.com/bedrock"
def test_base_url_used_when_no_bedrock(self):
env = {"ANTHROPIC_BASE_URL": "https://custom.example.com"}
with patch.dict(os.environ, env, clear=False):
os.environ.pop("CLAUDE_CODE_USE_BEDROCK", None)
os.environ.pop("ANTHROPIC_BEDROCK_BASE_URL", None)
os.environ.pop("CLAUDE_CODE_USE_VERTEX", None)
os.environ.pop("ANTHROPIC_VERTEX_BASE_URL", None)
assert _detect_claude_target() == "https://custom.example.com"
@patch("claude_tap.cli_clients._read_settings_env_base_url", return_value=None)
def test_default_when_no_env(self, mock_read):
with patch.dict(os.environ, {}, clear=False):
os.environ.pop("CLAUDE_CODE_USE_BEDROCK", None)
os.environ.pop("ANTHROPIC_BEDROCK_BASE_URL", None)
os.environ.pop("CLAUDE_CODE_USE_VERTEX", None)
os.environ.pop("ANTHROPIC_VERTEX_BASE_URL", None)
os.environ.pop("ANTHROPIC_BASE_URL", None)
target = _detect_claude_target()
assert target == "https://api.anthropic.com"
class TestDetectClaudeTargetVertex:
def test_vertex_gateway_takes_priority(self):
env = {
"CLAUDE_CODE_USE_VERTEX": "1",
"CLAUDE_CODE_USE_BEDROCK": "0",
"ANTHROPIC_VERTEX_BASE_URL": "https://vertex-gateway.internal.example.com/vertex",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
with patch.dict(os.environ, env, clear=False):
assert _detect_claude_target() == "https://vertex-gateway.internal.example.com/vertex"
def test_vertex_gateway_ignored_when_vertex_mode_is_off(self):
env = {
"CLAUDE_CODE_USE_VERTEX": "0",
"CLAUDE_CODE_USE_BEDROCK": "0",
"ANTHROPIC_VERTEX_BASE_URL": "https://vertex-gateway.internal.example.com/vertex",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
with patch.dict(os.environ, env, clear=False):
assert _detect_claude_target() == "https://custom.example.com"
def test_vertex_gateway_from_settings_takes_priority(self):
values = {
"CLAUDE_CODE_USE_VERTEX": "1",
"CLAUDE_CODE_USE_BEDROCK": "0",
"ANTHROPIC_VERTEX_BASE_URL": "https://vertex-gateway.internal.example.com/vertex",
"ANTHROPIC_BASE_URL": "https://custom.example.com",
}
def fake_read(_path, env_key):
return values.get(env_key)
with patch.dict(os.environ, {}, clear=False):
for key in values:
os.environ.pop(key, None)
with patch("claude_tap.cli_clients._read_settings_env_base_url", side_effect=fake_read):
assert _detect_claude_target() == "https://vertex-gateway.internal.example.com/vertex"
class TestClaudeConfigProviderEnv:
def test_extra_base_url_envs_includes_bedrock_and_vertex(self):
cfg = CLIENT_CONFIGS["claude"]
assert "ANTHROPIC_BEDROCK_BASE_URL" in cfg.extra_base_url_envs
assert "ANTHROPIC_VERTEX_BASE_URL" in cfg.extra_base_url_envs
def test_reverse_base_url_envs_includes_all_claude_provider_base_urls(self):
cfg = CLIENT_CONFIGS["claude"]
envs = cfg.reverse_base_url_envs
assert envs == ("ANTHROPIC_BASE_URL", "ANTHROPIC_BEDROCK_BASE_URL", "ANTHROPIC_VERTEX_BASE_URL")
def test_env_map_rewrites_custom_gateway(self):
"""Custom gateways (non-AWS) should be rewritten to localhost."""
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://ai-gateway.internal.example.com/bedrock",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert env_map["ANTHROPIC_BEDROCK_BASE_URL"] == "http://127.0.0.1:8080"
def test_env_map_ignores_bedrock_when_bedrock_mode_is_off(self):
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_BEDROCK": "0",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://ai-gateway.internal.example.com/bedrock",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_BEDROCK_BASE_URL" not in env_map
def test_env_map_ignores_bedrock_when_no_bedrock_base_url_is_configured(self):
cfg = CLIENT_CONFIGS["claude"]
with patch.dict(os.environ, {"CLAUDE_CODE_USE_BEDROCK": "1", "CLAUDE_CODE_USE_VERTEX": "0"}, clear=False):
os.environ.pop("ANTHROPIC_BEDROCK_BASE_URL", None)
with patch("claude_tap.cli_clients._read_settings_env_base_url", return_value=None):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_BEDROCK_BASE_URL" not in env_map
def test_env_map_skips_aws_native(self):
"""AWS native endpoints must NOT be rewritten (SigV4 would fail)."""
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-runtime.us-east-1.amazonaws.com",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_BEDROCK_BASE_URL" not in env_map
def test_env_map_skips_mantle_amazonaws_native(self):
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-mantle.us-east-1.amazonaws.com",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_BEDROCK_BASE_URL" not in env_map
def test_env_map_skips_api_aws_native(self):
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-mantle.us-east-1.api.aws",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_BEDROCK_BASE_URL" not in env_map
def test_env_map_skips_aws_native_from_settings(self):
cfg = CLIENT_CONFIGS["claude"]
values = {
"CLAUDE_CODE_USE_BEDROCK": "1",
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_BEDROCK_BASE_URL": "https://bedrock-runtime.us-east-1.amazonaws.com",
}
def fake_read(_path, env_key):
return values.get(env_key)
with patch.dict(os.environ, {}, clear=False):
for key in values:
os.environ.pop(key, None)
with patch("claude_tap.cli_clients._read_settings_env_base_url", side_effect=fake_read):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_BEDROCK_BASE_URL" not in env_map
def test_env_map_rewrites_vertex_gateway(self):
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_VERTEX": "1",
"ANTHROPIC_VERTEX_BASE_URL": "https://vertex-gateway.internal.example.com/vertex",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert env_map["ANTHROPIC_VERTEX_BASE_URL"] == "http://127.0.0.1:8080"
def test_env_map_ignores_vertex_when_vertex_mode_is_off(self):
cfg = CLIENT_CONFIGS["claude"]
env = {
"CLAUDE_CODE_USE_VERTEX": "0",
"ANTHROPIC_VERTEX_BASE_URL": "https://vertex-gateway.internal.example.com/vertex",
}
with patch.dict(os.environ, env, clear=False):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_VERTEX_BASE_URL" not in env_map
def test_env_map_ignores_vertex_when_no_vertex_base_url_is_configured(self):
cfg = CLIENT_CONFIGS["claude"]
with patch.dict(os.environ, {"CLAUDE_CODE_USE_VERTEX": "1"}, clear=False):
os.environ.pop("ANTHROPIC_VERTEX_BASE_URL", None)
with patch("claude_tap.cli_clients._read_settings_env_base_url", return_value=None):
env_map = cfg.reverse_base_url_env_map(8080)
assert env_map["ANTHROPIC_BASE_URL"] == "http://127.0.0.1:8080"
assert "ANTHROPIC_VERTEX_BASE_URL" not in env_map