diff --git a/Cargo.lock b/Cargo.lock index 2ebc653..c3f8e6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2198,6 +2198,7 @@ dependencies = [ "rstest", "serde", "sha3", + "temp-env", "thiserror", "time", "tokio", @@ -2567,6 +2568,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "temp-env" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" +dependencies = [ + "parking_lot", +] + [[package]] name = "termtree" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 3b3ecdf..f4418ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ time = "0.3.36" assert_cmd = "2.0.14" criterion = { version = "0.5.1", features = ["html_reports"] } rstest = "0.22.0" +temp-env = "0.3.6" [[bench]] name = "main" diff --git a/src/config.rs b/src/config.rs index 3cafd9a..551e8e2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,3 +14,24 @@ impl RunoConfig { } } } + +#[cfg(test)] +mod tests { + use rstest::*; + + use crate::k8s::K8s; + + use super::RunoConfig; + + #[fixture] + fn valid_k8s() -> K8s { + return K8s { dry_run: false }; + } + + #[rstest] + #[case(10)] + fn build_valid_requeue_duration(valid_k8s: K8s, #[case] requeue_duration: u64) { + let config = RunoConfig::build(valid_k8s, requeue_duration); + assert_eq!(config.requeue_duration, requeue_duration) + } +} diff --git a/src/errors.rs b/src/errors.rs index 62fc7f9..c13e638 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -26,3 +26,12 @@ impl fmt::Display for CantCreateStringFromRegex { write!(f, "Can't create random string from specified regex") } } + +#[derive(Debug, Clone)] +pub struct LogLevelMissing; + +impl fmt::Display for LogLevelMissing { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "RUST_LOG is not set properly!") + } +} diff --git a/src/logging.rs b/src/logging.rs index 2f07ca1..840abd8 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -1,30 +1,48 @@ -use tracing::error; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::{EnvFilter, Registry}; +use tracing_subscriber::fmt::format::{DefaultFields, Format}; +use tracing_subscriber::{EnvFilter, FmtSubscriber}; -pub fn set_logger() -> bool { - let logger = tracing_subscriber::fmt::layer().json(); - match EnvFilter::try_from_default_env().or_else(|_| EnvFilter::try_new("info")) { - Ok(env_filter) => { - let collector = Registry::default().with(logger).with(env_filter); - tracing::subscriber::set_global_default(collector).is_ok() - } - Err(e) => { - error!( - "Can't attach logger. No additional logs will be written!: {}", - e - ); - false +use crate::errors::LogLevelMissing; + +pub fn get_subscriber( + or_default: bool, +) -> Result, LogLevelMissing> { + match EnvFilter::try_from_default_env() { + Ok(ef) => Ok(tracing_subscriber::fmt().with_env_filter(ef).finish()), + Err(_) => { + if or_default { + Ok(tracing_subscriber::fmt() + .with_env_filter(EnvFilter::new("INFO")) + .finish()) + } else { + Err(LogLevelMissing) + } } } } #[cfg(test)] mod tests { - use crate::logging::set_logger; + use crate::logging::get_subscriber; + use rstest::*; + use std::env; + + #[rstest] + #[case("ERROR")] + #[case("WARN")] + #[case("INFO")] + #[case("DEBUG")] + #[case("TRACE")] + fn get_valid_subscriber(#[case] log_level: String) { + temp_env::with_var("RUST_LOG", Some(&log_level), || { + assert!(get_subscriber(false).is_ok()); + env::remove_var("RUST_LOG"); + }); + } - #[test] - fn is_logger_set() { - assert!(set_logger()); + #[rstest] + fn err_if_level_not_set() { + temp_env::with_var("RUST_LOG", None::<&str>, || { + assert!(get_subscriber(false).is_err()); + }); } } diff --git a/src/main.rs b/src/main.rs index 035b7f4..6ae2970 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,9 @@ use crate::k8s::K8s; use anyhow::anyhow; use clap::Parser; use config::RunoConfig; +use errors::LogLevelMissing; use tracing::info; +use tracing_subscriber::util::SubscriberInitExt; #[derive(Parser)] #[clap(author, version, about, long_about = None)] @@ -31,10 +33,14 @@ struct MainArgs { #[tokio::main] async fn main() -> anyhow::Result<()> { let args = MainArgs::parse(); - match logging::set_logger() { - true => info!("Logging initialized.."), - false => panic!("Logging not initialized properly!. Exiting..."), - } + let subscriber = match logging::get_subscriber(true) { + Ok(s) => { + info!("Logging initialized.."); + s + } + Err(LogLevelMissing) => panic!("RUST_LOG is not set properly!"), + }; + subscriber.init(); let k8s = K8s::build(args.dry_run); let config = RunoConfig::build(k8s, args.requeue_duration); match args.mode.as_str() {