iridium-db 0.4.0

A high-performance vector-graph hybrid storage and indexing engine
use super::*;
use std::sync::{Mutex, OnceLock};

fn metrics_test_lock() -> &'static Mutex<()> {
    static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
    LOCK.get_or_init(|| Mutex::new(()))
}

#[test]
fn metrics_record_and_snapshot() {
    let _guard = metrics_test_lock()
        .lock()
        .expect("metrics test lock poisoned");
    reset_metrics();
    record_query_success(100);
    record_query_success(200);
    record_query_error();
    record_ingest(10, 2);

    let m = metrics_snapshot();
    assert_eq!(m.query_total, 3);
    assert_eq!(m.query_errors, 1);
    assert_eq!(m.query_avg_latency_micros, 100);
    assert!(m.query_p95_latency_micros >= 200);
    assert!(m.query_p99_latency_micros >= m.query_p95_latency_micros);
    assert_eq!(m.ingest_accepted, 10);
    assert_eq!(m.ingest_rejected, 2);
}

#[test]
fn health_reports_degraded_or_unhealthy() {
    let _guard = metrics_test_lock()
        .lock()
        .expect("metrics test lock poisoned");
    reset_metrics();
    for _ in 0..9 {
        record_query_success(50);
    }
    record_query_error();
    let degraded = health();
    assert!(matches!(degraded.status, HealthStatus::Degraded));

    reset_metrics();
    for _ in 0..3 {
        record_query_success(50);
    }
    for _ in 0..2 {
        record_query_error();
    }
    let unhealthy = health();
    assert!(matches!(unhealthy.status, HealthStatus::Unhealthy));
}

#[test]
fn metrics_prometheus_text_contains_expected_series() {
    let _guard = metrics_test_lock()
        .lock()
        .expect("metrics test lock poisoned");
    reset_metrics();
    record_query_success(75);
    record_query_error();
    record_ingest(12, 3);
    let text = metrics_prometheus_text();
    assert!(text.contains("iridium_query_total 2"));
    assert!(text.contains("iridium_query_errors 1"));
    assert!(text.contains("iridium_query_p99_latency_micros"));
    assert!(text.contains("iridium_ingest_accepted 12"));
    assert!(text.contains("iridium_ingest_rejected 3"));
}

#[test]
fn background_job_tracker_lifecycle_transitions_are_deterministic() {
    let mut tracker = BackgroundJobTracker::new(BackgroundJobConfig::default()).unwrap();
    let job_id = tracker.submit("compaction").unwrap();
    let started = tracker.start_next().expect("queued job");
    assert_eq!(started, job_id);
    tracker.mark_succeeded(job_id).unwrap();

    let status = tracker.status(job_id).expect("job status");
    assert_eq!(status.attempts, 1);
    assert!(matches!(status.state, BackgroundJobState::Succeeded));
    assert_eq!(tracker.queued_jobs(), 0);
}

#[test]
fn background_job_tracker_applies_backpressure_and_shutdown() {
    let mut tracker = BackgroundJobTracker::new(BackgroundJobConfig {
        max_queued_jobs: 1,
        max_retained_terminal_jobs: 8,
    })
    .unwrap();
    tracker.submit("compaction").unwrap();
    let err = tracker.submit("rebuild").unwrap_err();
    assert!(matches!(err, BackgroundJobError::Backpressure { .. }));

    let canceled = tracker.request_shutdown();
    assert_eq!(canceled, 1);
    assert!(tracker.is_shutdown());

    let shutdown_err = tracker.submit("other").unwrap_err();
    assert!(matches!(shutdown_err, BackgroundJobError::Shutdown));
}

#[test]
fn background_job_tracker_prunes_old_terminal_history() {
    let mut tracker = BackgroundJobTracker::new(BackgroundJobConfig {
        max_queued_jobs: 8,
        max_retained_terminal_jobs: 2,
    })
    .unwrap();

    let a = tracker.submit("a").unwrap();
    let b = tracker.submit("b").unwrap();
    let c = tracker.submit("c").unwrap();

    for _ in 0..3 {
        let job_id = tracker.start_next().expect("start");
        tracker.mark_succeeded(job_id).unwrap();
    }

    assert!(tracker.status(a).is_none());
    assert!(tracker.status(b).is_some());
    assert!(tracker.status(c).is_some());
}

