use super::*;
use std::path::PathBuf;
fn system_unit(service_user: Option<&str>) -> String {
render_unit(&RenderParams {
scope: Scope::System,
exec_path: Path::new("/usr/local/bin/all-smi"),
service_user,
})
.expect("plain ASCII path must render")
}
fn user_unit() -> String {
render_unit(&RenderParams {
scope: Scope::User,
exec_path: Path::new("/home/dev/.cargo/bin/all-smi"),
service_user: None,
})
.expect("plain ASCII path must render")
}
#[test]
fn marker_is_the_first_line() {
let unit = system_unit(None);
assert_eq!(
unit.lines().next(),
Some(MANAGED_MARKER),
"the marker must lead the file so `head -1` identifies it"
);
assert!(is_managed(&unit));
}
#[test]
fn is_managed_rejects_a_foreign_unit() {
assert!(!is_managed(UNIT_TEMPLATE));
assert!(!is_managed("[Unit]\nDescription=hand written\n"));
}
#[test]
fn exec_start_uses_the_canonicalized_binary_path() {
let unit = system_unit(None);
assert!(
unit.contains("ExecStart=/usr/local/bin/all-smi api\n"),
"ExecStart must point at the running binary, got:\n{unit}"
);
assert!(
!unit.contains("ExecStart=/usr/bin/all-smi api\n"),
"the packaged ExecStart path must have been replaced, got:\n{unit}"
);
assert_eq!(
unit.matches("ExecStart=").count(),
1,
"exactly one ExecStart line must survive"
);
}
#[test]
fn system_scope_without_service_user_runs_as_root() {
let unit = system_unit(None);
assert!(
!unit.contains("\nUser="),
"no User= means systemd runs the unit as root, got:\n{unit}"
);
assert!(!unit.contains("\nGroup="), "Group= must be dropped too");
assert!(unit.contains("SupplementaryGroups=video render"));
assert!(unit.contains("NoNewPrivileges=true"));
assert!(unit.contains("ProtectSystem=strict"));
}
#[test]
fn system_scope_injects_the_requested_account() {
let unit = system_unit(Some("metrics"));
assert!(
unit.contains("\nUser=metrics\n"),
"--service-user must set User=, got:\n{unit}"
);
assert!(
unit.contains("\nGroup=metrics\n"),
"--service-user must set Group= to match, got:\n{unit}"
);
assert!(
!unit.contains("User=all-smi"),
"the packaged account must not leak through, got:\n{unit}"
);
}
#[test]
fn system_scope_keeps_the_wal_pin_and_boot_target() {
let unit = system_unit(None);
assert!(unit.contains("Environment=ALL_SMI_ENERGY_WAL_PATH=/var/cache/all-smi/energy-wal.bin"));
assert!(unit.contains("WantedBy=multi-user.target"));
assert!(unit.contains("Wants=network-online.target"));
}
#[test]
fn user_scope_drops_privileged_directives() {
let unit = user_unit();
assert!(!unit.contains("User="), "got:\n{unit}");
assert!(!unit.contains("Group="), "got:\n{unit}");
assert!(
!unit.contains("SupplementaryGroups="),
"a user manager cannot grant supplementary groups, got:\n{unit}"
);
}
#[test]
fn user_scope_drops_the_wal_pin() {
let unit = user_unit();
assert!(!unit.contains("ALL_SMI_ENERGY_WAL_PATH"), "got:\n{unit}");
}
#[test]
fn user_scope_targets_default_target_not_multi_user() {
let unit = user_unit();
assert!(
unit.contains("WantedBy=default.target"),
"a user manager has no multi-user.target, got:\n{unit}"
);
assert!(!unit.contains("multi-user.target"), "got:\n{unit}");
}
#[test]
fn user_scope_drops_network_online_dependencies() {
let unit = user_unit();
assert!(!unit.contains("network-online.target"), "got:\n{unit}");
assert!(unit.contains("Description=all-smi GPU/NPU metrics exporter (API mode)"));
}
#[test]
fn system_scope_keeps_every_hardening_directive() {
let unit = system_unit(None);
for directive in [
"NoNewPrivileges=true",
"ProtectSystem=strict",
"ProtectHome=true",
"PrivateTmp=true",
"ProtectKernelModules=true",
"ProtectControlGroups=true",
"RestrictSUIDSGID=true",
] {
assert!(
unit.contains(directive),
"{directive} must be preserved, got:\n{unit}"
);
}
}
const USER_SCOPE_KEPT_HARDENING: &[&str] = &["NoNewPrivileges=", "RestrictSUIDSGID="];
#[test]
fn user_scope_keeps_the_privilege_free_hardening() {
let unit = user_unit();
for directive in USER_SCOPE_KEPT_HARDENING {
assert!(
unit.contains(directive),
"{directive} needs no privilege and must be preserved, got:\n{unit}"
);
}
}
#[test]
fn user_scope_drops_everything_a_user_manager_cannot_apply() {
let unit = user_unit();
for directive in USER_SCOPE_DROPPED_PREFIXES {
assert!(
!unit.contains(directive),
"{directive} must be dropped in user scope or the unit fails before ExecStart, got:\n{unit}"
);
}
}
#[test]
fn user_scope_drops_protect_kernel_modules() {
let unit = user_unit();
assert!(
!unit.contains("ProtectKernelModules"),
"ProtectKernelModules needs a user namespace to alter the capability bounding set; \
leaving it in makes `systemctl --user start` fail with 218/CAPABILITIES, got:\n{unit}"
);
assert!(system_unit(None).contains("ProtectKernelModules=true"));
}
#[test]
fn kept_and_dropped_directive_lists_are_disjoint() {
for kept in USER_SCOPE_KEPT_HARDENING {
assert!(
!USER_SCOPE_DROPPED_PREFIXES.contains(kept),
"`{kept}` appears in both the kept and the dropped list"
);
}
}
#[test]
fn every_service_directive_in_the_user_render_is_classified() {
const KNOWN_SAFE: &[&str] = &[
"Type=",
"ExecStart=",
"EnvironmentFile=",
"Restart=",
"RestartSec=",
"RuntimeDirectory=",
"CacheDirectory=",
"NoNewPrivileges=",
"RestrictSUIDSGID=",
];
let unit = user_unit();
let mut in_service = false;
for line in unit.lines() {
let line = line.trim();
if line.starts_with('[') {
in_service = line == "[Service]";
continue;
}
if !in_service || line.is_empty() || line.starts_with('#') {
continue;
}
assert!(
KNOWN_SAFE.iter().any(|k| line.starts_with(k)),
"unclassified directive `{line}` reached the user-scope render. Decide whether a \
per-user systemd manager can apply it: add it to KNOWN_SAFE here if it needs no \
privilege, otherwise add it to USER_SCOPE_DROPPED_PREFIXES."
);
}
}
#[test]
fn kept_hardening_all_appears_in_the_shipped_unit() {
for prefix in USER_SCOPE_KEPT_HARDENING {
assert!(
UNIT_TEMPLATE
.lines()
.any(|l| l.trim_start().starts_with(prefix)),
"`{prefix}` is listed as kept user-scope hardening but the shipped unit no longer \
sets it"
);
}
}
#[test]
fn user_scope_can_still_read_the_operator_config() {
let unit = user_unit();
assert!(!unit.contains("ProtectHome"), "got:\n{unit}");
}
#[test]
fn neither_scope_adds_a_device_or_proc_restriction() {
for unit in [system_unit(None), system_unit(Some("all-smi")), user_unit()] {
assert!(!unit.contains("PrivateDevices"), "got:\n{unit}");
assert!(!unit.contains("ProtectProc"), "got:\n{unit}");
assert!(!unit.contains("ProcSubset"), "got:\n{unit}");
}
}
#[test]
fn dropped_prefixes_all_appear_in_the_shipped_unit() {
for prefix in USER_SCOPE_DROPPED_PREFIXES {
assert!(
UNIT_TEMPLATE
.lines()
.any(|l| l.trim_start().starts_with(prefix)),
"`{prefix}` is in the user-scope drop list but no longer exists in the shipped unit"
);
}
}
#[test]
fn rendered_unit_ends_with_a_newline() {
assert!(system_unit(None).ends_with('\n'));
assert!(user_unit().ends_with('\n'));
}
#[test]
fn exec_path_with_spaces_is_quoted() {
let unit = render_unit(&RenderParams {
scope: Scope::System,
exec_path: Path::new("/opt/my tools/all-smi"),
service_user: None,
})
.expect("a path with spaces is representable when quoted");
assert!(
unit.contains("ExecStart=\"/opt/my tools/all-smi\" api\n"),
"got:\n{unit}"
);
}
#[test]
fn exec_path_percent_is_escaped() {
let unit = render_unit(&RenderParams {
scope: Scope::System,
exec_path: Path::new("/opt/100%/all-smi"),
service_user: None,
})
.expect("percent is escapable");
assert!(
unit.contains("ExecStart=/opt/100%%/all-smi api\n"),
"% starts a systemd specifier and must be doubled, got:\n{unit}"
);
}
#[test]
fn exec_path_with_a_quote_is_rejected() {
let err = render_unit(&RenderParams {
scope: Scope::System,
exec_path: Path::new("/opt/we\"ird/all-smi"),
service_user: None,
})
.expect_err("an embedded double quote must be refused");
assert!(matches!(err, RenderError::UnsafePath(_)));
}
#[test]
fn exec_path_with_a_backslash_is_rejected() {
let err = render_unit(&RenderParams {
scope: Scope::System,
exec_path: Path::new("/opt/back\\slash/all-smi"),
service_user: None,
})
.expect_err("a backslash is a systemd escape and must be refused");
assert!(matches!(err, RenderError::UnsafePath(_)));
}
#[test]
fn template_is_the_shipped_unit_verbatim() {
assert!(UNIT_TEMPLATE.contains("[Unit]"));
assert!(UNIT_TEMPLATE.contains("ExecStart=/usr/bin/all-smi api"));
assert!(UNIT_TEMPLATE.contains("EnvironmentFile=-/etc/default/all-smi"));
assert!(UNIT_TEMPLATE.contains("Type=exec"));
assert!(UNIT_TEMPLATE.contains("Restart=on-failure"));
assert!(UNIT_TEMPLATE.contains("RestartSec=5"));
}
#[test]
fn render_is_deterministic() {
let path = PathBuf::from("/usr/local/bin/all-smi");
let params = RenderParams {
scope: Scope::System,
exec_path: &path,
service_user: Some("all-smi"),
};
assert_eq!(
render_unit(¶ms).unwrap(),
render_unit(¶ms).unwrap(),
"reinstall must produce byte-identical output so it is a no-op"
);
}