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

189 lines
6.3 KiB
Python

"""Tests for ``*_INSTANCES`` env var parsing in load_env_integrations."""
from __future__ import annotations
import json
import pytest
from integrations.catalog import load_env_integrations
def _clear_env(monkeypatch) -> None:
for key in (
"GRAFANA_INSTANCES",
"GRAFANA_INSTANCE_URL",
"GRAFANA_READ_TOKEN",
"DD_INSTANCES",
"DD_API_KEY",
"DD_APP_KEY",
"DD_SITE",
"HONEYCOMB_INSTANCES",
"HONEYCOMB_API_KEY",
"CORALOGIX_INSTANCES",
"CORALOGIX_API_KEY",
"AWS_INSTANCES",
"AWS_ROLE_ARN",
"AWS_EXTERNAL_ID",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
):
monkeypatch.delenv(key, raising=False)
def test_grafana_instances_json_produces_single_record_with_multiple_instances(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""PR #527 bug #2 regression: env multi-instance must NOT split into N
records, which the merge_integrations_by_service chokepoint would collapse."""
_clear_env(monkeypatch)
monkeypatch.setenv(
"GRAFANA_INSTANCES",
json.dumps(
[
{"name": "prod", "tags": {"env": "prod"}, "endpoint": "https://p", "api_key": "kp"},
{
"name": "staging",
"tags": {"env": "staging"},
"endpoint": "https://s",
"api_key": "ks",
},
]
),
)
records = load_env_integrations()
grafana_records = [r for r in records if r.get("service") == "grafana"]
assert len(grafana_records) == 1 # ← must be exactly one
instances = grafana_records[0]["instances"]
assert [i["name"] for i in instances] == ["prod", "staging"]
assert instances[0]["credentials"]["endpoint"] == "https://p"
assert instances[1]["credentials"]["endpoint"] == "https://s"
def test_grafana_instances_accepts_nested_credentials_shape(
monkeypatch: pytest.MonkeyPatch,
) -> None:
_clear_env(monkeypatch)
monkeypatch.setenv(
"GRAFANA_INSTANCES",
json.dumps(
[
{
"name": "prod",
"tags": {"env": "prod"},
"credentials": {"endpoint": "https://p", "api_key": "kp"},
}
]
),
)
records = load_env_integrations()
grafana = [r for r in records if r.get("service") == "grafana"][0]
creds = grafana["instances"][0]["credentials"]
assert creds == {"endpoint": "https://p", "api_key": "kp"}
def test_bad_json_logs_warning_and_falls_through_to_legacy(
monkeypatch: pytest.MonkeyPatch,
caplog: pytest.LogCaptureFixture,
) -> None:
_clear_env(monkeypatch)
monkeypatch.setenv("GRAFANA_INSTANCES", "this is not json")
monkeypatch.setenv("GRAFANA_INSTANCE_URL", "https://legacy")
monkeypatch.setenv("GRAFANA_READ_TOKEN", "legacy-key")
import logging
with caplog.at_level(logging.WARNING, logger="integrations.catalog"):
records = load_env_integrations()
grafana_records = [r for r in records if r.get("service") == "grafana"]
assert len(grafana_records) == 1
# Falls through to LEGACY shape, not the new instances shape
assert "instances" not in grafana_records[0]
assert grafana_records[0]["credentials"]["endpoint"] == "https://legacy"
assert any("GRAFANA_INSTANCES is not valid JSON" in r.message for r in caplog.records)
def test_instances_env_var_suppresses_legacy_single_var(
monkeypatch: pytest.MonkeyPatch,
) -> None:
_clear_env(monkeypatch)
monkeypatch.setenv(
"GRAFANA_INSTANCES",
json.dumps([{"name": "prod", "endpoint": "https://p", "api_key": "kp"}]),
)
# Also set legacy vars — they must be ignored
monkeypatch.setenv("GRAFANA_INSTANCE_URL", "https://legacy")
monkeypatch.setenv("GRAFANA_READ_TOKEN", "legacy-key")
records = load_env_integrations()
grafana_records = [r for r in records if r.get("service") == "grafana"]
# Exactly one record — legacy vars did NOT create a second one
assert len(grafana_records) == 1
assert "instances" in grafana_records[0]
def test_missing_env_var_uses_legacy_vars(monkeypatch: pytest.MonkeyPatch) -> None:
_clear_env(monkeypatch)
monkeypatch.setenv("GRAFANA_INSTANCE_URL", "https://legacy")
monkeypatch.setenv("GRAFANA_READ_TOKEN", "legacy-key")
records = load_env_integrations()
grafana_records = [r for r in records if r.get("service") == "grafana"]
assert len(grafana_records) == 1
assert "instances" not in grafana_records[0]
assert grafana_records[0]["credentials"]["api_key"] == "legacy-key"
def test_empty_json_array_falls_through_to_legacy(
monkeypatch: pytest.MonkeyPatch,
) -> None:
_clear_env(monkeypatch)
monkeypatch.setenv("GRAFANA_INSTANCES", "[]")
monkeypatch.setenv("GRAFANA_INSTANCE_URL", "https://legacy")
monkeypatch.setenv("GRAFANA_READ_TOKEN", "legacy-key")
records = load_env_integrations()
grafana_records = [r for r in records if r.get("service") == "grafana"]
assert len(grafana_records) == 1
assert "instances" not in grafana_records[0]
@pytest.mark.parametrize(
"env_name,service,entry",
[
(
"DD_INSTANCES",
"datadog",
{"name": "prod", "api_key": "k", "app_key": "a", "site": "datadoghq.com"},
),
(
"HONEYCOMB_INSTANCES",
"honeycomb",
{"name": "prod", "api_key": "k", "dataset": "__all__"},
),
(
"CORALOGIX_INSTANCES",
"coralogix",
{"name": "prod", "api_key": "k", "base_url": "https://api.coralogix.com"},
),
(
"AWS_INSTANCES",
"aws",
{"name": "prod", "role_arn": "arn:aws:iam::1:role/r", "external_id": "e"},
),
],
)
def test_instances_env_var_for_all_5_providers(
monkeypatch: pytest.MonkeyPatch,
env_name: str,
service: str,
entry: dict,
) -> None:
_clear_env(monkeypatch)
monkeypatch.setenv(env_name, json.dumps([entry, {**entry, "name": "staging"}]))
records = load_env_integrations()
service_records = [r for r in records if r.get("service") == service]
assert len(service_records) == 1
assert [i["name"] for i in service_records[0]["instances"]] == ["prod", "staging"]