From 9c96c9193db11496cf627c51db4bb5c55587afb8 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Sun, 3 May 2026 17:32:15 +0000 Subject: [PATCH] Pin node.log_level parser string-to-tracing::Level mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add table-driven unit test test_log_level_parser to src/config/node.rs covering all 5 explicit match arms (trace, debug, warn|warning, error), the implicit None-and-unknown → INFO default, case-insensitivity via to_lowercase (TRACE / Debug / Warning / WARN / ERROR / INFO), and edge cases (empty string, "verbose"). Pins observed behavior: there is no explicit "info" arm — it falls through the wildcard to INFO, identical to unknown strings. --- src/config/node.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/config/node.rs b/src/config/node.rs index 93c7c40..6bfcfd5 100644 --- a/src/config/node.rs +++ b/src/config/node.rs @@ -1084,6 +1084,52 @@ mod tests { assert_eq!(c.startup_sweep_max_age_secs, 3_600); } + #[test] + fn test_log_level_parser() { + // Pin the observed behavior of NodeConfig::log_level(): + // - 5 explicit lowercased match arms (trace/debug/warn|warning/error) + // - INFO is the default (no explicit "info" arm; falls through default) + // - Case-insensitive via .to_lowercase() + // - Unknown strings and None both fall through to INFO + let cases: &[(Option<&str>, tracing::Level)] = &[ + // Explicit arms (lowercase canonical form) + (Some("trace"), tracing::Level::TRACE), + (Some("debug"), tracing::Level::DEBUG), + (Some("warn"), tracing::Level::WARN), + (Some("warning"), tracing::Level::WARN), + (Some("error"), tracing::Level::ERROR), + // "info" has no explicit arm — falls through default + (Some("info"), tracing::Level::INFO), + // None → default INFO + (None, tracing::Level::INFO), + // Case-insensitivity (parser lowercases via .to_lowercase()) + (Some("TRACE"), tracing::Level::TRACE), + (Some("Debug"), tracing::Level::DEBUG), + (Some("Warning"), tracing::Level::WARN), + (Some("WARN"), tracing::Level::WARN), + (Some("ERROR"), tracing::Level::ERROR), + (Some("INFO"), tracing::Level::INFO), + // Unknown strings → INFO default (no error path) + (Some("verbose"), tracing::Level::INFO), + (Some("nonsense"), tracing::Level::INFO), + (Some(""), tracing::Level::INFO), + ]; + + for (input, expected) in cases { + let cfg = NodeConfig { + log_level: input.map(|s| s.to_string()), + ..NodeConfig::default() + }; + assert_eq!( + cfg.log_level(), + *expected, + "input {:?} should map to {:?}", + input, + expected + ); + } + } + #[cfg(windows)] #[test] fn test_default_socket_path_windows() {