tests/systemd_split.rs
//! **The systemd lifecycle is its own small crate** (lane B4, A31 §7.5).
//!
//! Holger's `systemd` flavour needs the unit render, the scope, the user and
//! dirs, the guarded purge and start/stop/status over D-Bus: about a quarter of
//! this crate. The rest (k8s, vmsuite, korpprov, machine, msi-oci, promote,
//! socket, install, pack …) compiled into Holger without being used. The
//! lifecycle now lives in `skidbladnir-systemd`; this crate re-exports it at the
//! old paths, so Gunnar, nornir, dwarves and monetize are unchanged.
/// The old paths are the new crate's items, not copies: one type each.
#[test]
fn the_root_re_exports_the_lifecycle_at_its_old_paths() {
fn same<T>(_: T, _: T) {}
let a = skidbladnir::service::ServiceSpec::new("holger", "Holger", "/usr/bin/holger");
let b = skidbladnir_systemd::service::ServiceSpec::new("holger", "Holger", "/usr/bin/holger");
same(a, b);
same(skidbladnir::systemd::Scope::User, skidbladnir_systemd::systemd::Scope::User);
same(skidbladnir::service::AgentMode::Fat, skidbladnir_systemd::service::AgentMode::Fat);
let _: fn(&skidbladnir::systemd::SystemdServiceSpec, skidbladnir::systemd::Scope) -> String =
skidbladnir_systemd::systemd::systemd_unit_scoped;
let _ = |p: &str| skidbladnir_systemd::uninstall::DataRoot::from_env("HOLGER_DATA", p).is_ok();
let _ = skidbladnir_systemd::systemd::guarded_remove_dir_all;
}
/// The root still renders Kubernetes (its own renderer, over the shared spec),
/// and the lifecycle crate alone does not pretend to.
#[test]
fn kubernetes_rendering_stays_with_the_root() {
use skidbladnir::service::Backend;
assert!(skidbladnir::service::renderer_for(Backend::Kubernetes).is_some());
assert!(skidbladnir_systemd::service::renderer_for(Backend::Kubernetes).is_none());
assert!(skidbladnir_systemd::service::renderer_for(Backend::SystemdSystem).is_some());
}
/// The lifecycle crate's own dependencies: the small set a systemd host needs.
/// A new one is a decision, made here.
#[test]
fn the_lifecycle_crate_links_only_what_a_systemd_host_needs() {
let text = std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/crates/skidbladnir-systemd/Cargo.toml")).unwrap();
let v: toml::Value = toml::from_str(&text).unwrap();
let deps: Vec<&str> = v["dependencies"].as_table().unwrap().keys().map(String::as_str).collect();
let allowed = [
"anyhow", "serde", "serde_json", "tracing", "zbus", "nornir-hash", "hex", "blake3", "chrono", "uuid",
// `pki` (off for Holger): the identity ceremony's keys.
"ed25519-dalek", "getrandom",
// `testmatrix` (off): the coverage rows.
"nornir-testmatrix",
];
for d in &deps {
assert!(allowed.contains(d), "skidbladnir-systemd depends on `{d}`, which a systemd host does not need");
}
for heavy in ["kube", "k8s-openapi", "reqwest", "ureq", "draupnir", "jera", "gix", "tokio", "tonic", "rcgen", "znippy-common"] {
assert!(!deps.contains(&heavy), "{heavy}");
}
}