use std::{borrow::Cow, collections::BTreeMap};
use testcontainers::{core::WaitFor, Image};
const DEFAULT_IMAGE_NAME: &str = "hashicorp/consul";
const DEFAULT_IMAGE_TAG: &str = "1.16.1";
const CONSUL_LOCAL_CONFIG: &str = "CONSUL_LOCAL_CONFIG";
#[derive(Debug, Default)]
pub struct Consul {
env_vars: BTreeMap<String, String>,
}
impl Consul {
pub fn with_local_config(self, config: String) -> Self {
let mut env_vars = self.env_vars;
env_vars.insert(CONSUL_LOCAL_CONFIG.to_owned(), config);
Self { env_vars }
}
}
impl Image for Consul {
fn name(&self) -> &str {
DEFAULT_IMAGE_NAME
}
fn tag(&self) -> &str {
DEFAULT_IMAGE_TAG
}
fn ready_conditions(&self) -> Vec<WaitFor> {
vec![WaitFor::message_on_stdout("agent: Consul agent running!")]
}
fn env_vars(
&self,
) -> impl IntoIterator<Item = (impl Into<Cow<'_, str>>, impl Into<Cow<'_, str>>)> {
&self.env_vars
}
}
#[cfg(test)]
mod tests {
use serde_json::Value;
use crate::{consul::Consul, testcontainers::runners::AsyncRunner};
#[tokio::test]
async fn consul_container() -> Result<(), Box<dyn std::error::Error + 'static>> {
let consul = Consul::default().with_local_config("{\"datacenter\":\"dc-rust\"}".to_owned());
let node = consul.start().await?;
let port = node.get_host_port_ipv4(8500).await?;
let response = reqwest::Client::new()
.get(format!("http://localhost:{}/v1/agent/self", port))
.send()
.await
.unwrap()
.json::<Value>()
.await
.unwrap();
let config = response.as_object().unwrap().get("Config").unwrap();
let dc = config
.as_object()
.unwrap()
.get("Datacenter")
.unwrap()
.as_str()
.unwrap();
assert_eq!("dc-rust", dc);
Ok(())
}
}