mod common;
use std::time::Duration;
use common::TestServer;
use httpress::Benchmark;
#[tokio::test]
async fn test_connection_refused() {
let results = Benchmark::builder()
.url("http://127.0.0.1:59999/ok")
.requests(5)
.concurrency(1)
.build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 5);
assert_eq!(results.failed_requests, 5);
assert_eq!(results.successful_requests, 0);
}
#[tokio::test]
async fn test_request_timeout() {
let server = TestServer::start().await;
let results = Benchmark::builder()
.url(&format!("{}/delay/5000", server.base_url)) .requests(3)
.concurrency(1)
.timeout(Duration::from_millis(100)) .build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 3);
assert_eq!(results.failed_requests, 3);
assert_eq!(results.successful_requests, 0);
assert!(
results.latency_max < Duration::from_millis(500),
"Latency max {:?} should be less than 500ms",
results.latency_max
);
}
#[tokio::test]
async fn test_http_500_errors_recorded() {
let server = TestServer::start().await;
let results = Benchmark::builder()
.url(&format!("{}/status/500", server.base_url))
.requests(10)
.concurrency(2)
.build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 10);
assert_eq!(results.failed_requests, 10);
assert_eq!(results.successful_requests, 0);
assert_eq!(
*results.status_codes.get(&500).unwrap_or(&0),
10,
"Expected 10 requests with status 500"
);
}
#[tokio::test]
async fn test_http_404_errors_recorded() {
let server = TestServer::start().await;
let results = Benchmark::builder()
.url(&format!("{}/status/404", server.base_url))
.requests(5)
.concurrency(1)
.build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 5);
assert_eq!(results.failed_requests, 5);
assert_eq!(results.successful_requests, 0);
assert_eq!(
*results.status_codes.get(&404).unwrap_or(&0),
5,
"Expected 5 requests with status 404"
);
}
#[tokio::test]
async fn test_mixed_status_codes() {
let server = TestServer::start_rotating(vec![200, 400, 500]).await;
let results = Benchmark::builder()
.url(&format!("{}/rotating", server.base_url))
.requests(30)
.concurrency(1) .build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 30);
let count_200 = *results.status_codes.get(&200).unwrap_or(&0);
let count_400 = *results.status_codes.get(&400).unwrap_or(&0);
let count_500 = *results.status_codes.get(&500).unwrap_or(&0);
assert_eq!(count_200, 10, "Expected 10 requests with status 200");
assert_eq!(count_400, 10, "Expected 10 requests with status 400");
assert_eq!(count_500, 10, "Expected 10 requests with status 500");
assert_eq!(results.successful_requests, 10);
assert_eq!(results.failed_requests, 20);
}
#[tokio::test]
async fn test_latency_recorded_for_errors() {
let server = TestServer::start().await;
let results = Benchmark::builder()
.url(&format!("{}/status/500", server.base_url))
.requests(5)
.concurrency(1)
.build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 5);
assert_eq!(results.failed_requests, 5);
assert!(
results.latency_min > Duration::ZERO,
"Latency min should be greater than zero"
);
assert!(
results.latency_max > Duration::ZERO,
"Latency max should be greater than zero"
);
}
#[tokio::test]
async fn test_throughput_calculated() {
let server = TestServer::start().await;
let results = Benchmark::builder()
.url(&format!("{}/ok", server.base_url))
.requests(50)
.concurrency(4)
.build()
.unwrap()
.run()
.await
.unwrap();
assert_eq!(results.total_requests, 50);
assert!(
results.throughput > 0.0,
"Throughput should be positive, got {}",
results.throughput
);
let calculated_throughput = results.total_requests as f64 / results.duration.as_secs_f64();
let diff = (results.throughput - calculated_throughput).abs();
assert!(
diff < 1.0,
"Throughput mismatch: reported {} vs calculated {}",
results.throughput,
calculated_throughput
);
}