8ed8750160
CI / push-validation (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 30s
CI / build (pull_request) Successful in 43s
CI / lint (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 54s
CI / typecheck (pull_request) Successful in 57s
CI / security (pull_request) Successful in 1m28s
CI / integration_tests (pull_request) Successful in 3m4s
CI / unit_tests (pull_request) Successful in 7m30s
CI / docker (pull_request) Failing after 14m0s
CI / coverage (pull_request) Failing after 21m7s
CI / status-check (pull_request) Has been cancelled
AuditService.record() was generating its own timestamp internally, discarding the original DomainEvent.timestamp. This means audit entries recorded when an event was audited, not when the domain event actually occurred, breaking forensic accuracy per §Audit Logging (SEC7). Changes: - Add `timestamp: datetime | None = None` keyword parameter to AuditService.record(). When provided, uses it as created_at; falls back to datetime.now(tz=UTC) for backward compatibility. Applied to both the async queue path and the synchronous DB path. - AuditEventSubscriber._handle_event() now passes timestamp=event.timestamp so the original event creation time is preserved in audit entries. - Add 3 Behave BDD scenarios covering: full pipeline timestamp preservation, direct record() with explicit timestamp, and backward compatibility (record() without timestamp auto-generates created_at). - Add preserve_event_timestamp Robot integration test and helper subcommand. - Add static source check in security_audit.robot verifying the timestamp parameter signature exists. ISSUES CLOSED: #719
101 lines
4.1 KiB
Plaintext
101 lines
4.1 KiB
Plaintext
*** Settings ***
|
|
Documentation SEC7 - Audit logging integration smoke tests
|
|
Library OperatingSystem
|
|
Library Process
|
|
|
|
*** Variables ***
|
|
${AUDIT_SERVICE} ${CURDIR}/../src/cleveragents/application/services/audit_service.py
|
|
${AUDIT_CLI} ${CURDIR}/../src/cleveragents/cli/commands/audit.py
|
|
${AUDIT_MODEL} ${CURDIR}/../src/cleveragents/infrastructure/database/models.py
|
|
${AUDIT_DOC} ${CURDIR}/../docs/reference/audit_logging.md
|
|
|
|
*** Test Cases ***
|
|
Audit Service Module Exists
|
|
[Documentation] Verify the audit service module is present
|
|
File Should Exist ${AUDIT_SERVICE}
|
|
|
|
Audit CLI Module Exists
|
|
[Documentation] Verify the audit CLI module is present
|
|
File Should Exist ${AUDIT_CLI}
|
|
|
|
Audit Log Model Defined
|
|
[Documentation] Verify AuditLogModel is defined in models.py
|
|
${content}= Get File ${AUDIT_MODEL}
|
|
Should Contain ${content} class AuditLogModel
|
|
Should Contain ${content} audit_log
|
|
Should Contain ${content} event_type
|
|
Should Contain ${content} plan_id
|
|
Should Contain ${content} details
|
|
Should Contain ${content} created_at
|
|
|
|
Audit Service Has Record Method
|
|
[Documentation] Verify the audit service has a record method
|
|
${content}= Get File ${AUDIT_SERVICE}
|
|
Should Contain ${content} def record(
|
|
Should Contain ${content} event_type
|
|
Should Contain ${content} VALID_EVENT_TYPES
|
|
|
|
Audit Service Has List Method
|
|
[Documentation] Verify the audit service has a list_entries method
|
|
${content}= Get File ${AUDIT_SERVICE}
|
|
Should Contain ${content} def list_entries(
|
|
Should Contain ${content} plan_id
|
|
Should Contain ${content} project_name
|
|
Should Contain ${content} since
|
|
|
|
Audit Service Has Prune Method
|
|
[Documentation] Verify the audit service has a prune method
|
|
${content}= Get File ${AUDIT_SERVICE}
|
|
Should Contain ${content} def prune(
|
|
Should Contain ${content} retention_days
|
|
|
|
Audit Service Has Thread Safe Session Init
|
|
[Documentation] Verify _ensure_session() uses threading.Lock (bug #991 fix)
|
|
${content}= Get File ${AUDIT_SERVICE}
|
|
Should Contain ${content} import threading
|
|
Should Contain ${content} _session_lock
|
|
Should Contain ${content} threading.Lock()
|
|
|
|
Audit Service Has Close And Context Manager
|
|
[Documentation] Verify the audit service supports close() and context manager
|
|
${content}= Get File ${AUDIT_SERVICE}
|
|
Should Contain ${content} def close(
|
|
Should Contain ${content} def __enter__(
|
|
Should Contain ${content} def __exit__(
|
|
|
|
Audit CLI Has List Command
|
|
[Documentation] Verify the audit CLI has a list command
|
|
${content}= Get File ${AUDIT_CLI}
|
|
Should Contain ${content} name="list"
|
|
Should Contain ${content} --plan
|
|
Should Contain ${content} --project
|
|
Should Contain ${content} --since
|
|
|
|
Audit CLI Has Show Command
|
|
[Documentation] Verify the audit CLI has a show command
|
|
${content}= Get File ${AUDIT_CLI}
|
|
Should Contain ${content} name="show"
|
|
Should Contain ${content} audit_id
|
|
|
|
Audit CLI Has Prune Command
|
|
[Documentation] Verify the audit CLI has a prune command
|
|
${content}= Get File ${AUDIT_CLI}
|
|
Should Contain ${content} name="prune"
|
|
Should Contain ${content} --days
|
|
Should Contain ${content} --yes
|
|
|
|
Audit Documentation Exists
|
|
[Documentation] Verify the audit logging reference doc exists
|
|
File Should Exist ${AUDIT_DOC}
|
|
${content}= Get File ${AUDIT_DOC}
|
|
Should Contain ${content} Audit Logging
|
|
Should Contain ${content} agents audit list
|
|
Should Contain ${content} agents audit show
|
|
Should Contain ${content} agents audit prune
|
|
|
|
Audit Service Record Accepts Timestamp Parameter
|
|
[Documentation] Verify AuditService.record() has a timestamp parameter (issue #719)
|
|
${content}= Get File ${AUDIT_SERVICE}
|
|
Should Contain ${content} timestamp: datetime | None = None
|
|
Should Contain ${content} audit_retention_days
|