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
124 lines
4.8 KiB
Python
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
|