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
137 lines
4.1 KiB
Python
137 lines
4.1 KiB
Python
"""
|
|
Test alert factory with optional remote submission.
|
|
|
|
Verifies alert creation and optional remote submission.
|
|
"""
|
|
|
|
import os
|
|
from datetime import UTC, datetime
|
|
|
|
import pytest
|
|
import requests
|
|
|
|
from config.grafana_cloud import load_env
|
|
from tests.utils.alert_factory.factory import create_alert, from_pipeline_run
|
|
from tests.utils.alert_factory.formatters.grafana import format_as_grafana
|
|
from tests.utils.alert_factory.intent import AlertIntent
|
|
|
|
load_env()
|
|
|
|
|
|
def test_alert_intent_creation():
|
|
"""Test that AlertIntent captures core information correctly."""
|
|
timestamp = datetime.now(UTC).isoformat()
|
|
intent = AlertIntent(
|
|
pipeline_name="test_pipeline",
|
|
run_name="test_run_001",
|
|
status="failed",
|
|
timestamp=timestamp,
|
|
severity="warning",
|
|
alert_name="CustomAlert",
|
|
environment="staging",
|
|
annotations={"foo": "bar"},
|
|
)
|
|
|
|
assert intent.pipeline_name == "test_pipeline"
|
|
assert intent.severity == "warning"
|
|
assert intent.alert_name == "CustomAlert"
|
|
assert intent.environment == "staging"
|
|
assert intent.annotations["foo"] == "bar"
|
|
|
|
|
|
def test_grafana_formatter():
|
|
"""Test that Grafana formatter renders intent correctly."""
|
|
timestamp = datetime.now(UTC).isoformat()
|
|
intent = AlertIntent(
|
|
pipeline_name="test_pipeline",
|
|
run_name="test_run_001",
|
|
status="failed",
|
|
timestamp=timestamp,
|
|
)
|
|
|
|
payload = format_as_grafana(intent)
|
|
|
|
assert payload["alerts"][0]["labels"]["pipeline_name"] == "test_pipeline"
|
|
assert payload["alerts"][0]["labels"]["alertname"] == "PipelineFailure"
|
|
assert payload["alerts"][0]["labels"]["severity"] == "critical"
|
|
assert payload["alerts"][0]["labels"]["environment"] == "production"
|
|
|
|
|
|
def test_factory_from_pipeline_run():
|
|
"""Test that from_pipeline_run produces valid payloads."""
|
|
timestamp = datetime.now(UTC).isoformat()
|
|
payload = from_pipeline_run(
|
|
pipeline_name="test_pipeline",
|
|
run_name="test_run_001",
|
|
status="failed",
|
|
timestamp=timestamp,
|
|
severity="high",
|
|
alert_name="FailureEvent",
|
|
)
|
|
|
|
assert payload["alerts"][0]["labels"]["severity"] == "high"
|
|
assert payload["alerts"][0]["labels"]["alertname"] == "FailureEvent"
|
|
|
|
|
|
def test_create_alert_backwards_compatibility():
|
|
"""Test that create_alert still works as expected."""
|
|
timestamp = datetime.now(UTC).isoformat()
|
|
alert = create_alert(
|
|
pipeline_name="test_pipeline",
|
|
run_name="test_run_001",
|
|
status="failed",
|
|
timestamp=timestamp,
|
|
annotations={"test_key": "test_value"},
|
|
)
|
|
|
|
assert alert is not None
|
|
assert "alerts" in alert
|
|
assert alert["version"] == "4"
|
|
assert "test_key" in alert["commonAnnotations"]
|
|
|
|
|
|
def test_fire_alert_to_remote_platform():
|
|
"""Test firing alert to a configured remote investigation stream URL."""
|
|
endpoint = os.getenv("OPENSRE_REMOTE_RUN_URL")
|
|
|
|
if not endpoint or "localhost" in endpoint:
|
|
pytest.skip("Remote OPENSRE_REMOTE_RUN_URL not configured")
|
|
|
|
timestamp = datetime.now(UTC).isoformat()
|
|
|
|
alert = create_alert(
|
|
pipeline_name="alert_factory_test",
|
|
run_name=f"test_run_{datetime.now(UTC).strftime('%Y%m%d_%H%M%S')}",
|
|
status="failed",
|
|
timestamp=timestamp,
|
|
annotations={
|
|
"test_source": "alert_factory_remote_test",
|
|
"error": "Test alert from alert factory",
|
|
},
|
|
)
|
|
|
|
payload = {
|
|
"input": {
|
|
"alert_name": "Alert factory test",
|
|
"pipeline_name": "alert_factory_test",
|
|
"severity": "critical",
|
|
"raw_alert": alert,
|
|
},
|
|
"config": {
|
|
"metadata": {
|
|
"test": "alert_factory_remote",
|
|
}
|
|
},
|
|
"stream_mode": ["values"],
|
|
}
|
|
|
|
response = requests.post(endpoint, json=payload, timeout=30)
|
|
|
|
assert response.status_code == 200, f"Failed to fire alert: {response.text}"
|
|
print(f"✓ Alert fired to remote platform: {endpoint}")
|
|
print(f" Status: {response.status_code}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"])
|