agent-governance/.archive/tests/test_phase9_integrations.py
profit 8c6e7831e9 Add Phase 10-12 implementation: multi-tenant, marketplace, observability
Major additions:
- marketplace/: Agent template registry with FTS5 search, ratings, versioning
- observability/: Prometheus metrics, distributed tracing, structured logging
- ledger/migrations/: Database migration scripts for multi-tenant support
- tests/governance/: 15 new test files for phases 6-12 (295 total tests)
- bin/validate-phases: Full 12-phase validation script

New features:
- Multi-tenant support with tenant isolation and quota enforcement
- Agent marketplace with semantic versioning and search
- Observability with metrics, tracing, and log correlation
- Tier-1 agent bootstrap scripts

Updated components:
- ledger/api.py: Extended API for tenants, marketplace, observability
- ledger/schema.sql: Added tenant, project, marketplace tables
- testing/framework.ts: Enhanced test framework
- checkpoint/checkpoint.py: Improved checkpoint management

Archived:
- External integrations (Slack/GitHub/PagerDuty) moved to .archive/
- Old checkpoint files cleaned up

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 18:39:47 -05:00

232 lines
6.3 KiB
Python

"""
Phase 9: External Integrations Tests
====================================
Tests for webhook delivery and notification paths.
Required tests:
- github_webhook: Verify GitHub event handling in dry-run
- slack_notification: Verify Slack notification dispatch in dry-run
- webhook_delivery: Verify IntegrationManager broadcast delivery
"""
import os
import sys
from pathlib import Path
# Add integrations to path
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "integrations"))
PASSED = 0
FAILED = 0
def log(msg: str, status: str = "info"):
icons = {"pass": "\033[92m✓\033[0m", "fail": "\033[91m✗\033[0m", "info": ""}
print(f" {icons.get(status, '')} {msg}")
def load_module(name: str, path: Path):
import importlib.util
spec = importlib.util.spec_from_file_location(name, path)
if spec is None or spec.loader is None:
raise ImportError(f"Module spec missing for {name}")
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
return module
def test_github_webhook():
"""Test GitHub webhook handling in dry-run mode"""
global PASSED, FAILED
print("\n[TEST] github_webhook")
os.environ["INTEGRATION_DRY_RUN"] = "true"
os.environ["GITHUB_TOKEN"] = "ghp_test_token"
os.environ["GITHUB_REPO"] = "example/repo"
try:
base = load_module(
"common.base",
Path(__file__).parent.parent.parent / "integrations" / "common" / "base.py",
)
github = load_module(
"github.github",
Path(__file__).parent.parent.parent
/ "integrations"
/ "github"
/ "github.py",
)
except ImportError as e:
log(f"GitHub import failed: {e}", "fail")
FAILED += 1
return False
gh = github.GitHubIntegration()
event = base.IntegrationEvent(
event_type="plan_created",
source="agent-001",
data={"plan": {"title": "Test Plan", "objective": "Verify webhook"}},
)
if gh.send_event(event):
log("GitHub plan event handled", "pass")
PASSED += 1
else:
log("GitHub plan event failed", "fail")
FAILED += 1
audit = gh.get_audit_log()
if any(entry.get("operation") == "create_pr" for entry in audit):
log("GitHub create_pr audit recorded", "pass")
PASSED += 1
else:
log("GitHub create_pr audit missing", "fail")
FAILED += 1
return True
def test_slack_notification():
"""Test Slack notification dispatch in dry-run mode"""
global PASSED, FAILED
print("\n[TEST] slack_notification")
os.environ["INTEGRATION_DRY_RUN"] = "true"
os.environ["SLACK_BOT_TOKEN"] = "xoxb-test-token"
os.environ["SLACK_WEBHOOK_URL"] = "https://hooks.slack.com/test"
try:
base = load_module(
"common.base",
Path(__file__).parent.parent.parent / "integrations" / "common" / "base.py",
)
slack_module = load_module(
"slack.slack",
Path(__file__).parent.parent.parent / "integrations" / "slack" / "slack.py",
)
except ImportError as e:
log(f"Slack import failed: {e}", "fail")
FAILED += 1
return False
slack = slack_module.SlackIntegration()
event = base.IntegrationEvent(
event_type="violation_detected",
source="agent-002",
data={
"violation": {"type": "policy", "severity": "high", "description": "Test"}
},
priority="high",
)
if slack.send_event(event):
log("Slack violation notification dispatched", "pass")
PASSED += 1
else:
log("Slack notification failed", "fail")
FAILED += 1
audit = slack.get_audit_log()
if any(entry.get("operation") == "send_message" for entry in audit):
log("Slack send_message audit recorded", "pass")
PASSED += 1
else:
log("Slack send_message audit missing", "fail")
FAILED += 1
return True
def test_webhook_delivery():
"""Test IntegrationManager broadcast delivery"""
global PASSED, FAILED
print("\n[TEST] webhook_delivery")
os.environ["INTEGRATION_DRY_RUN"] = "true"
os.environ["SLACK_BOT_TOKEN"] = "xoxb-test-token"
os.environ["GITHUB_TOKEN"] = "ghp_test_token"
os.environ["GITHUB_REPO"] = "example/repo"
try:
base = load_module(
"common.base",
Path(__file__).parent.parent.parent / "integrations" / "common" / "base.py",
)
slack_module = load_module(
"slack.slack",
Path(__file__).parent.parent.parent / "integrations" / "slack" / "slack.py",
)
github = load_module(
"github.github",
Path(__file__).parent.parent.parent
/ "integrations"
/ "github"
/ "github.py",
)
except ImportError as e:
log(f"Integration import failed: {e}", "fail")
FAILED += 1
return False
manager = base.IntegrationManager()
manager.register(
slack_module.SlackIntegration(
webhook_url="https://hooks.slack.com/test",
bot_token="xoxb-test-token",
)
)
manager.register(
github.GitHubIntegration(
token="ghp_test_token",
repo="example/repo",
)
)
event = base.IntegrationEvent(
event_type="execution_complete",
source="agent-003",
data={"result": {"success": True, "duration": 4.2}, "commit_sha": "HEAD"},
)
results = manager.broadcast(event)
if results.get("slack") and results.get("github"):
log("Broadcast delivered to Slack and GitHub", "pass")
PASSED += 1
else:
log(f"Broadcast results missing: {results}", "fail")
FAILED += 1
return True
def main():
global PASSED, FAILED
print("\n" + "=" * 60)
print("PHASE 9: EXTERNAL INTEGRATIONS TESTS")
print("=" * 60)
try:
test_github_webhook()
test_slack_notification()
test_webhook_delivery()
except Exception as e:
print(f"\n\033[91mTest execution error: {e}\033[0m")
FAILED += 1
print("\n" + "=" * 60)
print(f"RESULTS: {PASSED} passed, {FAILED} failed")
print("=" * 60 + "\n")
return FAILED == 0
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)