fix(test): isolate health tests from minimal-response env var race (#4702)

Three health handler tests assert on payload fields (degradedReasons,
details) that are absent when RUSTFS_HEALTH_MINIMAL_RESPONSE_ENABLE is
true. The minimal-mode sibling test sets that env var via
temp_env::with_var, which leaks across parallel test threads.

Wrap the three affected tests with their own with_var guard pinning the
env var to false so they are deterministic regardless of thread order.
This commit is contained in:
Zhengchao An
2026-07-11 13:39:34 +08:00
committed by GitHub
parent 5650dcdc5d
commit a97f3a9c52
+62 -45
View File
@@ -88,6 +88,7 @@ impl Operation for HealthCheckHandler {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use serial_test::serial;
use temp_env::with_var; use temp_env::with_var;
#[test] #[test]
@@ -285,6 +286,7 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_build_health_payload_minimal_mode_returns_status_and_ready_only() { fn test_build_health_payload_minimal_mode_returns_status_and_ready_only() {
let health = health_check_state(true, false, true, true, HealthProbe::Readiness); let health = health_check_state(true, false, true, true, HealthProbe::Readiness);
with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("true"), || { with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("true"), || {
@@ -309,20 +311,23 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_build_health_payload_includes_degraded_reasons() { fn test_build_health_payload_includes_degraded_reasons() {
let health = health_check_state(false, false, false, true, HealthProbe::Readiness); with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("false"), || {
let payload = build_health_payload(HealthPayloadContext { let health = health_check_state(false, false, false, true, HealthProbe::Readiness);
health, let payload = build_health_payload(HealthPayloadContext {
storage_ready: false, health,
iam_ready: false, storage_ready: false,
lock_quorum_ready: false, iam_ready: false,
degraded_reasons: &[crate::server::ReadinessDegradedReason::StorageAndIamUnavailable], lock_quorum_ready: false,
service: "rustfs-endpoint", degraded_reasons: &[crate::server::ReadinessDegradedReason::StorageAndIamUnavailable],
uptime: None, service: "rustfs-endpoint",
kms_ready: None, uptime: None,
include_dependency_details: true, kms_ready: None,
include_dependency_details: true,
});
assert_eq!(payload["degradedReasons"][0], "storage_and_iam_unavailable");
}); });
assert_eq!(payload["degradedReasons"][0], "storage_and_iam_unavailable");
} }
#[test] #[test]
@@ -343,43 +348,55 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn test_build_health_response_parts_get_includes_payload() { fn test_build_health_response_parts_get_includes_payload() {
let report = crate::server::DependencyReadinessReport { with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("false"), || {
readiness: crate::server::DependencyReadiness { let report = crate::server::DependencyReadinessReport {
storage_ready: false, readiness: crate::server::DependencyReadiness {
iam_ready: true, storage_ready: false,
lock_quorum_ready: true, iam_ready: true,
peer_health_ready: true, lock_quorum_ready: true,
}, peer_health_ready: true,
degraded_reasons: vec![crate::server::ReadinessDegradedReason::StorageQuorumUnavailable], },
}; degraded_reasons: vec![crate::server::ReadinessDegradedReason::StorageQuorumUnavailable],
let parts = };
build_health_response_parts(Method::GET, HealthProbe::Readiness, Some(&report), "rustfs-endpoint", None, None); let parts =
assert_eq!(parts.status_code, StatusCode::SERVICE_UNAVAILABLE); build_health_response_parts(Method::GET, HealthProbe::Readiness, Some(&report), "rustfs-endpoint", None, None);
let payload = parts.payload.expect("GET should include payload"); assert_eq!(parts.status_code, StatusCode::SERVICE_UNAVAILABLE);
assert_eq!(payload["status"], "degraded"); let payload = parts.payload.expect("GET should include payload");
assert_eq!(payload["ready"], false); assert_eq!(payload["status"], "degraded");
assert_eq!(payload["degradedReasons"][0], "storage_quorum_unavailable"); assert_eq!(payload["ready"], false);
assert_eq!(payload["degradedReasons"][0], "storage_quorum_unavailable");
});
} }
#[test] #[test]
#[serial]
fn test_build_health_response_parts_readiness_marks_kms_not_ready() { fn test_build_health_response_parts_readiness_marks_kms_not_ready() {
let report = crate::server::DependencyReadinessReport { with_var(rustfs_config::ENV_HEALTH_MINIMAL_RESPONSE_ENABLE, Some("false"), || {
readiness: crate::server::DependencyReadiness { let report = crate::server::DependencyReadinessReport {
storage_ready: true, readiness: crate::server::DependencyReadiness {
iam_ready: true, storage_ready: true,
lock_quorum_ready: true, iam_ready: true,
peer_health_ready: true, lock_quorum_ready: true,
}, peer_health_ready: true,
degraded_reasons: Vec::new(), },
}; degraded_reasons: Vec::new(),
let parts = };
build_health_response_parts(Method::GET, HealthProbe::Readiness, Some(&report), "rustfs-endpoint", None, Some(false)); let parts = build_health_response_parts(
assert_eq!(parts.status_code, StatusCode::SERVICE_UNAVAILABLE); Method::GET,
let payload = parts.payload.expect("GET should include payload"); HealthProbe::Readiness,
assert_eq!(payload["ready"], false); Some(&report),
assert_eq!(payload["details"]["lock"]["ready"], true); "rustfs-endpoint",
assert_eq!(payload["details"]["kms"]["ready"], false); None,
assert_eq!(payload["degradedReasons"][0], "kms_not_ready"); Some(false),
);
assert_eq!(parts.status_code, StatusCode::SERVICE_UNAVAILABLE);
let payload = parts.payload.expect("GET should include payload");
assert_eq!(payload["ready"], false);
assert_eq!(payload["details"]["lock"]["ready"], true);
assert_eq!(payload["details"]["kms"]["ready"], false);
assert_eq!(payload["degradedReasons"][0], "kms_not_ready");
});
} }
} }