#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
#![allow(clippy::panic)]
#![allow(clippy::indexing_slicing)]
use anyhow::Result;
use pg_exporter::collectors::config::CollectorConfig;
mod common;
fn collector_config(names: &[&str]) -> CollectorConfig {
let enabled = names
.iter()
.map(|name| (*name).to_string())
.collect::<Vec<_>>();
CollectorConfig::new(25).with_enabled(&enabled)
}
#[tokio::test]
async fn test_metrics_endpoint_returns_prometheus_format() -> Result<()> {
let port = common::get_available_port();
let dsn = common::get_test_dsn_secret();
let handle = tokio::spawn(async move {
pg_exporter::exporter::new(port, None, dsn, collector_config(&["default"])).await
});
assert!(common::wait_for_server(port, 50).await);
let client = reqwest::Client::new();
let response = client
.get(format!("{}/metrics", common::get_test_url(port)))
.send()
.await?;
assert_eq!(response.status(), 200);
let content_type = response
.headers()
.get("content-type")
.expect("Content-Type header should be present");
assert_eq!(content_type, "text/plain; charset=utf-8");
let body = response.text().await?;
assert!(body.contains("# HELP"));
assert!(body.contains("# TYPE"));
assert!(body.contains("pg_up"));
handle.abort();
Ok(())
}
#[tokio::test]
async fn test_metrics_endpoint_with_multiple_collectors() -> Result<()> {
let port = common::get_available_port();
let dsn = common::get_test_dsn_secret();
let config = collector_config(&[
"default",
"activity",
"vacuum",
"database",
"locks",
"stat",
"replication",
"index",
"statements",
]);
let handle =
tokio::spawn(async move { pg_exporter::exporter::new(port, None, dsn, config).await });
assert!(common::wait_for_server(port, 50).await);
let client = reqwest::Client::new();
let response = client
.get(format!("{}/metrics", common::get_test_url(port)))
.send()
.await?;
assert_eq!(response.status(), 200);
let body = response.text().await?;
assert!(body.contains("pg_up"));
assert!(body.contains("pg_stat_activity") || body.contains("pg_connections"));
handle.abort();
Ok(())
}
#[tokio::test]
async fn test_metrics_endpoint_performance() -> Result<()> {
let port = common::get_available_port();
let dsn = common::get_test_dsn_secret();
let handle = tokio::spawn(async move {
pg_exporter::exporter::new(port, None, dsn, collector_config(&["default"])).await
});
assert!(common::wait_for_server(port, 50).await);
let client = reqwest::Client::new();
for _ in 0..3 {
let start = std::time::Instant::now();
let response = client
.get(format!("{}/metrics", common::get_test_url(port)))
.send()
.await?;
let duration = start.elapsed();
assert_eq!(response.status(), 200);
assert!(
duration.as_secs() < 5,
"Metrics collection took too long: {duration:?}"
);
}
handle.abort();
Ok(())
}