#![allow(
clippy::missing_docs_in_private_items,
reason = "test helpers and fixtures do not need doc comments"
)]
use super::*;
fn scratch_dir(tag: &str) -> std::path::PathBuf {
std::env::temp_dir().join(format!("moadim-rs-{tag}-{}", uuid::Uuid::new_v4()))
}
fn with_override_home(body: impl FnOnce(&std::path::Path)) {
let home = scratch_dir("override-home");
std::fs::create_dir_all(&home).unwrap();
let previous = std::env::var_os("MOADIM_HOME_OVERRIDE");
unsafe {
std::env::set_var("MOADIM_HOME_OVERRIDE", &home);
}
body(&home);
unsafe {
match previous {
Some(value) => std::env::set_var("MOADIM_HOME_OVERRIDE", value),
None => std::env::remove_var("MOADIM_HOME_OVERRIDE"),
}
}
let _ = std::fs::remove_dir_all(&home);
}
#[test]
fn migrate_trigger_logs_from_dir_missing_dir_returns() {
let missing = scratch_dir("trigger-logs-missing");
migrate_trigger_logs_from_dir(&missing);
assert!(!missing.exists());
}
#[test]
fn migrate_trigger_logs_from_dir_migrates_scheduled_and_manual() {
let dir = scratch_dir("trigger-logs-migrate");
std::fs::create_dir_all(&dir).unwrap();
let routine_dir = dir.join("my-routine");
std::fs::create_dir_all(&routine_dir).unwrap();
std::fs::write(
routine_dir.join("scheduled.local.toml"),
"last_scheduled_trigger_at = 1111\n",
)
.unwrap();
std::fs::write(
routine_dir.join("state.local.toml"),
"last_manual_trigger_at = 2222\n",
)
.unwrap();
migrate_trigger_logs_from_dir(&dir);
assert!(
!routine_dir.join("scheduled.local.toml").exists(),
"legacy toml should be removed"
);
let sched_text = std::fs::read_to_string(routine_dir.join("scheduled.log")).unwrap();
assert_eq!(sched_text, "1111\n");
let manual_text = std::fs::read_to_string(routine_dir.join("manual.log")).unwrap();
assert_eq!(manual_text, "2222\n");
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn migrate_trigger_logs_from_dir_skips_when_logs_already_exist() {
let dir = scratch_dir("trigger-logs-skip");
std::fs::create_dir_all(&dir).unwrap();
let routine_dir = dir.join("my-routine");
std::fs::create_dir_all(&routine_dir).unwrap();
std::fs::write(
routine_dir.join("scheduled.local.toml"),
"last_scheduled_trigger_at = 5555\n",
)
.unwrap();
std::fs::write(routine_dir.join("scheduled.log"), "9999\n").unwrap();
std::fs::write(routine_dir.join("manual.log"), "8888\n").unwrap();
std::fs::write(
routine_dir.join("state.local.toml"),
"last_manual_trigger_at = 7777\n",
)
.unwrap();
migrate_trigger_logs_from_dir(&dir);
assert_eq!(
std::fs::read_to_string(routine_dir.join("scheduled.log")).unwrap(),
"9999\n"
);
assert_eq!(
std::fs::read_to_string(routine_dir.join("manual.log")).unwrap(),
"8888\n"
);
assert!(routine_dir.join("scheduled.local.toml").exists());
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn migrate_trigger_logs_from_dir_skips_non_dirs_and_unparsable() {
let dir = scratch_dir("trigger-logs-nondir");
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(dir.join("loose.txt"), "ignore me").unwrap();
let routine_dir = dir.join("my-routine");
std::fs::create_dir_all(&routine_dir).unwrap();
migrate_trigger_logs_from_dir(&dir);
assert!(!routine_dir.join("scheduled.log").exists());
assert!(!routine_dir.join("manual.log").exists());
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn migrate_trigger_logs_from_dir_removes_scheduled_toml_when_no_timestamp() {
let dir = scratch_dir("trigger-logs-no-ts");
std::fs::create_dir_all(&dir).unwrap();
let routine_dir = dir.join("my-routine");
std::fs::create_dir_all(&routine_dir).unwrap();
std::fs::write(routine_dir.join("scheduled.local.toml"), "").unwrap();
migrate_trigger_logs_from_dir(&dir);
assert!(!routine_dir.join("scheduled.log").exists());
assert!(!routine_dir.join("scheduled.local.toml").exists());
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
#[cfg(unix)]
fn migrate_trigger_logs_from_dir_logs_on_scheduled_write_failure() {
use std::os::unix::fs::PermissionsExt;
let dir = scratch_dir("trigger-logs-sched-fail");
std::fs::create_dir_all(&dir).unwrap();
let routine_dir = dir.join("my-routine");
std::fs::create_dir_all(&routine_dir).unwrap();
std::fs::write(
routine_dir.join("scheduled.local.toml"),
"last_scheduled_trigger_at = 42\n",
)
.unwrap();
std::fs::set_permissions(&routine_dir, std::fs::Permissions::from_mode(0o555)).unwrap();
migrate_trigger_logs_from_dir(&dir);
std::fs::set_permissions(&routine_dir, std::fs::Permissions::from_mode(0o755)).unwrap();
assert!(routine_dir.join("scheduled.local.toml").exists());
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
#[cfg(unix)]
fn migrate_trigger_logs_from_dir_logs_on_manual_write_failure() {
use std::os::unix::fs::PermissionsExt;
let dir = scratch_dir("trigger-logs-manual-fail");
std::fs::create_dir_all(&dir).unwrap();
let routine_dir = dir.join("my-routine");
std::fs::create_dir_all(&routine_dir).unwrap();
std::fs::write(
routine_dir.join("state.local.toml"),
"last_manual_trigger_at = 77\n",
)
.unwrap();
std::fs::set_permissions(&routine_dir, std::fs::Permissions::from_mode(0o555)).unwrap();
migrate_trigger_logs_from_dir(&dir);
std::fs::set_permissions(&routine_dir, std::fs::Permissions::from_mode(0o755)).unwrap();
assert!(!routine_dir.join("manual.log").exists());
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn migrate_trigger_logs_public_wrapper_runs() {
with_override_home(|_home| {
migrate_trigger_logs();
});
}