Files
Celes Renata c85c0068a2 fix: clean up utcnow deprecation warnings, fix 12 failing tests, add CI/CD pipeline manifests
- Replace all datetime.utcnow() with datetime.now(tz=timezone.utc) across 8 files
- Fix 12 failing tests to match current implementation behavior
- Fix pytest_plugins in non-top-level conftest (moved to root conftest.py)
- Auto-fix 189 lint issues (import sorting, unused imports)
- Add CI/CD pipeline infrastructure (ARC, ArgoCD, Kargo manifests)
- Add values-beta.yaml and values-paper.yaml for staged deployments
- Update GitHub Actions workflow to use self-hosted-gremlin runners
- Add integration-test job to CI pipeline

Result: 1596 passed, 0 failed, 0 warnings
2026-04-18 03:59:28 +00:00

161 lines
5.6 KiB
Python

"""Tests for the execution audit trail module.
Validates audit event construction, event type constants, and the
convenience helpers that record each stage of the execution pipeline.
"""
from services.shared.audit import (
AUDIT_ORDER_CANCELLED,
AUDIT_ORDER_DUPLICATE,
AUDIT_ORDER_FILLED,
AUDIT_ORDER_REJECTED,
AUDIT_ORDER_SUBMITTED,
AUDIT_POSITION_CLOSED,
AUDIT_POSITION_OPENED,
AUDIT_POSITION_UPDATED,
AUDIT_RECOMMENDATION_GENERATED,
AUDIT_RECOMMENDATION_SUPPRESSED,
AUDIT_RISK_EVALUATED,
AUDIT_RISK_REJECTED,
AUDIT_TRADING_MODE_CHANGED,
)
# ---------------------------------------------------------------------------
# Event type constants
# ---------------------------------------------------------------------------
class TestAuditEventTypes:
"""Verify event type constants are well-formed and distinct."""
def test_recommendation_events(self):
assert AUDIT_RECOMMENDATION_GENERATED == "recommendation.generated"
assert AUDIT_RECOMMENDATION_SUPPRESSED == "recommendation.suppressed"
def test_risk_events(self):
assert AUDIT_RISK_EVALUATED == "risk.evaluated"
assert AUDIT_RISK_REJECTED == "risk.rejected"
def test_order_events(self):
assert AUDIT_ORDER_SUBMITTED == "order.submitted"
assert AUDIT_ORDER_FILLED == "order.filled"
assert AUDIT_ORDER_REJECTED == "order.rejected"
assert AUDIT_ORDER_CANCELLED == "order.cancelled"
assert AUDIT_ORDER_DUPLICATE == "order.duplicate_prevented"
def test_position_events(self):
assert AUDIT_POSITION_OPENED == "position.opened"
assert AUDIT_POSITION_CLOSED == "position.closed"
assert AUDIT_POSITION_UPDATED == "position.updated"
def test_trading_mode_event(self):
assert AUDIT_TRADING_MODE_CHANGED == "trading.mode_changed"
def test_all_event_types_unique(self):
all_types = [
AUDIT_RECOMMENDATION_GENERATED,
AUDIT_RECOMMENDATION_SUPPRESSED,
AUDIT_RISK_EVALUATED,
AUDIT_RISK_REJECTED,
AUDIT_ORDER_SUBMITTED,
AUDIT_ORDER_FILLED,
AUDIT_ORDER_REJECTED,
AUDIT_ORDER_CANCELLED,
AUDIT_ORDER_DUPLICATE,
AUDIT_POSITION_OPENED,
AUDIT_POSITION_CLOSED,
AUDIT_POSITION_UPDATED,
AUDIT_TRADING_MODE_CHANGED,
]
assert len(all_types) == len(set(all_types))
def test_event_types_follow_dot_notation(self):
"""All event types should follow entity.action pattern."""
all_types = [
AUDIT_RECOMMENDATION_GENERATED,
AUDIT_RECOMMENDATION_SUPPRESSED,
AUDIT_RISK_EVALUATED,
AUDIT_RISK_REJECTED,
AUDIT_ORDER_SUBMITTED,
AUDIT_ORDER_FILLED,
AUDIT_ORDER_REJECTED,
AUDIT_ORDER_CANCELLED,
AUDIT_ORDER_DUPLICATE,
AUDIT_POSITION_OPENED,
AUDIT_POSITION_CLOSED,
AUDIT_POSITION_UPDATED,
AUDIT_TRADING_MODE_CHANGED,
]
for t in all_types:
assert "." in t, f"Event type {t} should use dot notation"
parts = t.split(".")
assert len(parts) == 2, f"Event type {t} should have exactly one dot"
assert all(p for p in parts), f"Event type {t} has empty parts"
# ---------------------------------------------------------------------------
# Module imports and structure
# ---------------------------------------------------------------------------
class TestAuditModuleStructure:
"""Verify the audit module exports the expected functions."""
def test_record_audit_event_exists(self):
from services.shared.audit import record_audit_event
assert callable(record_audit_event)
def test_convenience_helpers_exist(self):
from services.shared.audit import (
audit_duplicate_prevented,
audit_order_cancelled,
audit_order_filled,
audit_order_rejected,
audit_order_submitted,
audit_position_change,
audit_recommendation_generated,
audit_risk_evaluated,
audit_trading_mode_changed,
)
for fn in [
audit_recommendation_generated,
audit_risk_evaluated,
audit_order_submitted,
audit_order_filled,
audit_order_rejected,
audit_order_cancelled,
audit_duplicate_prevented,
audit_position_change,
audit_trading_mode_changed,
]:
assert callable(fn)
def test_query_helpers_exist(self):
from services.shared.audit import (
get_entity_audit_trail,
get_order_audit_trail,
)
assert callable(get_order_audit_trail)
assert callable(get_entity_audit_trail)
# ---------------------------------------------------------------------------
# Broker service audit integration
# ---------------------------------------------------------------------------
class TestBrokerServiceAuditImports:
"""Verify the broker service uses audit functions from the audit module."""
def test_broker_service_has_audit_calls(self):
"""The broker service module should reference audit functions."""
import inspect
import services.adapters.broker_service as bs
source = inspect.getsource(bs)
assert "audit_order_submitted" in source
assert "audit_order_filled" in source
assert "audit_order_rejected" in source
assert "audit_risk_evaluated" in source
assert "audit_duplicate_prevented" in source