#![allow(dead_code)]
use std::time::Duration;
use testcontainers::GenericImage;
use testcontainers::core::{IntoContainerPort, WaitFor};
use testcontainers::runners::AsyncRunner;
pub type RedisContainer = testcontainers::ContainerAsync<GenericImage>;
pub async fn setup_redis_container_on_port(
host_port: u16,
) -> Result<(RedisContainer, String), String> {
use testcontainers::ImageExt;
let redis = GenericImage::new("redis", "7-alpine")
.with_exposed_port(6379.tcp())
.with_mapped_port(host_port, 6379.tcp())
.with_ready_conditions(vec![WaitFor::message_on_stdout(
"Ready to accept connections",
)])
.start()
.await
.map_err(|e| format!("failed to start the Redis container: {}", e))?;
Ok((redis, format!("redis://127.0.0.1:{}", host_port)))
}
pub fn free_local_port() -> u16 {
std::net::TcpListener::bind("127.0.0.1:0")
.expect("bind ephemeral port")
.local_addr()
.expect("read local addr")
.port()
}
pub async fn wait_for_redis(url: &str, timeout_secs: u64) -> bool {
let client = match redis::Client::open(url) {
Ok(c) => c,
Err(_) => return false,
};
let start = std::time::Instant::now();
let timeout = Duration::from_secs(timeout_secs);
while start.elapsed() < timeout {
match tokio::time::timeout(
Duration::from_secs(2),
client.get_multiplexed_async_connection(),
)
.await
{
Ok(Ok(_)) => return true,
_ => tokio::time::sleep(Duration::from_millis(100)).await,
}
}
false
}