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
543 lines
18 KiB
Python
543 lines
18 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from claude_tap import cli_clients, parse_args
|
|
from claude_tap.cli import CLIENT_CONFIGS, ClientConfig, run_client
|
|
|
|
SUPPORTED_CLIENTS = {
|
|
"agy",
|
|
"claude",
|
|
"codex",
|
|
"codexapp",
|
|
"gemini",
|
|
"kimi",
|
|
"kimi-code",
|
|
"mimo",
|
|
"opencode",
|
|
"openclaw",
|
|
"pi",
|
|
"hermes",
|
|
"cursor",
|
|
"qoder",
|
|
"codebuddy",
|
|
}
|
|
|
|
SINGLE_REVERSE_ENV_CLIENTS = SUPPORTED_CLIENTS - {"claude", "gemini", "kimi-code", "openclaw", "codexapp"}
|
|
|
|
SUPPORTED_DEFAULT_PROXY_MODES = {
|
|
"agy": "forward",
|
|
"claude": "reverse",
|
|
"codex": "reverse",
|
|
"codexapp": "transcript",
|
|
"gemini": "forward",
|
|
"kimi": "reverse",
|
|
"kimi-code": "reverse",
|
|
"mimo": "forward",
|
|
"opencode": "forward",
|
|
"openclaw": "reverse",
|
|
"pi": "forward",
|
|
"hermes": "forward",
|
|
"cursor": "forward",
|
|
"qoder": "forward",
|
|
"codebuddy": "reverse",
|
|
}
|
|
|
|
|
|
class _DummyProc:
|
|
def __init__(self) -> None:
|
|
self.pid = 12345
|
|
self.returncode: int | None = None
|
|
|
|
async def wait(self) -> int:
|
|
self.returncode = 0
|
|
return 0
|
|
|
|
def terminate(self) -> None:
|
|
self.returncode = 0
|
|
|
|
def kill(self) -> None:
|
|
self.returncode = -9
|
|
|
|
|
|
def test_client_matrix_contains_only_supported_clients() -> None:
|
|
assert set(CLIENT_CONFIGS) == SUPPORTED_CLIENTS
|
|
|
|
|
|
def test_only_agy_auto_trusts_ca_on_macos() -> None:
|
|
auto_trust_clients = {client for client, cfg in CLIENT_CONFIGS.items() if cfg.auto_trust_ca_macos}
|
|
|
|
assert auto_trust_clients == {"agy"}
|
|
|
|
|
|
@pytest.mark.parametrize("client", sorted(SUPPORTED_CLIENTS))
|
|
def test_supported_client_default_proxy_modes_are_unchanged(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
client: str,
|
|
) -> None:
|
|
monkeypatch.setenv("CODEX_HOME", str(tmp_path / "codex-home"))
|
|
|
|
args = parse_args(["--tap-client", client])
|
|
|
|
assert args.client == client
|
|
assert args.proxy_mode == SUPPORTED_DEFAULT_PROXY_MODES[client]
|
|
|
|
|
|
@pytest.mark.parametrize("client", sorted(SINGLE_REVERSE_ENV_CLIENTS))
|
|
def test_single_env_clients_keep_single_reverse_base_url_env(client: str) -> None:
|
|
cfg = CLIENT_CONFIGS[client]
|
|
|
|
assert cfg.reverse_base_url_envs == (cfg.base_url_env,)
|
|
|
|
|
|
def test_gemini_declares_both_reverse_base_url_envs() -> None:
|
|
cfg = CLIENT_CONFIGS["gemini"]
|
|
|
|
assert cfg.reverse_base_url_envs == ("GOOGLE_GEMINI_BASE_URL", "GOOGLE_VERTEX_BASE_URL")
|
|
assert cfg.reverse_base_url_env_map(43123) == {
|
|
"GOOGLE_GEMINI_BASE_URL": "http://127.0.0.1:43123",
|
|
"GOOGLE_VERTEX_BASE_URL": "http://127.0.0.1:43123",
|
|
}
|
|
|
|
|
|
def test_claude_declares_provider_reverse_base_url_envs() -> None:
|
|
cfg = CLIENT_CONFIGS["claude"]
|
|
|
|
assert cfg.reverse_base_url_envs == (
|
|
"ANTHROPIC_BASE_URL",
|
|
"ANTHROPIC_BEDROCK_BASE_URL",
|
|
"ANTHROPIC_VERTEX_BASE_URL",
|
|
)
|
|
|
|
|
|
def test_agy_declares_cloud_code_bridge_env() -> None:
|
|
cfg = CLIENT_CONFIGS["agy"]
|
|
|
|
assert cfg.base_url_env == "CLOUD_CODE_URL"
|
|
assert cfg.default_target == "https://daily-cloudcode-pa.googleapis.com"
|
|
assert cfg.forward_base_url_envs == ("CLOUD_CODE_URL",)
|
|
assert cfg.forward_base_url_allowed_path_prefixes == ("/v1internal",)
|
|
|
|
|
|
def test_codexapp_declares_transcript_only_mode() -> None:
|
|
cfg = CLIENT_CONFIGS["codexapp"]
|
|
|
|
assert cfg.label == "Codex App"
|
|
assert cfg.default_target == "codex-app://sessions"
|
|
assert cfg.default_proxy_mode == "transcript"
|
|
assert cfg.transcript_only is True
|
|
|
|
|
|
def test_parse_args_codexapp_rejects_proxy_mode() -> None:
|
|
with pytest.raises(SystemExit):
|
|
parse_args(["--tap-client", "codexapp", "--tap-proxy-mode", "forward"])
|
|
|
|
|
|
def test_parse_args_codexapp_rejects_trust_ca() -> None:
|
|
with pytest.raises(SystemExit):
|
|
parse_args(["--tap-client", "codexapp", "--tap-trust-ca"])
|
|
|
|
|
|
def test_openclaw_declares_multi_provider_reverse_envs() -> None:
|
|
cfg = CLIENT_CONFIGS["openclaw"]
|
|
|
|
assert cfg.default_proxy_mode == "reverse"
|
|
assert cfg.reverse_base_url_envs == (
|
|
"OPENAI_BASE_URL",
|
|
"ANTHROPIC_BASE_URL",
|
|
"GOOGLE_GEMINI_BASE_URL",
|
|
"OPENROUTER_BASE_URL",
|
|
"CUSTOM_BASE_URL",
|
|
)
|
|
|
|
|
|
def test_reverse_base_url_envs_deduplicate_primary_and_extra_envs() -> None:
|
|
cfg = ClientConfig(
|
|
cmd="multi-cli",
|
|
label="Multi CLI",
|
|
install_url="https://example.com",
|
|
base_url_env="PRIMARY_BASE_URL",
|
|
extra_base_url_envs=("SECONDARY_BASE_URL", "PRIMARY_BASE_URL"),
|
|
base_url_suffix="/v1",
|
|
default_target="https://example.com",
|
|
)
|
|
|
|
assert cfg.reverse_base_url_envs == ("PRIMARY_BASE_URL", "SECONDARY_BASE_URL")
|
|
assert cfg.reverse_base_url_env_map(43123) == {
|
|
"PRIMARY_BASE_URL": "http://127.0.0.1:43123/v1",
|
|
"SECONDARY_BASE_URL": "http://127.0.0.1:43123/v1",
|
|
}
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_client_reverse_sets_all_base_url_envs_and_settings(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
cfg = ClientConfig(
|
|
cmd="multi-cli",
|
|
label="Multi CLI",
|
|
install_url="https://example.com",
|
|
base_url_env="PRIMARY_BASE_URL",
|
|
extra_base_url_envs=("SECONDARY_BASE_URL",),
|
|
base_url_suffix="/v1",
|
|
default_target="https://example.com",
|
|
inject_settings_env=True,
|
|
)
|
|
captured: dict[str, object] = {}
|
|
|
|
async def fake_create_subprocess_exec(*cmd, **kwargs):
|
|
captured["cmd"] = cmd
|
|
captured["env"] = kwargs["env"]
|
|
return _DummyProc()
|
|
|
|
monkeypatch.setitem(CLIENT_CONFIGS, "multi-env", cfg)
|
|
monkeypatch.setattr("claude_tap.cli.shutil.which", lambda name: f"/tmp/{name}")
|
|
monkeypatch.setattr(asyncio, "create_subprocess_exec", fake_create_subprocess_exec)
|
|
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
|
|
|
code = await run_client(43123, ["--flag"], client="multi-env", proxy_mode="reverse")
|
|
|
|
assert code == 0
|
|
base_url = "http://127.0.0.1:43123/v1"
|
|
env = captured["env"]
|
|
assert env["PRIMARY_BASE_URL"] == base_url
|
|
assert env["SECONDARY_BASE_URL"] == base_url
|
|
|
|
cmd = captured["cmd"]
|
|
assert cmd[:3] == (
|
|
"/tmp/multi-cli",
|
|
"--settings",
|
|
json.dumps({"env": cfg.reverse_base_url_env_map(43123)}, separators=(",", ":")),
|
|
)
|
|
assert cmd[3:] == ("--flag",)
|
|
|
|
out = capsys.readouterr().out
|
|
assert out.count("PRIMARY_BASE_URL=http://127.0.0.1:43123/v1") == 1
|
|
assert out.count("SECONDARY_BASE_URL=http://127.0.0.1:43123/v1") == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_client_openclaw_reverse_patches_temp_config(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
config = tmp_path / ".openclaw" / "openclaw.json"
|
|
config.parent.mkdir()
|
|
config.write_text(
|
|
json.dumps(
|
|
{
|
|
"agents": {"defaults": {"model": {"primary": "phistory/phistory-dummy"}}},
|
|
"models": {
|
|
"providers": {
|
|
"phistory": {
|
|
"baseUrl": "https://relay.example.com/v1",
|
|
"api": "openai-responses",
|
|
}
|
|
}
|
|
},
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
captured: dict[str, object] = {}
|
|
|
|
async def fake_create_subprocess_exec(*cmd, **kwargs):
|
|
captured["cmd"] = cmd
|
|
captured["env"] = kwargs["env"]
|
|
openclaw_config = Path(kwargs["env"]["OPENCLAW_CONFIG_PATH"])
|
|
captured["config_text"] = openclaw_config.read_text(encoding="utf-8")
|
|
return _DummyProc()
|
|
|
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
monkeypatch.setattr("claude_tap.cli.shutil.which", lambda name: f"/tmp/{name}")
|
|
monkeypatch.setattr(asyncio, "create_subprocess_exec", fake_create_subprocess_exec)
|
|
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
|
|
|
code = await run_client(43123, ["agent"], client="openclaw", proxy_mode="reverse")
|
|
|
|
assert code == 0
|
|
env = captured["env"]
|
|
temp_config = Path(env["OPENCLAW_CONFIG_PATH"])
|
|
assert not temp_config.exists()
|
|
assert captured["cmd"] == ("/tmp/openclaw", "agent")
|
|
config_text = captured["config_text"]
|
|
assert isinstance(config_text, str)
|
|
patched_config = json.loads(config_text)
|
|
assert patched_config["models"]["providers"]["phistory"]["baseUrl"] == "http://127.0.0.1:43123/v1"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_client_openclaw_reverse_patches_model_arg_provider(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
config = tmp_path / ".openclaw" / "openclaw.json"
|
|
config.parent.mkdir()
|
|
config.write_text(
|
|
json.dumps(
|
|
{
|
|
"agents": {"defaults": {"model": {"primary": "openai-codex/gpt-5.4"}}},
|
|
"models": {
|
|
"providers": {
|
|
"anthropic": {
|
|
"baseUrl": "https://api.anthropic.com",
|
|
"api": "anthropic-messages",
|
|
}
|
|
}
|
|
},
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
captured: dict[str, object] = {}
|
|
|
|
async def fake_create_subprocess_exec(*cmd, **kwargs):
|
|
captured["env"] = kwargs["env"]
|
|
openclaw_config = Path(kwargs["env"]["OPENCLAW_CONFIG_PATH"])
|
|
captured["config_text"] = openclaw_config.read_text(encoding="utf-8")
|
|
return _DummyProc()
|
|
|
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
monkeypatch.setattr("claude_tap.cli.shutil.which", lambda name: f"/tmp/{name}")
|
|
monkeypatch.setattr(asyncio, "create_subprocess_exec", fake_create_subprocess_exec)
|
|
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
|
|
|
code = await run_client(
|
|
43123,
|
|
["agent", "--model", "anthropic/claude-opus-4-6"],
|
|
client="openclaw",
|
|
proxy_mode="reverse",
|
|
)
|
|
|
|
assert code == 0
|
|
env = captured["env"]
|
|
assert "OPENCLAW_CONFIG_PATH" in env
|
|
config_text = captured["config_text"]
|
|
assert isinstance(config_text, str)
|
|
patched_config = json.loads(config_text)
|
|
assert patched_config["models"]["providers"]["anthropic"]["baseUrl"] == "http://127.0.0.1:43123"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_client_openclaw_reverse_cleans_temp_config_on_spawn_error(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
config = tmp_path / ".openclaw" / "openclaw.json"
|
|
config.parent.mkdir()
|
|
config.write_text(
|
|
json.dumps(
|
|
{
|
|
"agents": {"defaults": {"model": {"primary": "anthropic/claude-opus-4-6"}}},
|
|
"models": {
|
|
"providers": {
|
|
"anthropic": {
|
|
"baseUrl": "https://api.anthropic.com",
|
|
"api": "anthropic-messages",
|
|
}
|
|
}
|
|
},
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
captured: dict[str, object] = {}
|
|
|
|
async def fake_create_subprocess_exec(*_cmd, **kwargs):
|
|
captured["config_path"] = Path(kwargs["env"]["OPENCLAW_CONFIG_PATH"])
|
|
raise OSError("spawn failed")
|
|
|
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
monkeypatch.setattr("claude_tap.cli.shutil.which", lambda name: f"/tmp/{name}")
|
|
monkeypatch.setattr(asyncio, "create_subprocess_exec", fake_create_subprocess_exec)
|
|
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
|
|
|
with pytest.raises(OSError, match="spawn failed"):
|
|
await run_client(43123, ["agent"], client="openclaw", proxy_mode="reverse")
|
|
|
|
config_path = captured["config_path"]
|
|
assert isinstance(config_path, Path)
|
|
assert not config_path.exists()
|
|
|
|
|
|
def test_openclaw_config_helpers_cover_paths_and_invalid_files(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
missing = tmp_path / "missing.json"
|
|
invalid = tmp_path / "invalid.json"
|
|
invalid.write_text("{", encoding="utf-8")
|
|
|
|
assert cli_clients._read_openclaw_config(missing) is None
|
|
assert cli_clients._read_openclaw_config(invalid) is None
|
|
|
|
explicit = tmp_path / "explicit.json"
|
|
monkeypatch.setenv("OPENCLAW_CONFIG_PATH", str(explicit))
|
|
assert cli_clients._openclaw_config_path() == explicit
|
|
|
|
monkeypatch.delenv("OPENCLAW_CONFIG_PATH")
|
|
monkeypatch.setenv("OPENCLAW_STATE_DIR", str(tmp_path / "state"))
|
|
assert cli_clients._openclaw_config_path() == tmp_path / "state" / "openclaw.json"
|
|
|
|
|
|
def test_openclaw_model_and_provider_helpers_cover_fallback_shapes() -> None:
|
|
assert cli_clients._openclaw_primary_model({}) is None
|
|
assert cli_clients._openclaw_primary_model({}, ["--model=anthropic/claude"]) == "anthropic/claude"
|
|
assert cli_clients._openclaw_primary_model({}, ["-m", "openai/gpt-5"]) == "openai/gpt-5"
|
|
assert cli_clients._openclaw_primary_model({"agents": {"defaults": {"model": "openai/gpt-5"}}}) == "openai/gpt-5"
|
|
assert (
|
|
cli_clients._openclaw_primary_model({"agents": {"defaults": {"models": {"anthropic/claude": {}}}}})
|
|
== "anthropic/claude"
|
|
)
|
|
assert (
|
|
cli_clients._openclaw_primary_model({"agents": {"defaults": {"model": {"primary": "openrouter/auto"}}}})
|
|
== "openrouter/auto"
|
|
)
|
|
|
|
assert cli_clients._openclaw_provider_proxy_url({}, "http://127.0.0.1:43123") == "http://127.0.0.1:43123/v1"
|
|
assert (
|
|
cli_clients._openclaw_provider_proxy_url({"api": "openai-responses"}, "http://127.0.0.1:43123")
|
|
== "http://127.0.0.1:43123/v1"
|
|
)
|
|
assert (
|
|
cli_clients._openclaw_provider_proxy_url({"api": "anthropic"}, "http://127.0.0.1:43123")
|
|
== "http://127.0.0.1:43123"
|
|
)
|
|
assert (
|
|
cli_clients._openclaw_provider_target_url({"api": "openai-responses"}, "https://relay.example.com/v1/")
|
|
== "https://relay.example.com"
|
|
)
|
|
assert (
|
|
cli_clients._openclaw_provider_target_url({"api": "anthropic"}, "https://relay.example.com/anthropic/")
|
|
== "https://relay.example.com/anthropic"
|
|
)
|
|
|
|
|
|
def test_openclaw_config_patch_rejects_incomplete_configs() -> None:
|
|
proxy_url = "http://127.0.0.1:43123"
|
|
|
|
assert cli_clients._openclaw_config_with_proxy({}, proxy_url) is None
|
|
assert cli_clients._openclaw_config_with_proxy({"agents": {"defaults": {"model": "claude"}}}, proxy_url) is None
|
|
assert cli_clients._openclaw_config_with_proxy({"agents": {"defaults": {"model": "openai/gpt"}}}, proxy_url) is None
|
|
assert (
|
|
cli_clients._openclaw_config_with_proxy(
|
|
{"agents": {"defaults": {"model": "openai/gpt"}}, "models": {"providers": {}}},
|
|
proxy_url,
|
|
)
|
|
is None
|
|
)
|
|
|
|
|
|
def test_openclaw_reverse_env_falls_back_without_patchable_config(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
monkeypatch.setenv("OPENCLAW_CONFIG_PATH", str(tmp_path / "missing.json"))
|
|
|
|
env = cli_clients._openclaw_reverse_env(43123)
|
|
|
|
assert env == {"OPENAI_BASE_URL": "http://127.0.0.1:43123/v1"}
|
|
|
|
assert cli_clients._openclaw_reverse_env(43123, ["--model", "anthropic/claude"]) == {
|
|
"ANTHROPIC_BASE_URL": "http://127.0.0.1:43123"
|
|
}
|
|
|
|
monkeypatch.setenv("OPENAI_API_KEY", "openai-token")
|
|
monkeypatch.setenv("ANTHROPIC_API_KEY", "anthropic-token")
|
|
assert cli_clients._openclaw_reverse_env(43123) == {"OPENAI_BASE_URL": "http://127.0.0.1:43123/v1"}
|
|
|
|
monkeypatch.delenv("OPENAI_API_KEY")
|
|
assert cli_clients._openclaw_reverse_env(43123) == {"ANTHROPIC_BASE_URL": "http://127.0.0.1:43123"}
|
|
|
|
|
|
def test_detect_openclaw_target_uses_config_then_env(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
config = tmp_path / "openclaw.json"
|
|
config.write_text(
|
|
json.dumps(
|
|
{
|
|
"agents": {"defaults": {"model": "openai/gpt-5"}},
|
|
"models": {"providers": {"openai": {"baseUrl": "https://relay.example.com/v1/"}}},
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
monkeypatch.setenv("OPENCLAW_CONFIG_PATH", str(config))
|
|
|
|
assert cli_clients._detect_openclaw_target() == "https://relay.example.com"
|
|
|
|
config.write_text("{}", encoding="utf-8")
|
|
monkeypatch.setenv("OPENROUTER_API_KEY", "token")
|
|
|
|
assert cli_clients._detect_openclaw_target() == "https://openrouter.ai/api/v1"
|
|
|
|
|
|
def test_detect_openclaw_target_uses_model_arg_provider(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
tmp_path: Path,
|
|
) -> None:
|
|
config = tmp_path / "openclaw.json"
|
|
config.write_text(
|
|
json.dumps(
|
|
{
|
|
"agents": {"defaults": {"model": {"primary": "openai/default"}}},
|
|
"models": {
|
|
"providers": {
|
|
"openai": {"baseUrl": "https://openai.example.com/v1", "api": "openai-responses"},
|
|
"anthropic": {"baseUrl": "https://anthropic.example.com", "api": "anthropic-messages"},
|
|
}
|
|
},
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
monkeypatch.setenv("OPENCLAW_CONFIG_PATH", str(config))
|
|
|
|
assert cli_clients._detect_openclaw_target(["--model", "anthropic/claude-opus-4-6"]) == (
|
|
"https://anthropic.example.com"
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_client_agy_forward_sets_proxy_ca_and_cloud_code_url(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
captured: dict[str, object] = {}
|
|
|
|
async def fake_create_subprocess_exec(*cmd, **kwargs):
|
|
captured["cmd"] = cmd
|
|
captured["env"] = kwargs["env"]
|
|
return _DummyProc()
|
|
|
|
monkeypatch.setattr("claude_tap.cli.shutil.which", lambda name: f"/tmp/{name}")
|
|
monkeypatch.setattr(asyncio, "create_subprocess_exec", fake_create_subprocess_exec)
|
|
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
|
|
|
code = await run_client(
|
|
43123,
|
|
["--print", "ok"],
|
|
client="agy",
|
|
proxy_mode="forward",
|
|
ca_cert_path=Path("/tmp/claude-tap-ca.pem"),
|
|
)
|
|
|
|
assert code == 0
|
|
env = captured["env"]
|
|
assert env["HTTPS_PROXY"] == "http://127.0.0.1:43123"
|
|
assert env["CLOUD_CODE_URL"] == "http://127.0.0.1:43123"
|
|
assert "AGY_BASE_URL" not in env
|
|
assert captured["cmd"] == ("/tmp/agy", "--print", "ok")
|
|
|
|
out = capsys.readouterr().out
|
|
assert "HTTPS_PROXY=http://127.0.0.1:43123" in out
|
|
assert "CLOUD_CODE_URL=http://127.0.0.1:43123" in out
|