Codex Handbook
otel/tests/suite/timing.rs 118 lines
use crate::harness::attributes_to_map;use crate::harness::build_metrics_with_defaults;use crate::harness::histogram_data;use crate::harness::latest_metrics;use codex_otel::Result;use pretty_assertions::assert_eq;use std::time::Duration;// Ensures duration recording maps to histogram output.#[test]fn record_duration_records_histogram() -> Result<()> {    let (metrics, exporter) = build_metrics_with_defaults(&[])?;    metrics.record_duration(        "codex.request_latency",        Duration::from_millis(15),        &[("route", "chat")],    )?;    metrics.shutdown()?;    let resource_metrics = latest_metrics(&exporter);    let (bounds, bucket_counts, sum, count) =        histogram_data(&resource_metrics, "codex.request_latency");    assert!(!bounds.is_empty());    assert_eq!(bucket_counts.iter().sum::<u64>(), 1);    assert_eq!(sum, 15.0);    assert_eq!(count, 1);    let metric = crate::harness::find_metric(&resource_metrics, "codex.request_latency")        .expect("codex.request_latency metric should exist");    assert_eq!(metric.unit(), "ms");    assert_eq!(metric.description(), "Duration in milliseconds.");    Ok(())}#[test]fn record_duration_seconds_uses_fractional_seconds_and_scaled_buckets() -> Result<()> {    let (metrics, exporter) = build_metrics_with_defaults(&[])?;    for duration in [        Duration::from_millis(200),        Duration::from_secs(1),        Duration::from_millis(4900),    ] {        metrics.record_duration_seconds_with_description(            "codex.request_duration_seconds",            "Duration of Codex requests in seconds.",            duration,            &[("method", "initialize")],        )?;    }    metrics.shutdown()?;    let resource_metrics = latest_metrics(&exporter);    let (bounds, bucket_counts, sum, count) =        histogram_data(&resource_metrics, "codex.request_duration_seconds");    assert_eq!(        bounds,        vec![            0.0, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0,        ]    );    assert_eq!(        bucket_counts,        vec![0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0]    );    assert!((sum - 6.1).abs() < f64::EPSILON * 8.0);    assert_eq!(count, 3);    let metric = crate::harness::find_metric(&resource_metrics, "codex.request_duration_seconds")        .expect("codex.request_duration_seconds metric should exist");    assert_eq!(metric.unit(), "s");    assert_eq!(        metric.description(),        "Duration of Codex requests in seconds."    );    Ok(())}// Ensures time_result returns the closure output and records timing.#[test]fn timer_result_records_success() -> Result<()> {    let (metrics, exporter) = build_metrics_with_defaults(&[])?;    {        let timer = metrics.start_timer("codex.request_latency", &[("route", "chat")]);        assert!(timer.is_ok());    }    metrics.shutdown()?;    let resource_metrics = latest_metrics(&exporter);    let (bounds, bucket_counts, _sum, count) =        histogram_data(&resource_metrics, "codex.request_latency");    assert!(!bounds.is_empty());    assert_eq!(count, 1);    assert_eq!(bucket_counts.iter().sum::<u64>(), 1);    let metric = crate::harness::find_metric(&resource_metrics, "codex.request_latency")        .expect("codex.request_latency metric should exist");    assert_eq!(metric.unit(), "ms");    assert_eq!(metric.description(), "Duration in milliseconds.");    let attrs = attributes_to_map(        crate::harness::find_metric(&resource_metrics, "codex.request_latency")            .and_then(|metric| match metric.data() {                opentelemetry_sdk::metrics::data::AggregatedMetrics::F64(                    opentelemetry_sdk::metrics::data::MetricData::Histogram(histogram),                ) => histogram                    .data_points()                    .next()                    .map(opentelemetry_sdk::metrics::data::HistogramDataPoint::attributes),                _ => None,            })            .expect("codex.request_latency attributes should exist"),    );    assert_eq!(attrs.get("route").map(String::as_str), Some("chat"));    Ok(())}