Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

256 lines
10 KiB
Python

"""Tests for Helm CLI client behavior."""
from __future__ import annotations
from types import SimpleNamespace
from typing import Any
import pytest
from integrations.config_models import HelmIntegrationConfig
from integrations.helm.client import HelmClient, _helm_client_major_version
_HELM_V3_VERSION_STDOUT = (
'Client: version.BuildInfo{Version:"v3.14.0", GitCommit:"abc", GoVersion:"go1.22"}\n'
)
def _client() -> HelmClient:
return HelmClient(
HelmIntegrationConfig(
helm_path="helm",
kube_context="",
kubeconfig="",
default_namespace="",
integration_id="test",
)
)
def test_helm_probe_missing_binary(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: None)
client = _client()
result = client.probe_access()
assert result.status == "missing"
assert "not found" in result.detail.lower()
def test_helm_client_major_version_parses_helm2_and_helm3_output() -> None:
assert (
_helm_client_major_version('Client: &version.Version{SemVer:"v2.17.0", GitCommit:""}') == 2
)
assert _helm_client_major_version('version.BuildInfo{Version:"v3.0.0", GitCommit:""}') == 3
def test_helm_probe_passes_when_version_and_list_succeed(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/usr/bin/helm")
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
if "version" in cmd:
return SimpleNamespace(returncode=0, stdout=_HELM_V3_VERSION_STDOUT, stderr="")
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="[]", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
result = _client().probe_access()
assert result.ok is True
assert "Helm CLI" in result.detail
def test_helm_probe_invokes_helm_version_without_client_flag(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Regression: modern Helm rejects ``helm version --client`` with an unknown-flag error."""
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/usr/bin/helm")
cmds: list[list[str]] = []
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
cmds.append(list(cmd))
if "version" in cmd:
return SimpleNamespace(returncode=0, stdout=_HELM_V3_VERSION_STDOUT, stderr="")
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="[]", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
_client().probe_access()
version_cmds = [c for c in cmds if "version" in c]
assert version_cmds, "probe_access did not invoke `helm version`"
for vc in version_cmds:
assert "--client" not in vc, f"`--client` must not be passed; argv: {vc}"
def test_helm_probe_rejects_helm2_client(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/usr/bin/helm")
helm2_out = 'Client: &version.Version{SemVer:"v2.17.0", GitCommit:""}\n'
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
if "version" in cmd:
return SimpleNamespace(returncode=0, stdout=helm2_out, stderr="")
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="[]", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
result = _client().probe_access()
assert result.ok is False
assert "helm 3" in result.detail.lower()
def test_helm_probe_fails_when_list_stdout_is_not_valid_json(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/usr/bin/helm")
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
if "version" in cmd:
return SimpleNamespace(returncode=0, stdout=_HELM_V3_VERSION_STDOUT, stderr="")
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="WARNING: banner\nnot-json", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
result = _client().probe_access()
assert result.ok is False
assert "json" in result.detail.lower()
def test_helm_probe_fails_when_list_stdout_is_not_a_json_array(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/usr/bin/helm")
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
if "version" in cmd:
return SimpleNamespace(returncode=0, stdout=_HELM_V3_VERSION_STDOUT, stderr="")
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout='{"releases":[]}', stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
result = _client().probe_access()
assert result.ok is False
assert "array" in result.detail.lower()
def test_helm_probe_fails_when_list_stdout_is_empty(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/usr/bin/helm")
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
if "version" in cmd:
return SimpleNamespace(returncode=0, stdout=_HELM_V3_VERSION_STDOUT, stderr="")
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
result = _client().probe_access()
assert result.ok is False
assert "empty" in result.detail.lower()
def test_helm_list_parses_json_array(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/bin/helm")
payload = '[{"name": "demo", "namespace": "demo"}]'
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
return SimpleNamespace(returncode=0, stdout=payload, stderr="")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
out = _client().list_releases(all_namespaces=True, max_releases=10)
assert out["success"] is True
assert out["releases"][0]["name"] == "demo"
def test_helm_list_reports_all_namespaces_when_cli_uses_dash_a_with_empty_namespace(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Default branch passes `-A`; response metadata must not claim single-namespace mode."""
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/bin/helm")
cmds: list[list[str]] = []
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
cmds.append(list(cmd))
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="[]", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
out = _client().list_releases(all_namespaces=False, namespace="", max_releases=10)
assert out["success"] is True
assert out["all_namespaces"] is True
assert any(part == "-A" for part in cmds[0])
def test_helm_list_reports_single_namespace_when_cli_uses_dash_n(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/bin/helm")
cmds: list[list[str]] = []
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
cmds.append(list(cmd))
if "list" in cmd:
return SimpleNamespace(returncode=0, stdout="[]", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
out = _client().list_releases(all_namespaces=False, namespace="prod", max_releases=10)
assert out["success"] is True
assert out["all_namespaces"] is False
assert out["namespace"] == "prod"
assert "-n" in cmds[0] and "prod" in cmds[0]
def test_helm_status_requires_release_name(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/bin/helm")
out = _client().release_status("", "demo")
assert out["success"] is False
assert "required" in out["error"].lower()
def test_helm_get_values_treats_json_null_as_empty_dict(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Helm 3 prints the JSON literal null for releases installed without custom values."""
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/bin/helm")
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
for i, part in enumerate(cmd):
if part == "get" and i + 1 < len(cmd) and cmd[i + 1] == "values":
return SimpleNamespace(returncode=0, stdout="null\n", stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
out = _client().get_values("my-release", "default")
assert out["success"] is True
assert out["values"] == {}
assert out["release"] == "my-release"
assert out["namespace"] == "default"
def test_helm_get_manifest_truncates_using_helm_manifest_max_chars_env(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv("HELM_MANIFEST_MAX_CHARS", "5000")
monkeypatch.setattr("integrations.helm.client.shutil.which", lambda _name: "/bin/helm")
payload = "x" * 8000
def fake_run(cmd: list[str], **_kwargs: Any) -> SimpleNamespace:
for i, part in enumerate(cmd):
if part == "get" and i + 1 < len(cmd) and cmd[i + 1] == "manifest":
return SimpleNamespace(returncode=0, stdout=payload, stderr="")
return SimpleNamespace(returncode=1, stdout="", stderr="unexpected argv")
monkeypatch.setattr("integrations.helm.client.subprocess.run", fake_run)
out = _client().get_manifest("rel", "ns")
assert out["success"] is True
assert len(out["manifest"]) == 5000
assert out["truncated"] is True