#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Backend {
Docker,
K8s,
}
pub const GLOBAL_BACKEND_ENV: &str = "FAKECLOUD_CONTAINER_BACKEND";
pub fn backend_choice(per_service_env: &str) -> Backend {
match read_choice(per_service_env) {
Some(b) => b,
None => read_choice(GLOBAL_BACKEND_ENV).unwrap_or(Backend::Docker),
}
}
fn read_choice(var: &str) -> Option<Backend> {
match std::env::var(var)
.ok()?
.trim()
.to_ascii_lowercase()
.as_str()
{
"k8s" | "kubernetes" => Some(Backend::K8s),
"docker" | "podman" => Some(Backend::Docker),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Mutex;
static ENV_LOCK: Mutex<()> = Mutex::new(());
struct EnvGuard(Vec<(String, Option<String>)>);
impl Drop for EnvGuard {
fn drop(&mut self) {
for (k, v) in &self.0 {
match v {
Some(v) => std::env::set_var(k, v),
None => std::env::remove_var(k),
}
}
}
}
fn with_env(vars: &[(&str, Option<&str>)], f: impl FnOnce()) {
let _g = ENV_LOCK.lock().unwrap_or_else(|p| p.into_inner());
let _restore = EnvGuard(
vars.iter()
.map(|(k, _)| (k.to_string(), std::env::var(k).ok()))
.collect(),
);
for (k, v) in vars {
match v {
Some(v) => std::env::set_var(k, v),
None => std::env::remove_var(k),
}
}
f();
}
const SVC: &str = "FAKECLOUD_ELASTICACHE_BACKEND";
#[test]
fn defaults_to_docker_when_unset() {
with_env(&[(SVC, None), (GLOBAL_BACKEND_ENV, None)], || {
assert_eq!(backend_choice(SVC), Backend::Docker);
});
}
#[test]
fn per_service_k8s_wins() {
with_env(&[(SVC, Some("k8s")), (GLOBAL_BACKEND_ENV, None)], || {
assert_eq!(backend_choice(SVC), Backend::K8s);
});
}
#[test]
fn global_k8s_applies_when_service_unset() {
with_env(&[(SVC, None), (GLOBAL_BACKEND_ENV, Some("k8s"))], || {
assert_eq!(backend_choice(SVC), Backend::K8s);
});
}
#[test]
fn per_service_docker_overrides_global_k8s() {
with_env(
&[(SVC, Some("docker")), (GLOBAL_BACKEND_ENV, Some("k8s"))],
|| {
assert_eq!(backend_choice(SVC), Backend::Docker);
},
);
}
#[test]
fn case_insensitive_and_trimmed() {
with_env(
&[(SVC, Some(" K8s ")), (GLOBAL_BACKEND_ENV, None)],
|| {
assert_eq!(backend_choice(SVC), Backend::K8s);
},
);
}
#[test]
fn unrecognized_service_value_falls_through_to_global() {
with_env(
&[(SVC, Some("banana")), (GLOBAL_BACKEND_ENV, Some("k8s"))],
|| {
assert_eq!(backend_choice(SVC), Backend::K8s);
},
);
}
#[test]
fn unrecognized_everywhere_is_docker() {
with_env(
&[(SVC, Some("banana")), (GLOBAL_BACKEND_ENV, Some("nope"))],
|| {
assert_eq!(backend_choice(SVC), Backend::Docker);
},
);
}
}