mecha10-cli 0.9.0

Mecha10 CLI tool
Documentation

use mecha10_cli::services::process::*;

#[test]
fn test_new_service() {
    let service = ProcessService::new();
    assert_eq!(service.count(), 0);
    assert!(service.is_empty());
}

#[test]
fn test_spawn_node() -> Result<()> {
    let mut service = ProcessService::new();

    let pid = service.spawn_node("test_process", "sleep", &["1"])?;

    assert!(pid > 0);
    assert_eq!(service.count(), 1);
    assert!(!service.is_empty());

    service.cleanup();

    Ok(())
}

#[test]
fn test_is_running() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("test_process", "sleep", &["2"])?;

    assert!(service.is_running("test_process"));

    service.stop("test_process")?;

    assert!(!service.is_running("test_process"));

    Ok(())
}

#[test]
fn test_stop_process() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("test_process", "sleep", &["10"])?;
    assert_eq!(service.count(), 1);

    service.stop("test_process")?;

    Ok(())
}

#[test]
fn test_cleanup() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("test1", "sleep", &["5"])?;
    service.spawn_node("test2", "sleep", &["5"])?;

    assert_eq!(service.count(), 2);

    service.cleanup();


    Ok(())
}


#[test]
fn test_default() {
    let service = ProcessService::default();
    assert_eq!(service.count(), 0);
    assert!(service.is_empty());
}

#[test]
fn test_spawn_with_output() -> Result<()> {
    let mut service = ProcessService::new();

    let pid = service.spawn_with_output("test_output", "sleep", &["1"])?;
    assert!(pid > 0);
    assert_eq!(service.count(), 1);

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_with_env() -> Result<()> {
    let mut service = ProcessService::new();

    let mut env = HashMap::new();
    env.insert("TEST_VAR".to_string(), "test_value".to_string());

    let pid = service.spawn_with_env("test_env", "sleep", &["1"], env)?;
    assert!(pid > 0);
    assert_eq!(service.count(), 1);

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_in_dir() -> Result<()> {
    let mut service = ProcessService::new();

    let pid = service.spawn_in_dir("test_dir", "sleep", &["1"], "/tmp")?;
    assert!(pid > 0);
    assert_eq!(service.count(), 1);

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_nodes_multiple() -> Result<()> {
    let mut service = ProcessService::new();

    let nodes = vec![
        ("node1", "sleep", vec!["1"]),
        ("node2", "sleep", vec!["1"]),
        ("node3", "sleep", vec!["1"]),
    ];

    let pids = service.spawn_nodes(nodes)?;

    assert_eq!(pids.len(), 3);
    assert!(pids.contains_key("node1"));
    assert!(pids.contains_key("node2"));
    assert!(pids.contains_key("node3"));
    assert_eq!(service.count(), 3);

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_nodes_with_failures() -> Result<()> {
    let mut service = ProcessService::new();

    let nodes = vec![
        ("node1", "sleep", vec!["1"]),
        ("node2", "nonexistent_binary", vec![]),
        ("node3", "sleep", vec!["1"]),
    ];

    let pids = service.spawn_nodes(nodes)?;

    assert_eq!(pids.len(), 2);
    assert!(pids.contains_key("node1"));
    assert!(pids.contains_key("node3"));
    assert!(!pids.contains_key("node2"));

    service.cleanup();
    Ok(())
}

#[test]
fn test_get_status() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("test1", "sleep", &["2"])?;
    service.spawn_node("test2", "sleep", &["2"])?;

    let status = service.get_status();
    assert_eq!(status.len(), 2);
    assert!(status.contains_key("test1"));
    assert!(status.contains_key("test2"));

    service.cleanup();
    Ok(())
}

#[test]
fn test_stop_nonexistent_process() {
    let mut service = ProcessService::new();

    let result = service.stop("nonexistent");
    assert!(result.is_err());
}

#[test]
fn test_spawn_invalid_binary() {
    let mut service = ProcessService::new();

    let result = service.spawn_node("test", "nonexistent_binary_12345", &[]);
    assert!(result.is_err());
}

#[test]
fn test_tracker_access() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("test", "sleep", &["1"])?;

    let tracker = service.tracker();
    assert!(!tracker.is_empty());

    service.cleanup();
    Ok(())
}

#[test]
fn test_restart_process() -> Result<()> {
    let mut service = ProcessService::new();

    let pid1 = service.spawn_node("test", "sleep", &["5"])?;

    let pid2 = service.restart("test", "sleep", &["5"])?;

    assert_ne!(pid1, pid2);

    service.cleanup();
    Ok(())
}

#[test]
fn test_restart_all() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("node1", "sleep", &["5"])?;
    service.spawn_node("node2", "sleep", &["5"])?;

    let nodes = vec![("node1", "sleep", vec!["5"]), ("node2", "sleep", vec!["5"])];

    let pids = service.restart_all(nodes)?;

    assert_eq!(pids.len(), 2);
    assert!(pids.contains_key("node1"));
    assert!(pids.contains_key("node2"));

    service.cleanup();
    Ok(())
}

#[test]
fn test_count_accuracy() -> Result<()> {
    let mut service = ProcessService::new();

    assert_eq!(service.count(), 0);

    service.spawn_node("test1", "sleep", &["1"])?;
    assert_eq!(service.count(), 1);

    service.spawn_node("test2", "sleep", &["1"])?;
    assert_eq!(service.count(), 2);

    service.stop("test1")?;

    service.cleanup();
    Ok(())
}

#[test]
fn test_is_empty_states() -> Result<()> {
    let mut service = ProcessService::new();

    assert!(service.is_empty());

    service.spawn_node("test", "sleep", &["1"])?;
    assert!(!service.is_empty());

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_same_name_twice() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("duplicate", "sleep", &["1"])?;
    service.spawn_node("duplicate", "sleep", &["1"])?;

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_with_args() -> Result<()> {
    let mut service = ProcessService::new();

    let pid = service.spawn_node("test_args", "echo", &["hello", "world"])?;
    assert!(pid > 0);

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_with_empty_args() -> Result<()> {
    let mut service = ProcessService::new();

    let pid = service.spawn_node("test_no_args", "sleep", &["1"])?;
    assert!(pid > 0);

    service.cleanup();
    Ok(())
}

#[test]
fn test_is_running_after_process_exits() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("quick_exit", "true", &[])?;

    std::thread::sleep(std::time::Duration::from_millis(100));

    let running = service.is_running("quick_exit");
    assert!(!running);

    service.cleanup();
    Ok(())
}

#[test]
fn test_spawn_nodes_empty_list() -> Result<()> {
    let mut service = ProcessService::new();

    let nodes = vec![];
    let pids = service.spawn_nodes(nodes)?;

    assert_eq!(pids.len(), 0);
    assert_eq!(service.count(), 0);

    Ok(())
}

#[test]
fn test_multiple_cleanup_calls() -> Result<()> {
    let mut service = ProcessService::new();

    service.spawn_node("test", "sleep", &["1"])?;

    service.cleanup();
    service.cleanup();

    Ok(())
}