use super::service::*;
use crate::core::types::{MachineTarget, Resource, ResourceType};
fn make_service_resource(name: &str, state: &str) -> Resource {
Resource {
resource_type: ResourceType::Service,
machine: MachineTarget::Single("m1".to_string()),
state: Some(state.to_string()),
depends_on: vec![],
provider: None,
packages: vec![],
version: None,
path: None,
content: None,
source: None,
target: None,
owner: None,
group: None,
mode: None,
name: Some(name.to_string()),
enabled: Some(true),
restart_on: vec![],
triggers: vec![],
fs_type: None,
options: None,
uid: None,
shell: None,
home: None,
groups: vec![],
ssh_authorized_keys: vec![],
system_user: false,
schedule: None,
command: None,
image: None,
ports: vec![],
environment: vec![],
volumes: vec![],
restart: None,
protocol: None,
port: None,
action: None,
from_addr: None,
recipe: None,
inputs: std::collections::HashMap::new(),
arch: vec![],
tags: vec![],
resource_group: None,
when: None,
count: None,
for_each: None,
chroot_dir: None,
namespace_uid: None,
namespace_gid: None,
seccomp: false,
netns: false,
cpuset: None,
memory_limit: None,
overlay_lower: None,
overlay_upper: None,
overlay_work: None,
overlay_merged: None,
format: None,
quantization: None,
checksum: None,
cache_dir: None,
gpu_backend: None,
driver_version: None,
cuda_version: None,
rocm_version: None,
devices: vec![],
persistence_mode: None,
compute_mode: None,
gpu_memory_limit_mb: None,
output_artifacts: vec![],
completion_check: None,
timeout: None,
working_dir: None,
task_mode: None,
task_inputs: vec![],
stages: vec![],
cache: false,
gpu_device: None,
restart_delay: None,
quality_gate: None,
health_check: None,
restart_policy: None,
pre_apply: None,
post_apply: None,
lifecycle: None,
store: false,
sudo: false,
script: None,
gather: vec![],
scatter: vec![],
build_machine: None,
repo: None,
tag: None,
asset_pattern: None,
binary: None,
install_dir: None,
}
}
#[test]
fn test_fj008_check_service() {
let r = make_service_resource("nfs-kernel-server", "running");
let script = check_script(&r);
assert!(script.contains("systemctl is-active 'nfs-kernel-server'"));
assert!(script.contains("systemctl is-enabled 'nfs-kernel-server'"));
assert!(
script.contains("command -v systemctl"),
"must include systemd guard"
);
}
#[test]
fn test_fj008_apply_start() {
let r = make_service_resource("nfs-kernel-server", "running");
let script = apply_script(&r);
assert!(script.contains("systemctl start"));
assert!(script.contains("systemctl enable"));
}
#[test]
fn test_fj008_apply_stop() {
let r = make_service_resource("nfs-kernel-server", "stopped");
let script = apply_script(&r);
assert!(script.contains("systemctl stop"));
}
#[test]
fn test_fj008_disable() {
let mut r = make_service_resource("svc", "running");
r.enabled = Some(false);
let script = apply_script(&r);
assert!(script.contains("systemctl disable"));
}
#[test]
fn test_fj008_restart_on() {
let mut r = make_service_resource("svc", "running");
r.restart_on = vec!["config-file".to_string()];
let script = apply_script(&r);
assert!(script.contains("systemctl reload-or-restart"));
}
#[test]
fn test_fj008_state_query_script() {
let r = make_service_resource("nginx", "running");
let script = state_query_script(&r);
assert!(script.contains("systemctl is-active 'nginx'"));
assert!(script.contains("systemctl is-enabled 'nginx'"));
assert!(
script.contains("command -v systemctl"),
"must include systemd guard"
);
}
#[test]
fn test_fj081_systemd_guard_in_all_scripts() {
let r = make_service_resource("test-svc", "running");
let check = check_script(&r);
assert!(check.contains("FORJAR_WARN: systemctl not found"));
assert!(check.contains("exit 0"));
let apply = apply_script(&r);
assert!(apply.contains("FORJAR_WARN: systemctl not found"));
assert!(apply.contains("exit 0"));
let query = state_query_script(&r);
assert!(query.contains("FORJAR_WARN: systemctl not found"));
assert!(query.contains("exit 0"));
}
#[test]
fn test_fj008_apply_pipefail() {
let r = make_service_resource("nginx", "running");
let script = apply_script(&r);
assert!(
script.starts_with("set -euo pipefail"),
"service apply must start with pipefail"
);
}
#[test]
fn test_fj008_apply_idempotent_start() {
let r = make_service_resource("nginx", "running");
let script = apply_script(&r);
assert!(script.contains("if ! systemctl is-active --quiet"));
assert!(script.contains("systemctl start 'nginx'"));
}
#[test]
fn test_fj008_apply_idempotent_stop() {
let r = make_service_resource("nginx", "stopped");
let script = apply_script(&r);
assert!(script.contains("if systemctl is-active --quiet"));
assert!(script.contains("systemctl stop 'nginx'"));
}
#[test]
fn test_fj008_apply_idempotent_enable() {
let r = make_service_resource("nginx", "running");
let script = apply_script(&r);
assert!(script.contains("if ! systemctl is-enabled --quiet"));
assert!(script.contains("systemctl enable 'nginx'"));
}
#[test]
fn test_fj008_default_state_and_enabled() {
let mut r = make_service_resource("svc", "running");
r.state = None;
r.enabled = None;
let script = apply_script(&r);
assert!(
script.contains("systemctl start"),
"default state should be running"
);
assert!(
script.contains("systemctl enable"),
"default enabled should be true"
);
}
#[test]
fn test_fj008_stopped_and_disabled() {
let mut r = make_service_resource("svc", "stopped");
r.enabled = Some(false);
let script = apply_script(&r);
assert!(script.contains("systemctl stop"));
assert!(script.contains("systemctl disable"));
assert!(!script.contains("systemctl start"));
assert!(!script.contains("systemctl enable 'svc'\nfi"));
}
#[test]
fn test_fj008_invalid_state_no_op() {
let r = make_service_resource("svc", "restarted");
let script = apply_script(&r);
assert!(!script.contains("systemctl start"));
assert!(!script.contains("systemctl stop"));
assert!(script.contains("systemctl enable"));
}
#[test]
fn test_fj008_restart_on_with_disabled() {
let mut r = make_service_resource("svc", "running");
r.enabled = Some(false);
r.restart_on = vec!["config-file".to_string()];
let script = apply_script(&r);
assert!(script.contains("systemctl reload-or-restart 'svc'"));
assert!(script.contains("systemctl disable"));
}
#[test]
fn test_fj008_no_name_defaults_to_unknown() {
let mut r = make_service_resource("placeholder", "running");
r.name = None;
let script = apply_script(&r);
assert!(script.contains("systemctl start 'unknown'"));
let check = check_script(&r);
assert!(check.contains("is-active 'unknown'"));
let query = state_query_script(&r);
assert!(query.contains("is-active 'unknown'"));
}
#[test]
fn test_fj008_multiple_restart_on_single_reload() {
let mut r = make_service_resource("app", "running");
r.restart_on = vec!["cfg1".to_string(), "cfg2".to_string()];
let script = apply_script(&r);
let count = script.matches("systemctl reload-or-restart").count();
assert_eq!(count, 1, "should emit exactly one reload-or-restart");
}
#[test]
fn test_fj132_check_script_idempotent() {
let r = make_service_resource("nginx", "running");
let s1 = check_script(&r);
let s2 = check_script(&r);
assert_eq!(s1, s2, "check_script must be idempotent");
}
#[test]
fn test_fj132_state_query_captures_active_and_enabled() {
let r = make_service_resource("nginx", "running");
let script = state_query_script(&r);
assert!(
script.contains("systemctl is-active 'nginx'"),
"state_query should check is-active"
);
assert!(
script.contains("systemctl is-enabled 'nginx'"),
"state_query should check is-enabled"
);
}
#[test]
fn test_fj132_apply_running_enabled_explicit() {
let mut r = make_service_resource("app", "running");
r.enabled = Some(true);
let script = apply_script(&r);
assert!(script.contains("systemctl start 'app'"));
assert!(script.contains("systemctl enable 'app'"));
assert!(!script.contains("systemctl stop"));
assert!(!script.contains("systemctl disable"));
}
#[test]
fn test_fj132_restart_on_stopped_service() {
let mut r = make_service_resource("worker", "stopped");
r.restart_on = vec!["config".to_string()];
let script = apply_script(&r);
assert!(
script.contains("systemctl reload-or-restart 'worker'"),
"restart_on should trigger even for stopped services"
);
assert!(script.contains("systemctl stop"));
}
#[test]
fn test_fj036_service_apply_enable_true() {
let mut r = make_service_resource("caddy", "running");
r.enabled = Some(true);
let script = apply_script(&r);
assert!(
script.contains("systemctl enable 'caddy'"),
"enabled=true must emit systemctl enable"
);
assert!(
!script.contains("systemctl disable"),
"enabled=true must not emit disable"
);
}
#[test]
fn test_fj036_service_apply_stopped() {
let r = make_service_resource("redis", "stopped");
let script = apply_script(&r);
assert!(
script.contains("systemctl stop 'redis'"),
"state=stopped must emit systemctl stop with service name"
);
assert!(
!script.contains("systemctl start"),
"state=stopped must not emit start"
);
}
#[test]
fn test_fj036_service_apply_restart_on() {
let mut r = make_service_resource("myapp", "running");
r.restart_on = vec!["etc-myapp-conf".to_string(), "myapp-env".to_string()];
let script = apply_script(&r);
assert!(
script.contains("systemctl reload-or-restart 'myapp'"),
"restart_on with deps must trigger reload-or-restart"
);
}
#[test]
fn test_fj153_stopped_disabled_no_restart() {
let mut r = make_service_resource("old-app", "stopped");
r.enabled = Some(false);
r.restart_on = vec![];
let script = apply_script(&r);
assert!(script.contains("systemctl stop 'old-app'"));
assert!(script.contains("systemctl disable 'old-app'"));
assert!(!script.contains("systemctl start"));
assert!(!script.contains("systemctl enable 'old-app'\nfi"));
assert!(!script.contains("reload-or-restart"));
}
#[test]
fn test_fj153_unknown_state_still_enables() {
let mut r = make_service_resource("custom", "custom-state");
r.enabled = Some(true);
let script = apply_script(&r);
assert!(!script.contains("systemctl start"));
assert!(!script.contains("systemctl stop"));
assert!(script.contains("systemctl enable 'custom'"));
}
#[test]
fn test_fj153_unknown_state_disables() {
let mut r = make_service_resource("custom", "custom-state");
r.enabled = Some(false);
let script = apply_script(&r);
assert!(script.contains("systemctl disable 'custom'"));
}
#[test]
fn test_fj153_running_disabled_restart_on() {
let mut r = make_service_resource("worker", "running");
r.enabled = Some(false);
r.restart_on = vec!["config".to_string(), "env".to_string()];
let script = apply_script(&r);
assert!(script.contains("systemctl start 'worker'"));
assert!(script.contains("systemctl disable 'worker'"));
assert!(script.contains("systemctl reload-or-restart 'worker'"));
}
#[test]
fn test_fj036_service_state_query_active() {
let r = make_service_resource("postgresql", "running");
let script = state_query_script(&r);
assert!(
script.contains("systemctl is-active 'postgresql'"),
"state_query must check is-active for the service"
);
assert!(
script.contains("active="),
"state_query must capture active state into variable"
);
}