use std::io::{Read, Write};
use std::net::{SocketAddr, TcpStream};
use std::sync::{Arc, Mutex, PoisonError};
use std::thread;
use std::time::{Duration, Instant};
use serde_json::Value;
use super::{
OperatorCredentialReissueRefusal, OperatorCredentialReissueRequest, OperatorCredentialReissuer,
ServedState, response_for_request, start_health_server,
};
use crate::health::checks::{
ClusterReadiness, ReadinessCondition, ReadinessState, SharedReadinessState,
};
fn loopback_ephemeral() -> Result<SocketAddr, Box<dyn std::error::Error>> {
Ok("127.0.0.1:0".parse()?)
}
fn served(readiness: SharedReadinessState) -> ServedState {
ServedState {
started_at: 1,
drafts: Arc::new(Mutex::new(None)),
grant_stream: Arc::new(std::sync::OnceLock::new()),
lys_root: Arc::new(std::sync::OnceLock::new()),
readiness,
unloadable: crate::health::unloadable::SharedUnloadableConversations::default(),
reissue: crate::health::reissue::SharedOperatorCredentialReissue::default(),
reclaim: crate::health::reclaim_route::SharedReclaimSpine::default(),
ephemeral_sweep: Arc::new(std::sync::OnceLock::new()),
listen_addresses: Arc::new(std::sync::OnceLock::new()),
link_bridges: crate::link_bridge::BridgeRegistry::default(),
}
}
fn get(address: SocketAddr, path: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut stream = TcpStream::connect(address)?;
stream.set_read_timeout(Some(Duration::from_secs(2)))?;
let request = format!("GET {path} HTTP/1.1\r\nHost: localhost\r\n\r\n");
stream.write_all(request.as_bytes())?;
let mut response = String::new();
stream.read_to_string(&mut response)?;
Ok(response)
}
fn assert_status(response: &str, status: u16) {
let expected = format!("HTTP/1.1 {status} ");
assert!(
response.starts_with(&expected),
"response status did not start with {expected}: {response}"
);
}
fn body(response: &str) -> Result<&str, Box<dyn std::error::Error>> {
let Some((_headers, body)) = response.split_once("\r\n\r\n") else {
return Err("response did not contain a header/body separator".into());
};
Ok(body)
}
fn json_body(response: &str) -> Result<Value, Box<dyn std::error::Error>> {
Ok(serde_json::from_str(body(response)?)?)
}
#[path = "health_tests.rs"]
mod health;
#[path = "lifecycle_tests.rs"]
mod lifecycle;
#[path = "reissue_tests.rs"]
mod reissue;
#[path = "grant_stream_tests.rs"]
mod grant_stream;
#[path = "lys_root_tests.rs"]
mod lys_root;