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

124 lines
4.8 KiB
Python

"""Tests for integrations._validation_helpers."""
from __future__ import annotations
import logging
from unittest.mock import MagicMock, patch
from integrations._validation_helpers import report_validation_failure
def _mock_logger() -> MagicMock:
return MagicMock(spec=logging.Logger)
class TestReportValidationFailure:
def test_default_severity_is_warning(self) -> None:
mock_log = _mock_logger()
exc = RuntimeError("boom")
with patch("platform.observability.errors.boundary.capture_exception"):
report_validation_failure(
exc,
logger=mock_log,
integration="trello",
method="validate_trello_config",
)
mock_log.warning.assert_called_once()
mock_log.error.assert_not_called()
def test_message_includes_integration_and_method(self) -> None:
mock_log = _mock_logger()
with patch("platform.observability.errors.boundary.capture_exception"):
report_validation_failure(
RuntimeError("x"),
logger=mock_log,
integration="kafka",
method="get_topic_health",
)
message = mock_log.warning.call_args[0][1]
assert message == "[kafka] get_topic_health validation failed"
def test_tags_have_expected_shape(self) -> None:
mock_log = _mock_logger()
exc = RuntimeError("boom")
with patch("platform.observability.errors.boundary.capture_exception") as mock_cap:
report_validation_failure(
exc,
logger=mock_log,
integration="postgresql",
method="get_server_status",
)
extra = mock_cap.call_args[1]["extra"]
assert extra["tag.surface"] == "integration"
assert extra["tag.integration"] == "postgresql"
assert extra["tag.event"] == "validation_failed"
assert extra["tag.method"] == "get_server_status"
def test_extras_pass_through_unprefixed(self) -> None:
mock_log = _mock_logger()
with patch("platform.observability.errors.boundary.capture_exception") as mock_cap:
report_validation_failure(
RuntimeError("x"),
logger=mock_log,
integration="airflow",
method="get_recent_airflow_failures.task_instances",
extras={"dag_id": "dag-42", "dag_run_id": "run-7"},
)
extra = mock_cap.call_args[1]["extra"]
assert extra["dag_id"] == "dag-42"
assert extra["dag_run_id"] == "run-7"
# extras should NOT be prefixed with "tag." (they're not Sentry tags)
assert "tag.dag_id" not in extra
assert "tag.dag_run_id" not in extra
def test_severity_override_routes_to_logger(self) -> None:
mock_log = _mock_logger()
with patch("platform.observability.errors.boundary.capture_exception"):
report_validation_failure(
RuntimeError("x"),
logger=mock_log,
integration="mongodb",
method="get_server_status",
severity="error",
)
mock_log.error.assert_called_once()
mock_log.warning.assert_not_called()
def test_default_suppresses_terminal_traceback(self) -> None:
"""Validator failures must not dump a stack trace into the REPL by default."""
mock_log = _mock_logger()
with patch("platform.observability.errors.boundary.capture_exception"):
report_validation_failure(
RuntimeError("boom"),
logger=mock_log,
integration="github_mcp",
method="validate_github_mcp_config",
)
assert mock_log.warning.call_args.kwargs["exc_info"] is False
def test_traceback_included_when_explicitly_requested(self) -> None:
mock_log = _mock_logger()
exc = RuntimeError("boom")
with patch("platform.observability.errors.boundary.capture_exception"):
report_validation_failure(
exc,
logger=mock_log,
integration="github_mcp",
method="validate_github_mcp_config",
include_traceback=True,
)
assert mock_log.warning.call_args.kwargs["exc_info"] is exc
def test_captures_to_sentry_exactly_once(self) -> None:
mock_log = _mock_logger()
exc = RuntimeError("once")
with patch("platform.observability.errors.boundary.capture_exception") as mock_cap:
report_validation_failure(
exc,
logger=mock_log,
integration="mysql",
method="validate_mysql_config",
)
mock_cap.assert_called_once()
assert mock_cap.call_args[0][0] is exc