use crate::cli::ui::{cron_blocked_by_a2a, daemon_start_line, scheduler_lock_for_start};
use crate::config::profile::acquire_scheduler_lock_in;
use std::cell::Cell;
fn lock_dir() -> tempfile::TempDir {
tempfile::TempDir::new().expect("temp dir")
}
#[test]
fn a_blocked_start_holds_no_scheduler_lock() {
let dir = lock_dir();
let inherited = acquire_scheduler_lock_in(dir.path(), "default")
.expect("the test needs a free lock dir to hand over");
let acquire_calls = Cell::new(0);
let taken = scheduler_lock_for_start(true, Some(inherited), || {
acquire_calls.set(acquire_calls.get() + 1);
None
});
assert!(taken.is_none(), "a start with no scheduler takes no lock");
assert_eq!(
acquire_calls.get(),
0,
"a blocked start must not even try to acquire the lock"
);
assert!(
acquire_scheduler_lock_in(dir.path(), "default").is_some(),
"the blocked start must release the lock it was handed, so another process can schedule"
);
}
#[test]
fn an_unblocked_start_keeps_the_inherited_lock() {
let dir = lock_dir();
let inherited = acquire_scheduler_lock_in(dir.path(), "default").expect("free lock dir");
let taken = scheduler_lock_for_start(false, Some(inherited), || {
panic!("an inherited lock must not trigger a second acquisition")
});
assert!(
taken.is_some(),
"the inherited lock is the one this start holds"
);
assert!(
acquire_scheduler_lock_in(dir.path(), "default").is_none(),
"the lock is still held by this start"
);
}
#[test]
fn an_unblocked_start_acquires_when_nothing_was_inherited() {
let dir = lock_dir();
let path = dir.path().to_path_buf();
let taken =
scheduler_lock_for_start(false, None, || acquire_scheduler_lock_in(&path, "default"));
assert!(taken.is_some(), "the start owns scheduling for the profile");
assert!(
acquire_scheduler_lock_in(dir.path(), "default").is_none(),
"and nothing else can take it while this start lives"
);
}
#[test]
fn only_an_enabled_unready_gateway_blocks_the_scheduler() {
assert!(
!cron_blocked_by_a2a(false, false),
"A2A off is never a blocker"
);
assert!(
!cron_blocked_by_a2a(false, true),
"A2A off, readiness irrelevant"
);
assert!(!cron_blocked_by_a2a(true, true), "A2A up is not a blocker");
assert!(
cron_blocked_by_a2a(true, false),
"enabled but not ready blocks"
);
}
#[test]
fn a_degraded_start_names_the_failed_bind_and_the_lost_cron() {
let plain = daemon_start_line(false, "127.0.0.1", 18790);
assert_eq!(plain, "🦀 OpenCrabs daemon running. Press Ctrl+C to stop.");
let degraded = daemon_start_line(true, "127.0.0.1", 18790);
assert_ne!(
degraded, plain,
"a failed bind must not claim a normal start"
);
assert!(
!degraded.contains("daemon running."),
"not the success line"
);
assert!(
degraded.contains("degraded"),
"the state is named: {degraded}"
);
assert!(
degraded.contains("127.0.0.1:18790"),
"the operator needs the address that failed: {degraded}"
);
assert!(
degraded.contains("cron scheduler is off"),
"and what it costs: {degraded}"
);
}