2025-12-01 12:48:39 +01:00
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
|
|
use reqwest::Url;
|
|
|
|
|
use testing_framework_core::{
|
|
|
|
|
nodes::ApiClient,
|
2026-01-26 16:36:51 +01:00
|
|
|
scenario::{NodeClients, http_probe::NODE_ROLE},
|
2026-01-26 08:26:15 +01:00
|
|
|
topology::generation::GeneratedTopology,
|
2025-12-01 12:48:39 +01:00
|
|
|
};
|
|
|
|
|
use tokio::time::sleep;
|
|
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
|
errors::{NodeClientError, StackReadinessError},
|
2025-12-10 15:26:34 +01:00
|
|
|
infrastructure::ports::{HostPortMapping, NodeHostPorts},
|
2026-01-26 08:26:15 +01:00
|
|
|
lifecycle::wait::wait_for_nodes,
|
2025-12-01 12:48:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const DISABLED_READINESS_SLEEP: Duration = Duration::from_secs(5);
|
|
|
|
|
|
2026-01-26 08:26:15 +01:00
|
|
|
/// Wait until all nodes respond on their API ports.
|
|
|
|
|
pub async fn ensure_nodes_ready_with_ports(ports: &[u16]) -> Result<(), StackReadinessError> {
|
2025-12-01 12:48:39 +01:00
|
|
|
if ports.is_empty() {
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-26 08:26:15 +01:00
|
|
|
wait_for_nodes(ports).await.map_err(Into::into)
|
2025-12-01 12:48:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Allow a brief pause when readiness probes are disabled.
|
|
|
|
|
pub async fn maybe_sleep_for_disabled_readiness(readiness_enabled: bool) {
|
|
|
|
|
if !readiness_enabled {
|
|
|
|
|
sleep(DISABLED_READINESS_SLEEP).await;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Construct API clients using the mapped host ports.
|
|
|
|
|
pub fn build_node_clients_with_ports(
|
|
|
|
|
descriptors: &GeneratedTopology,
|
|
|
|
|
mapping: &HostPortMapping,
|
|
|
|
|
host: &str,
|
|
|
|
|
) -> Result<NodeClients, NodeClientError> {
|
2026-01-26 08:26:15 +01:00
|
|
|
let nodes = descriptors
|
|
|
|
|
.nodes()
|
2025-12-01 12:48:39 +01:00
|
|
|
.iter()
|
2026-01-26 08:26:15 +01:00
|
|
|
.zip(mapping.nodes.iter())
|
2026-01-26 16:36:51 +01:00
|
|
|
.map(|(_node, ports)| api_client_from_host_ports(NODE_ROLE, ports, host))
|
2025-12-01 12:48:39 +01:00
|
|
|
.collect::<Result<Vec<_>, _>>()?;
|
|
|
|
|
|
2026-01-26 08:26:15 +01:00
|
|
|
Ok(NodeClients::new(nodes))
|
2025-12-01 12:48:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn api_client_from_host_ports(
|
2026-01-26 16:36:51 +01:00
|
|
|
role: &'static str,
|
2025-12-01 12:48:39 +01:00
|
|
|
ports: &NodeHostPorts,
|
|
|
|
|
host: &str,
|
|
|
|
|
) -> Result<ApiClient, NodeClientError> {
|
|
|
|
|
let base_url = localhost_url(ports.api, host).map_err(|source| NodeClientError::Endpoint {
|
|
|
|
|
role,
|
|
|
|
|
endpoint: "api",
|
|
|
|
|
port: ports.api,
|
|
|
|
|
source,
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
let testing_url =
|
|
|
|
|
Some(
|
|
|
|
|
localhost_url(ports.testing, host).map_err(|source| NodeClientError::Endpoint {
|
|
|
|
|
role,
|
|
|
|
|
endpoint: "testing",
|
|
|
|
|
port: ports.testing,
|
|
|
|
|
source,
|
|
|
|
|
})?,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(ApiClient::from_urls(base_url, testing_url))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn localhost_url(port: u16, host: &str) -> Result<Url, url::ParseError> {
|
|
|
|
|
Url::parse(&format!("http://{host}:{port}/"))
|
|
|
|
|
}
|