use std::net::SocketAddr;
use super::bootstrap::start_cluster;
use super::{SharedReadinessState, StartStages};
use crate::ServerError;
use crate::config::types::ClusterConfig;
use crate::health::{ClusterReadiness, ReadinessCondition, ReadinessState, readiness_check};
use crate::server::connection::services::ChannelCluster;
use crate::server::connection::services::LiminalConnectionServices;
#[test]
fn start_stages_read_as_lengths_and_ends() {
let stages = StartStages {
began: std::time::Instant::now(),
marks: vec![("config", 3), ("health", 4), ("services", 2_104)],
};
assert_eq!(
stages.to_string(),
"config 3 (3), health 1 (4), services 2100 (2104)"
);
}
fn unclustered_channel_cluster() -> Result<ChannelCluster, ServerError> {
Ok(LiminalConnectionServices::empty()?
.channel_cluster()
.clone())
}
fn clustered_but_unmet_readiness() -> SharedReadinessState {
SharedReadinessState::new(ReadinessState::new(
true,
true,
ClusterReadiness::Configured {
membership_established: false,
},
))
}
fn sample_cluster_config() -> Result<ClusterConfig, Box<dyn std::error::Error>> {
let listen_address: SocketAddr = "127.0.0.1:0".parse()?;
Ok(ClusterConfig {
node_name: "node-under-test@127.0.0.1".to_owned(),
listen_address,
seed_nodes: Vec::new(),
cookie: "runtime-test-cookie".to_owned(),
})
}
#[test]
fn failed_cluster_start_leaves_membership_unestablished() -> Result<(), Box<dyn std::error::Error>>
{
let readiness = clustered_but_unmet_readiness();
let channel_cluster = unclustered_channel_cluster()?;
let config = sample_cluster_config()?;
let result = start_cluster(&channel_cluster, &config, &readiness);
assert!(
result.is_err(),
"start_cluster must fail without a distribution resolver"
);
let status = readiness_check(&readiness.snapshot());
assert!(
!status.ready,
"readiness must remain not-ready after a failed start"
);
assert!(
status
.unmet_conditions
.contains(&ReadinessCondition::ClusterMembershipEstablished),
"cluster membership gate must stay unmet after a failed start"
);
Ok(())
}