#[test]
fn background_job_tracker_retry_increments_attempts() {
    let mut tracker = BackgroundJobTracker::new(BackgroundJobConfig::default()).unwrap();
    let job_id = tracker.submit("compaction").unwrap();
    let started = tracker.start_next().unwrap();
    assert_eq!(started, job_id);
    let attempts = tracker.retry_running(job_id).unwrap();
    assert_eq!(attempts, 2);
    tracker.mark_succeeded(job_id).unwrap();
}

#[test]
fn core_metrics_snapshot_and_aggregate_are_deterministic() {
    let _guard = metrics_test_lock()
        .lock()
        .expect("metrics test lock poisoned");
    reset_metrics();
    record_query_success_for_core(0, 100);
    record_query_success_for_core(0, 300);
    record_query_error_for_core(1);
    record_ingest_for_core(0, 10, 2);
    record_ingest_for_core(1, 4, 1);

    let by_core = core_metrics_snapshot();
    assert_eq!(by_core.len(), 2);
    assert_eq!(by_core[0].core_id, 0);
    assert_eq!(by_core[0].query_total, 2);
    assert_eq!(by_core[0].query_avg_latency_micros, 200);
    assert_eq!(by_core[1].core_id, 1);
    assert_eq!(by_core[1].query_errors, 1);

    let aggregate = core_metrics_aggregate_snapshot();
    assert_eq!(aggregate.query_total, 3);
    assert_eq!(aggregate.query_errors, 1);
    assert_eq!(aggregate.ingest_accepted, 14);
    assert_eq!(aggregate.ingest_rejected, 3);
}

#[test]
fn alloy_contract_report_acceptance_uses_shared_contracts() {
    let report = contract_report(ContractScenario::Acceptance, "abc1234", 42);
    assert_eq!(report.scope, "phase-1-v0.1");
    assert_eq!(report.telemetry_scope, "phase-2-v1");
    assert!(report.permits_release);
    assert!(report.evidence_artifact_name.contains("acceptance-gate"));
    assert!(report
        .replay_bundle_artifact_name
        .contains("embedded-restart-requery"));
    assert!(report
        .baseline_metric_names
        .contains(&"alloy.operation.duration_ms"));
}

#[test]
fn alloy_contract_report_retrieval_quality_has_expected_trace_and_tags() {
    let report = contract_report(ContractScenario::RetrievalQuality, "def5678", 99);
    assert_eq!(report.trace_operation, "embedded-retrieval-quality");
    assert_eq!(
        report.correlation_id.as_deref(),
        Some("embedded-retrieval-quality")
    );
    assert!(report
        .scenario_manifest_summary
        .contains("retrieval-quality"));
}

#[test]
fn restart_requery_evidence_v1_exposes_typed_strontium_surface() {
    let report = restart_requery_evidence_v1("abc1234", 42);
    assert_eq!(report.schema, "sr.iridium.restart-requery.v1");
    assert_eq!(
        report.workload_identity.workload_id,
        "embedded-restart-requery"
    );
    assert_eq!(
        report.workload_identity.planner_surface,
        "plexus-serialized-plan"
    );
    assert_eq!(report.assertions.len(), 3);
    assert_eq!(report.assertions[0].assertion_id, "restart-recovery");
    assert_eq!(
        report.attached_artifacts[0].artifact_name,
        "durability_verification_report.json"
    );
    assert!(report
        .replay_payload
        .replay_bundle_artifact_name
        .contains("embedded-restart-requery"));
    assert_eq!(
        report.replay_payload.reproduction_commands.len(),
        report.assertions.len()
    );
}

#[test]
fn service_report_uses_shared_phase_4_service_and_phase_2_telemetry_contracts() {
    let report = service_report(Some("0.0.0.0:7443"), 42);
    assert_eq!(report.service_scope, "phase-4-v1");
    assert_eq!(report.deploy_scope, "phase-4-v1");
    assert_eq!(report.telemetry_scope, "phase-2-v1");
    assert_eq!(report.runtime_mode, "service-target");
    assert_eq!(report.profile_id, "single-node-service-v0-1");
    assert_eq!(report.listen_address, "0.0.0.0:7443");
    assert_eq!(report.liveness_path, "/livez");
    assert_eq!(report.readiness_path, "/readyz");
    assert!(report.lifecycle_verbs.contains(&"start"));
    assert!(report.required_env.contains(&"listen_address"));
    assert!(report
        .required_evidence_artifacts
        .contains(&"evidence-report"));
    assert_eq!(report.admin_routes.len(), 2);
    assert!(report.graceful_shutdown.drain_in_flight_requests);
}