use redis::ConnectionAddr;
use redis::ConnectionInfo;
use redis::TlsMode;
use redis::sentinel::SentinelNodeConnectionInfo;
use redis_test::sentinel::{RedisSentinelCluster, wait_for_master_server, wait_for_replica};
use redis_test::server::RedisServer;
use crate::support::start_tls_crypto_provider;
const MTLS_NOT_ENABLED: bool = false;
pub struct TestSentinelContext {
pub cluster: RedisSentinelCluster,
pub sentinel: redis::sentinel::Sentinel,
pub sentinels_connection_info: Vec<ConnectionInfo>,
mtls_enabled: bool, }
impl TestSentinelContext {
pub fn new(nodes: u16, replicas: u16, sentinels: u16) -> TestSentinelContext {
Self::new_with_cluster_client_builder(nodes, replicas, sentinels)
}
pub fn new_with_cluster_client_builder(
nodes: u16,
replicas: u16,
sentinels: u16,
) -> TestSentinelContext {
start_tls_crypto_provider();
let cluster = RedisSentinelCluster::new(nodes, replicas, sentinels);
let initial_nodes: Vec<ConnectionInfo> = cluster
.iter_sentinel_servers()
.map(RedisServer::connection_info)
.collect();
let sentinel = redis::sentinel::Sentinel::build(initial_nodes.clone());
let sentinel = sentinel.unwrap();
let mut context = TestSentinelContext {
cluster,
sentinel,
sentinels_connection_info: initial_nodes,
mtls_enabled: MTLS_NOT_ENABLED,
};
context.wait_for_cluster_up();
context
}
pub fn sentinel(&self) -> &redis::sentinel::Sentinel {
&self.sentinel
}
pub fn sentinel_mut(&mut self) -> &mut redis::sentinel::Sentinel {
&mut self.sentinel
}
pub fn sentinels_connection_info(&self) -> &Vec<ConnectionInfo> {
&self.sentinels_connection_info
}
pub fn sentinel_node_connection_info(&self) -> SentinelNodeConnectionInfo {
if let Some(tls_mode) = self.tls_mode() {
SentinelNodeConnectionInfo::default().set_tls_mode(tls_mode)
} else {
SentinelNodeConnectionInfo::default()
}
}
pub fn tls_mode(&self) -> Option<TlsMode> {
if let ConnectionAddr::TcpTls { insecure, .. } = self.cluster.servers[0].client_addr() {
if *insecure {
Some(TlsMode::Insecure)
} else {
Some(TlsMode::Secure)
}
} else {
None
}
}
pub fn wait_for_cluster_up(&mut self) {
let node_conn_info = self.sentinel_node_connection_info();
let con = self.sentinel_mut();
let r = wait_for_master_server(|| con.master_for("master1", Some(&node_conn_info)));
if r.is_err() {
panic!("failed waiting for sentinel master1 to be ready");
}
let r = wait_for_replica(|| con.replica_for("master1", Some(&node_conn_info)));
if r.is_err() {
panic!("failed waiting for sentinel master1 replica to be ready");
}
}
}