Files
wehub-resource-sync 5296d0e97c
CI / Ban suppressions and legacy annotations (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / ruff-check (push) Has been cancelled
CI / ruff-format (push) Has been cancelled
CI / ty (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:44 +08:00

556 lines
18 KiB
Python

import json
import subprocess
from pathlib import Path
from typing import cast
from free_claude_code.config.settings import Settings
from smoke.lib.claude_cli_matrix import (
ClaudeCliRun,
_build_claude_cli_command,
_subagent_probe_options,
make_outcome,
regression_failures,
run_claude_cli,
write_matrix_report,
)
from smoke.lib.config import DEFAULT_TARGETS, SmokeConfig
from smoke.lib.server import RunningServer
def _smoke_config(tmp_path: Path) -> SmokeConfig:
return SmokeConfig(
root=tmp_path,
results_dir=tmp_path / ".smoke-results",
live=False,
interactive=False,
targets=DEFAULT_TARGETS,
provider_matrix=frozenset(),
timeout_s=45.0,
prompt="Reply with exactly: FCC_SMOKE_PONG",
claude_bin="claude",
worker_id="test-worker",
settings=Settings.model_construct(anthropic_auth_token=""),
)
def test_nvidia_nim_cli_matrix_report_shape_and_redaction(
tmp_path: Path, monkeypatch
) -> None:
monkeypatch.setenv("NVIDIA_NIM_API_KEY", "secret-nim-key")
run = ClaudeCliRun(
command=("claude", "-p", "redacted"),
returncode=0,
stdout="FCC_NIM_BASIC secret-nim-key",
stderr="",
duration_s=1.25,
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="basic_text",
marker="FCC_NIM_BASIC",
run=run,
log_delta='POST /v1/messages HTTP/1.1" 200 OK secret-nim-key',
log_path=tmp_path / "server.log",
)
path = write_matrix_report(
_smoke_config(tmp_path),
[outcome],
target="nvidia_nim_cli",
filename_prefix="nvidia-nim-cli",
)
payload = json.loads(path.read_text(encoding="utf-8"))
assert path.name.startswith("nvidia-nim-cli-matrix-test-worker-")
assert payload["target"] == "nvidia_nim_cli"
assert payload["models"] == ["nvidia_nim/z-ai/glm-5.2"]
saved = payload["outcomes"][0]
assert saved["feature"] == "basic_text"
assert saved["classification"] == "passed"
assert saved["request_count"] == 1
assert saved["token_evidence"]["marker_present"] is True
assert saved["token_evidence"]["agent_catalog_present"] is False
assert saved["token_evidence"]["agent_tool_count"] == 0
assert saved["token_evidence"]["agent_result_count"] == 0
assert "secret-nim-key" not in path.read_text(encoding="utf-8")
def test_cli_matrix_normalizes_missing_captured_output(
tmp_path: Path, monkeypatch
) -> None:
def fake_run_captured_text(
command: list[str],
**_kwargs: object,
) -> subprocess.CompletedProcess[str]:
return cast(
subprocess.CompletedProcess[str],
subprocess.CompletedProcess(
args=command,
returncode=0,
stdout=None,
stderr=None,
),
)
monkeypatch.setattr(
"smoke.lib.claude_cli_matrix.run_captured_text",
fake_run_captured_text,
)
server = RunningServer(
base_url="http://127.0.0.1:9999",
port=9999,
log_path=tmp_path / "server.log",
process=cast(subprocess.Popen[bytes], object()),
)
run = run_claude_cli(
claude_bin="claude",
server=server,
config=_smoke_config(tmp_path),
cwd=tmp_path / "workspace",
prompt="hello",
tools="",
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="basic_text",
marker="FCC_NIM_BASIC",
run=run,
log_delta='POST /v1/messages HTTP/1.1" 200 OK',
log_path=tmp_path / "server.log",
)
assert run.stdout == ""
assert run.stderr == ""
assert outcome.stdout_excerpt == ""
assert outcome.stderr_excerpt == ""
def test_openrouter_free_cli_matrix_report_shape_and_redaction(
tmp_path: Path, monkeypatch
) -> None:
monkeypatch.setenv("OPENROUTER_API_KEY", "secret-openrouter-key")
run = ClaudeCliRun(
command=("claude", "-p", "redacted"),
returncode=0,
stdout="FCC_OPENROUTER_FREE_BASIC secret-openrouter-key",
stderr="",
duration_s=1.25,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="basic_text",
marker="FCC_OPENROUTER_FREE_BASIC",
run=run,
log_delta='POST /v1/messages HTTP/1.1" 200 OK secret-openrouter-key',
log_path=tmp_path / "server.log",
)
path = write_matrix_report(
_smoke_config(tmp_path),
[outcome],
target="openrouter_free_cli",
filename_prefix="openrouter-free-cli",
)
payload = json.loads(path.read_text(encoding="utf-8"))
assert path.name.startswith("openrouter-free-cli-matrix-test-worker-")
assert payload["target"] == "openrouter_free_cli"
assert payload["models"] == ["open_router/openai/gpt-oss-120b:free"]
saved = payload["outcomes"][0]
assert saved["feature"] == "basic_text"
assert saved["classification"] == "passed"
assert saved["request_count"] == 1
assert saved["token_evidence"]["marker_present"] is True
assert saved["token_evidence"]["agent_catalog_present"] is False
assert saved["token_evidence"]["agent_tool_count"] == 0
assert saved["token_evidence"]["agent_result_count"] == 0
assert "secret-openrouter-key" not in path.read_text(encoding="utf-8")
def test_nvidia_nim_cli_matrix_regression_detection(tmp_path: Path) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="basic_text",
marker="FCC_NIM_BASIC",
run=run,
log_delta='POST /v1/messages HTTP/1.1" 500 Internal Server Error',
log_path=tmp_path / "server.log",
)
assert outcome.classification == "product_failure"
assert regression_failures([outcome]) == [
"nvidia_nim/z-ai/glm-5.2 basic_text: product_failure"
]
def test_nvidia_nim_cli_matrix_model_feature_failures_do_not_regress(
tmp_path: Path,
) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="ordinary answer",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="tool_use_roundtrip",
marker="FCC_NIM_TOOL",
run=run,
log_delta='POST /v1/messages HTTP/1.1" 200 OK',
log_path=tmp_path / "server.log",
requires_tool_result=True,
)
assert outcome.classification == "model_feature_failure"
assert regression_failures([outcome]) == []
def test_nvidia_nim_cli_raw_payload_log_counts_as_proxy_request(
tmp_path: Path,
) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="ordinary answer",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="subagent_task",
marker="FCC_NIM_TASK",
run=run,
log_delta="API_REQUEST: request_id=req_1 model=z-ai/glm-5.2 messages=2",
log_path=tmp_path / "server.log",
requires_task=True,
)
assert outcome.classification == "model_feature_failure"
assert outcome.request_count == 1
assert regression_failures([outcome]) == []
def test_cli_matrix_missing_agent_catalog_is_harness_bug(tmp_path: Path) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="ordinary answer",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="subagent_task",
marker="FCC_OPENROUTER_FREE_TASK",
run=run,
log_delta=(
"API_REQUEST: request_id=req_1 model=openai/gpt-oss-120b:free "
"messages=1\n"
"FULL_PAYLOAD [req_1]: {'messages': [], 'tools': [{'name': 'Read'}], "
"'tool_choice': None}"
),
log_path=tmp_path / "server.log",
requires_agent=True,
)
assert outcome.classification == "harness_bug"
assert outcome.token_evidence["agent_catalog_present"] is False
def test_cli_matrix_agent_catalog_without_agent_use_is_model_feature_failure(
tmp_path: Path,
) -> None:
marker = "FCC_OPENROUTER_FREE_TASK"
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout=(
f'{marker}\n{{"type":"tool_use","name":"Read"}}\n{{"type":"tool_result"}}'
),
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="subagent_task",
marker=marker,
run=run,
log_delta=(
"API_REQUEST: request_id=req_1 model=openai/gpt-oss-120b:free "
"messages=1\n"
"FULL_PAYLOAD [req_1]: {'messages': [], 'tools': "
"[{'name': 'Agent'}, {'name': 'Read'}], 'tool_choice': None}"
),
log_path=tmp_path / "server.log",
requires_tool_result=True,
requires_agent=True,
)
assert outcome.classification == "model_feature_failure"
assert outcome.token_evidence["agent_catalog_present"] is True
assert outcome.token_evidence["agent_tool_count"] == 0
def test_cli_matrix_agent_use_result_and_marker_pass(tmp_path: Path) -> None:
marker = "FCC_OPENROUTER_FREE_TASK"
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout=(
f'{marker}\n{{"type":"tool_use","name":"Agent"}}\n'
'{"type":"tool_result","content":"agentId: abc123"}'
),
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="subagent_task",
marker=marker,
run=run,
log_delta=(
"API_REQUEST: request_id=req_1 model=openai/gpt-oss-120b:free "
"messages=1\n"
"FULL_PAYLOAD [req_1]: {'messages': [], 'tools': "
"[{'name': 'Agent'}, {'name': 'Read'}], 'tool_choice': None}"
),
log_path=tmp_path / "server.log",
requires_tool_result=True,
requires_agent=True,
)
assert outcome.classification == "passed"
assert outcome.token_evidence["agent_catalog_present"] is True
assert outcome.token_evidence["agent_tool_count"] == 1
assert outcome.token_evidence["agent_result_count"] == 1
def test_cli_matrix_agent_prompt_text_without_tool_evidence_does_not_pass(
tmp_path: Path,
) -> None:
marker = "FCC_OPENROUTER_FREE_TASK"
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout=f"{marker}\nAgent should read the file.",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="subagent_task",
marker=marker,
run=run,
log_delta=(
"API_REQUEST: request_id=req_1 model=openai/gpt-oss-120b:free "
"messages=1\n"
"FULL_PAYLOAD [req_1]: {'messages': [], 'tools': "
"[{'name': 'Agent'}, {'name': 'Read'}], 'tool_choice': None}"
),
log_path=tmp_path / "server.log",
requires_agent=True,
)
assert outcome.classification == "model_feature_failure"
assert outcome.token_evidence["agent_catalog_present"] is True
assert outcome.token_evidence["agent_tool_count"] == 0
def test_cli_matrix_structured_provider_error_is_upstream_unavailable(
tmp_path: Path,
) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="Provider API request failed. (request_id=req_123)",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="poolside/laguna-m.1:free",
full_model="open_router/poolside/laguna-m.1:free",
source="openrouter_free_cli_default",
feature="tool_use_roundtrip",
marker="FCC_OPENROUTER_FREE_TOOL",
run=run,
log_delta=(
'{"event": "free_claude_code.api.request.received", "http_method": "POST", '
'"http_path": "/v1/messages"}\n'
'{"event": "provider.response.error", "exc_type": "HTTPStatusError"}'
),
log_path=tmp_path / "server.log",
requires_tool_result=True,
)
assert outcome.classification == "upstream_unavailable"
assert outcome.request_count == 1
def test_nvidia_nim_cli_timeout_is_not_model_missing(
tmp_path: Path,
) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=None,
stdout='{"type":"assistant","content":[{"type":"text","text":"FCC_NIM_TOOL"}]}',
stderr="",
duration_s=45.0,
timed_out=True,
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="tool_use_roundtrip",
marker="FCC_NIM_TOOL",
run=run,
log_delta="API_REQUEST: request_id=req_1 model=z-ai/glm-5.2 messages=2",
log_path=tmp_path / "server.log",
)
assert outcome.classification == "probe_timeout"
assert outcome.token_evidence["timed_out"] is True
assert regression_failures([outcome]) == []
def test_nvidia_nim_cli_success_beats_verbose_timeout_words(tmp_path: Path) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="FCC_NIM_THINK",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="z-ai/glm-5.2",
full_model="nvidia_nim/z-ai/glm-5.2",
source="nvidia_nim_cli_default",
feature="thinking",
marker="FCC_NIM_THINK",
run=run,
log_delta=(
"API_REQUEST: request_id=req_1 model=z-ai/glm-5.2 messages=1 "
"read_timeout_s=300"
),
log_path=tmp_path / "server.log",
)
assert outcome.classification == "passed"
assert outcome.request_count == 1
def test_cli_matrix_uuid_429_does_not_count_as_upstream_unavailable(
tmp_path: Path,
) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout='{"uuid":"d3c76eea-3634-4299-aec0-e7634b3716da"}',
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="subagent_task",
marker="FCC_OPENROUTER_FREE_TASK",
run=run,
log_delta="API_REQUEST: request_id=req_1 model=openai/gpt-oss-120b:free messages=2",
log_path=tmp_path / "server.log",
requires_task=True,
)
assert outcome.classification == "model_feature_failure"
def test_cli_matrix_real_http_429_counts_as_upstream_unavailable(
tmp_path: Path,
) -> None:
run = ClaudeCliRun(
command=("claude", "-p", "x"),
returncode=0,
stdout="ordinary answer",
stderr="",
duration_s=0.1,
)
outcome = make_outcome(
model="openai/gpt-oss-120b:free",
full_model="open_router/openai/gpt-oss-120b:free",
source="openrouter_free_cli_default",
feature="subagent_task",
marker="FCC_OPENROUTER_FREE_TASK",
run=run,
log_delta=(
"API_REQUEST: request_id=req_1 model=openai/gpt-oss-120b:free "
'messages=2 upstream HTTP/1.1" 429 Too Many Requests'
),
log_path=tmp_path / "server.log",
requires_task=True,
)
assert outcome.classification == "upstream_unavailable"
def test_cli_matrix_default_command_uses_bare_mode() -> None:
command = _build_claude_cli_command(
claude_bin="claude",
prompt="hello",
tools="Read",
)
assert command[:2] == ("claude", "--bare")
assert "--tools" in command
assert "Read" in command
def test_cli_matrix_subagent_command_uses_agent_without_bare_or_task() -> None:
bare, tools, pre_tool_args, extra_args = _subagent_probe_options("{}")
command = _build_claude_cli_command(
claude_bin="claude",
prompt="hello",
tools=tools,
bare=bare,
pre_tool_args=pre_tool_args,
extra_args=extra_args,
)
assert "--bare" not in command
assert command[command.index("--setting-sources") + 1] == "local"
assert "--strict-mcp-config" in command
assert command[command.index("--mcp-config") + 1] == '{"mcpServers":{}}'
assert command[command.index("--tools") + 1] == "Agent,Read"
assert command[command.index("--allowedTools") + 1] == "Agent,Read"
assert command[command.index("--agents") + 1] == "{}"
assert "Task,Read" not in command