#![allow(
clippy::missing_docs_in_private_items,
reason = "test helpers and fixtures do not need doc comments"
)]
use super::*;
#[test]
fn rotate_daemon_log_if_due_is_a_no_op_when_file_is_missing() {
let path = std::env::temp_dir().join(format!("moadim-log-missing-{}", uuid::Uuid::new_v4()));
rotate_daemon_log_if_due(&path);
assert!(!path.exists());
}
#[test]
fn rotate_daemon_log_if_due_leaves_small_files_in_place() {
let base = std::env::temp_dir().join(format!("moadim-log-small-{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&base).unwrap();
let path = base.join("daemon.log");
std::fs::write(&path, b"a few bytes").unwrap();
rotate_daemon_log_if_due(&path);
assert!(path.exists(), "file under the cap must not be rotated");
let mut rotated = path.as_os_str().to_os_string();
rotated.push(".1");
assert!(!std::path::Path::new(&rotated).exists());
let _ = std::fs::remove_dir_all(&base);
}
#[test]
fn rotate_daemon_log_if_due_rolls_the_file_past_the_cap() {
let base = std::env::temp_dir().join(format!("moadim-log-big-{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&base).unwrap();
let path = base.join("daemon.log");
std::fs::write(&path, vec![b'x'; (DAEMON_LOG_MAX_BYTES + 1) as usize]).unwrap();
rotate_daemon_log_if_due(&path);
assert!(
!path.exists(),
"the oversized file must be moved out of the way"
);
let mut rotated = path.as_os_str().to_os_string();
rotated.push(".1");
assert!(
std::path::Path::new(&rotated).exists(),
"the oversized file must land at the .1 sibling"
);
let _ = std::fs::remove_dir_all(&base);
}
#[test]
fn rotate_daemon_log_if_due_replaces_a_previous_1_file() {
let base = std::env::temp_dir().join(format!("moadim-log-replace-{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&base).unwrap();
let path = base.join("daemon.log");
std::fs::write(&path, vec![b'y'; (DAEMON_LOG_MAX_BYTES + 1) as usize]).unwrap();
let mut rotated = path.as_os_str().to_os_string();
rotated.push(".1");
let rotated = std::path::PathBuf::from(rotated);
std::fs::write(&rotated, b"stale rotated content").unwrap();
rotate_daemon_log_if_due(&path);
assert!(rotated.exists());
assert_eq!(
std::fs::metadata(&rotated).unwrap().len(),
DAEMON_LOG_MAX_BYTES + 1,
"rotation must replace a stale .1 file with the freshly-rolled one"
);
let _ = std::fs::remove_dir_all(&base);
}
#[test]
fn log_rotation_is_due_is_false_for_a_small_fresh_log() {
assert!(!log_rotation_is_due(1024, Duration::from_secs(60)));
}
#[test]
fn log_rotation_is_due_is_true_when_oversized_but_fresh() {
assert!(log_rotation_is_due(
DAEMON_LOG_MAX_BYTES + 1,
Duration::from_secs(0)
));
}
#[test]
fn log_rotation_is_due_is_true_when_small_but_stale() {
assert!(log_rotation_is_due(
1024,
DAEMON_LOG_MAX_AGE + Duration::from_secs(1)
));
}
#[test]
fn log_rotation_is_due_is_false_right_at_the_age_boundary() {
assert!(!log_rotation_is_due(1024, DAEMON_LOG_MAX_AGE));
}
struct EnvGuard {
name: &'static str,
previous: Option<std::ffi::OsString>,
}
impl EnvGuard {
fn set(name: &'static str, value: &str) -> Self {
let previous = std::env::var_os(name);
unsafe {
std::env::set_var(name, value);
}
Self { name, previous }
}
}
impl Drop for EnvGuard {
fn drop(&mut self) {
unsafe {
match self.previous.take() {
Some(value) => std::env::set_var(self.name, value),
None => std::env::remove_var(self.name),
}
}
}
}
#[test]
fn http_request_core_rejects_an_unparsable_bind_override() {
let _addr = EnvGuard::set(crate::cli::BIND_ADDR_ENV, "not-a-socket-addr");
let err = http_request_core("GET", "/health", None, Duration::from_millis(50)).unwrap_err();
assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
assert!(
err.to_string().contains("invalid bind address"),
"unexpected message: {err}"
);
}
#[test]
fn ensure_readme_returns_early_when_the_path_has_no_parent() {
ensure_readme(std::path::Path::new(""), "ignored");
}