这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 8 additions & 45 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ http_request_handler!(vts_status_handler, |request: &mut http::Request| {
///
/// A formatted string containing VTS status information
fn generate_vts_status_content() -> String {
let manager = VTS_MANAGER.read().unwrap();
let manager = VTS_MANAGER
.read()
.unwrap_or_else(|poisoned| poisoned.into_inner());
let formatter = PrometheusFormatter::new();

// Get all server statistics
Expand Down Expand Up @@ -355,42 +357,6 @@ fn generate_vts_status_content() -> String {
));
}

// Upstream zones information
if !upstream_zones.is_empty() {
content.push_str("# Upstream Zones:\n");
for (upstream_name, zone) in upstream_zones {
content.push_str(&format!(
"# {}: {} servers, {} total requests\n",
upstream_name,
zone.servers.len(),
zone.total_requests()
));

for (server_addr, server) in &zone.servers {
let status_2xx = server.responses.status_2xx;
let status_4xx = server.responses.status_4xx;
let status_5xx = server.responses.status_5xx;
content.push_str(&format!(
"# - {}: {} req, {}ms avg ({}×2xx, {}×4xx, {}×5xx)\n",
server_addr,
server.request_counter,
if server.request_counter > 0 {
server.request_time_total / server.request_counter
} else {
0
},
status_2xx,
status_4xx,
status_5xx
));
}
}
content.push_str(&format!(
"# Total Upstream Zones: {}\n\n",
upstream_zones.len()
));
}

// Generate Prometheus metrics section
content.push_str("# Prometheus Metrics:\n");

Expand Down Expand Up @@ -474,12 +440,6 @@ mod integration_tests {
assert!(status_content.contains("# 2xx Responses: 2"));
assert!(status_content.contains("# 4xx Responses: 1"));

// Verify upstream zones are included
assert!(status_content.contains("# Upstream Zones:"));
assert!(status_content.contains("backend_pool: 2 servers"));
assert!(status_content.contains("api_pool: 2 servers"));
assert!(status_content.contains("# Total Upstream Zones: 2"));

// Verify Prometheus metrics section exists
assert!(status_content.contains("# Prometheus Metrics:"));
assert!(status_content.contains("nginx_vts_upstream_requests_total"));
Expand Down Expand Up @@ -526,10 +486,13 @@ mod integration_tests {
update_upstream_zone_stats("test_backend", "10.0.0.2:80", 80, 40, 800, 400, 200);

let content2 = generate_vts_status_content();
assert!(content2.contains("test_backend: 2 servers"));
// Verify metrics are present (no longer check summary format)
assert!(content2.contains("nginx_vts_upstream_requests_total"));

// Verify metrics accumulation
let manager = VTS_MANAGER.read().unwrap();
let manager = VTS_MANAGER
.read()
.unwrap_or_else(|poisoned| poisoned.into_inner());
let backend_zone = manager.get_upstream_zone("test_backend").unwrap();
let server1 = backend_zone.servers.get("10.0.0.1:80").unwrap();
assert_eq!(server1.request_counter, 2);
Expand Down
12 changes: 6 additions & 6 deletions test_issue1_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ mod issue1_test {

#[test]
fn test_issue1_backend_upstream_statistics() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Simulate the specific scenario from ISSUE1.md:
// - upstream backend { server 127.0.0.1:8080; }
// - vts_upstream_stats on;

// Initialize upstream statistics for the exact backend mentioned in ISSUE1.md
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
// Clear any existing data
manager.upstream_zones.clear();

Expand Down Expand Up @@ -57,10 +61,6 @@ mod issue1_test {
assert!(status_content.contains("nginx_vts_upstream_responses_total{upstream=\"backend\",server=\"127.0.0.1:8080\",status=\"2xx\"}"));
assert!(status_content.contains("nginx_vts_upstream_server_up{upstream=\"backend\",server=\"127.0.0.1:8080\"} 1"));

// Verify that upstream zones are not empty anymore
assert!(status_content.contains("# Upstream Zones:"));
assert!(status_content.contains("backend: 1 servers, 500 total requests"));
assert!(status_content.contains("127.0.0.1:8080: 500 req"));

// Verify basic VTS info is present
assert!(status_content.contains("# nginx-vts-rust"));
Expand Down
28 changes: 18 additions & 10 deletions test_issue2_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ mod issue2_test {

#[test]
fn test_issue2_zero_initialization() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Clear all existing data to simulate fresh nginx startup
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand All @@ -25,7 +29,6 @@ mod issue2_test {

// Verify that initially no upstream zones exist
assert!(!initial_content.contains("nginx_vts_upstream_requests_total"));
assert!(!initial_content.contains("# Upstream Zones:"));

// Should only show basic VTS info
assert!(initial_content.contains("# nginx-vts-rust"));
Expand All @@ -41,10 +44,14 @@ mod issue2_test {

#[test]
fn test_issue2_dynamic_request_tracking() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Clear all existing data
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand Down Expand Up @@ -75,8 +82,6 @@ mod issue2_test {
assert!(after_first_request.contains("nginx_vts_upstream_bytes_total{upstream=\"backend\",server=\"127.0.0.1:8080\",direction=\"in\"} 512"));
assert!(after_first_request.contains("nginx_vts_upstream_bytes_total{upstream=\"backend\",server=\"127.0.0.1:8080\",direction=\"out\"} 1024"));
assert!(after_first_request.contains("nginx_vts_upstream_responses_total{upstream=\"backend\",server=\"127.0.0.1:8080\",status=\"2xx\"} 1"));
assert!(after_first_request.contains("# Upstream Zones:"));
assert!(after_first_request.contains("backend: 1 servers, 1 total requests"));

// Simulate second request
update_upstream_zone_stats(
Expand All @@ -100,18 +105,21 @@ mod issue2_test {
assert!(after_second_request.contains("nginx_vts_upstream_bytes_total{upstream=\"backend\",server=\"127.0.0.1:8080\",direction=\"in\"} 1280")); // 512 + 768
assert!(after_second_request.contains("nginx_vts_upstream_bytes_total{upstream=\"backend\",server=\"127.0.0.1:8080\",direction=\"out\"} 2560")); // 1024 + 1536
assert!(after_second_request.contains("nginx_vts_upstream_responses_total{upstream=\"backend\",server=\"127.0.0.1:8080\",status=\"2xx\"} 2"));
assert!(after_second_request.contains("backend: 1 servers, 2 total requests"));

// Verify response time calculations (average should be updated)
assert!(after_second_request.contains("nginx_vts_upstream_response_seconds"));
}

#[test]
fn test_issue2_external_c_api() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Clear state
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand Down
28 changes: 12 additions & 16 deletions test_issue3_integrated_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ mod issue3_integration_test {

#[test]
fn test_issue3_complete_flow_simulation() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

println!("=== ISSUE3.md Complete Flow Simulation ===");

// Step 1: Simulate fresh nginx startup with upstream backend configuration
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand All @@ -32,11 +36,6 @@ mod issue3_integration_test {
assert!(first_status_response.contains("# VTS Status: Active"));
assert!(first_status_response.contains("# Module: nginx-vts-rust"));

// Key assertion: should show upstream zones with zero values (not missing zones)
assert!(first_status_response.contains("# Upstream Zones:"));
assert!(first_status_response.contains("# backend: 1 servers, 0 total requests"));
assert!(first_status_response.contains("# - 127.0.0.1:8080: 0 req, 0ms avg"));
assert!(first_status_response.contains("# Total Upstream Zones: 1"));

// Should have all prometheus metrics with zero values
assert!(first_status_response.contains("nginx_vts_upstream_requests_total{upstream=\"backend\",server=\"127.0.0.1:8080\"} 0"));
Expand Down Expand Up @@ -74,12 +73,6 @@ mod issue3_integration_test {
assert!(third_status_response.contains("# VTS Status: Active"));
assert!(third_status_response.contains("# Module: nginx-vts-rust"));

// Key assertion: should show updated statistics
assert!(third_status_response.contains("# Upstream Zones:"));
assert!(third_status_response.contains("# backend: 1 servers, 1 total requests"));
assert!(third_status_response.contains("# - 127.0.0.1:8080: 1 req, 94ms avg"));
assert!(third_status_response.contains("1×2xx")); // Should show 1 2xx response
assert!(third_status_response.contains("# Total Upstream Zones: 1"));

// Verify all Prometheus metrics are updated correctly
assert!(third_status_response.contains("nginx_vts_upstream_requests_total{upstream=\"backend\",server=\"127.0.0.1:8080\"} 1"));
Expand Down Expand Up @@ -107,7 +100,7 @@ mod issue3_integration_test {

#[test]
fn test_issue3_nginx_conf_compliance() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// This test validates that our implementation correctly interprets
// the nginx.conf from ISSUE3.md:
Expand All @@ -125,7 +118,11 @@ mod issue3_integration_test {
// }
// }

if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand All @@ -139,7 +136,6 @@ mod issue3_integration_test {
assert!(status_content.contains("127.0.0.1:8080"));

// Verify vts_upstream_stats directive behavior
assert!(status_content.contains("# Upstream Zones:"));
assert!(status_content.contains("nginx_vts_upstream_requests_total"));
assert!(status_content.contains("nginx_vts_upstream_bytes_total"));
assert!(status_content.contains("nginx_vts_upstream_response_seconds"));
Expand Down
43 changes: 20 additions & 23 deletions test_issue3_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ mod issue3_test {

#[test]
fn test_issue3_upstream_zone_initialization() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Clear any existing data to simulate fresh nginx startup
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand All @@ -35,11 +39,6 @@ mod issue3_test {
println!("{}", after_init_content);
println!("=== End Test 2 ===");

// Should show the backend upstream from nginx.conf
assert!(after_init_content.contains("# Upstream Zones:"));
assert!(after_init_content.contains("backend: 1 servers, 0 total requests"));
// Check the actual format as generated (using × instead of x)
assert!(after_init_content.contains("127.0.0.1:8080: 0 req, 0ms avg"));

// Should show proper Prometheus metrics for the backend upstream
assert!(after_init_content.contains("nginx_vts_upstream_requests_total{upstream=\"backend\",server=\"127.0.0.1:8080\"} 0"));
Expand All @@ -61,10 +60,14 @@ mod issue3_test {

#[test]
fn test_issue3_expected_response_format() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Clear and initialize
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand All @@ -78,12 +81,6 @@ mod issue3_test {
assert!(content.contains("# VTS Status: Active"));
assert!(content.contains("# Module: nginx-vts-rust"));

// Should contain the upstream zones section as expected in ISSUE3.md
assert!(content.contains("# Upstream Zones:"));
assert!(content.contains("# backend: 1 servers, 0 total requests"));
// Check the actual format (using × instead of x for some status codes)
assert!(content.contains("# - 127.0.0.1:8080: 0 req, 0ms avg"));
assert!(content.contains("# Total Upstream Zones: 1"));

// Should contain all Prometheus metrics from ISSUE3.md expected response
assert!(content.contains("# HELP nginx_vts_upstream_requests_total Total upstream requests"));
Expand All @@ -100,10 +97,14 @@ mod issue3_test {

#[test]
fn test_issue3_dynamic_request_tracking() {
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap();
let _lock = GLOBAL_VTS_TEST_MUTEX.lock().unwrap_or_else(|poisoned| poisoned.into_inner());

// Clear and initialize
if let Ok(mut manager) = VTS_MANAGER.write() {
{
let mut manager = match VTS_MANAGER.write() {
Ok(guard) => guard,
Err(poisoned) => poisoned.into_inner(),
};
manager.stats.clear();
manager.upstream_zones.clear();
}
Expand All @@ -115,7 +116,6 @@ mod issue3_test {
println!("=== Initial Status (After nginx startup) ===");
println!("{}", initial_status);

assert!(initial_status.contains("backend: 1 servers, 0 total requests"));
assert!(initial_status.contains("nginx_vts_upstream_requests_total{upstream=\"backend\",server=\"127.0.0.1:8080\"} 0"));

// Simulate the second curl request: curl -I http://localhost:8081/
Expand All @@ -138,7 +138,6 @@ mod issue3_test {
println!("{}", after_request_status);

// Should show the request was processed
assert!(after_request_status.contains("backend: 1 servers, 1 total requests"));
assert!(after_request_status.contains("nginx_vts_upstream_requests_total{upstream=\"backend\",server=\"127.0.0.1:8080\"} 1"));
assert!(after_request_status.contains("nginx_vts_upstream_bytes_total{upstream=\"backend\",server=\"127.0.0.1:8080\",direction=\"in\"} 615"));
assert!(after_request_status.contains("nginx_vts_upstream_bytes_total{upstream=\"backend\",server=\"127.0.0.1:8080\",direction=\"out\"} 1370"));
Expand All @@ -147,9 +146,7 @@ mod issue3_test {
// Verify response time metrics are calculated
assert!(after_request_status.contains("nginx_vts_upstream_response_seconds"));

// Should show proper server status line with 94ms avg
assert!(after_request_status.contains("127.0.0.1:8080: 1 req"));
assert!(after_request_status.contains("94ms avg"));
assert!(after_request_status.contains("1×2xx")); // Should show 1 2xx response
// Should show proper metrics instead of summary format
assert!(after_request_status.contains("nginx_vts_upstream_responses_total{upstream=\"backend\",server=\"127.0.0.1:8080\",status=\"2xx\"} 1"));
}
}
Loading