#![allow(dead_code, unused_imports)] use super::common::*; use serde_json::{Value, json}; use serial_test::serial; use time::{Duration, OffsetDateTime, format_description::well_known::Rfc3339}; #[tokio::test(flavor = "multi_thread")] #[serial] async fn exposes_logs_and_usage_from_real_test_runs() { let registry = test_registry().await; let storage_root = test_storage_root("observability"); let upstream_base_url = spawn_upstream_server().await; let base_url = spawn_admin_api(build_test_app(registry, storage_root)).await; let client = authorized_client(&base_url).await; let created = client .post(format!("{base_url}/operations")) .json(&test_operation_payload( &upstream_base_url, "crm_observability", )) .send() .await .unwrap() .json::() .await .unwrap(); let operation_id = created["operation_id"].as_str().unwrap().to_owned(); client .post(format!("{base_url}/operations/{operation_id}/test-runs")) .json(&json!({ "version": 1, "input": { "email": "user@example.com" } })) .send() .await .unwrap(); let logs = client .get(format!("{base_url}/logs?period=7d")) .send() .await .unwrap() .json::() .await .unwrap(); assert!(logs["items"].is_array()); assert!(logs.get("next_cursor").is_some()); let log_id = logs["items"][0]["log"]["id"].as_str().unwrap().to_owned(); let created_at = OffsetDateTime::parse( logs["items"][0]["log"]["created_at"].as_str().unwrap(), &Rfc3339, ) .unwrap(); let log_detail = client .get(format!("{base_url}/logs/{log_id}")) .send() .await .unwrap() .json::() .await .unwrap(); let csv = client .get(format!("{base_url}/logs/export.csv?period=7d&status=ok")) .send() .await .unwrap() .text() .await .unwrap(); let outcome_logs = client .get(format!("{base_url}/logs?period=7d&outcome_group=success")) .send() .await .unwrap() .json::() .await .unwrap(); let created_after = (created_at - Duration::minutes(1)) .format(&Rfc3339) .unwrap(); let created_before = (created_at + Duration::minutes(1)) .format(&Rfc3339) .unwrap(); let usage = client .get(format!("{base_url}/usage?period=7d")) .send() .await .unwrap() .json::() .await .unwrap(); let windowed_usage = client .get(format!( "{base_url}/usage?created_after={created_after}&created_before={created_before}" )) .send() .await .unwrap() .json::() .await .unwrap(); let usage_csv = client .get(format!("{base_url}/usage/export.csv?period=7d")) .send() .await .unwrap() .text() .await .unwrap(); let operation_usage = client .get(format!( "{base_url}/usage/operations/{operation_id}?period=7d" )) .send() .await .unwrap() .json::() .await .unwrap(); assert_eq!(logs["items"][0]["log"]["source"], "admin_test_run"); assert_eq!(logs["items"][0]["operation_name"], "crm_observability"); assert_eq!(log_detail["log"]["status"], "ok"); assert_eq!(log_detail["log"]["operation_version"], 1); assert!(log_detail["log"]["request_id"].as_str().is_some()); assert!( log_detail["log"]["trace_id"] .as_str() .is_some_and(|value| value.len() == 32) ); assert!(csv.starts_with("created_at,level,status,source")); assert!(csv.contains(log_detail["log"]["request_id"].as_str().unwrap())); assert!(csv.contains(log_detail["log"]["trace_id"].as_str().unwrap())); assert_eq!(outcome_logs["items"][0]["log"]["status"], "ok"); assert_eq!(usage["summary"]["rollup"]["calls_total"], 1); assert_eq!(usage["summary"]["rollup"]["calls_ok"], 1); assert_eq!(usage["outcomes"][0]["group"], "success"); assert_eq!(usage["outcomes"][0]["calls_total"], 1); assert_eq!(windowed_usage["summary"]["rollup"]["calls_total"], 1); assert!(usage_csv.starts_with("kind,name,group,error_code,calls_total")); assert!(usage_csv.contains("operation")); assert!(usage_csv.contains("outcome")); assert_eq!( usage["operations"][0]["operation_name"], "crm_observability" ); assert_eq!(operation_usage["rollup"]["calls_total"], 1); }