terraphim_agent 1.16.30

Terraphim AI Agent CLI - Command-line interface with interactive REPL and ASCII graph visualization
Documentation
use terraphim_agent::client::*;

/// Test VM command parsing with feature gates
#[cfg(feature = "repl")]
#[test]
fn test_vm_command_features() {
    // This test will only run when repl feature is enabled
    // The test passes if the code compiles with repl feature
}

/// Test VM API type compatibility
#[test]
fn test_vm_api_type_compatibility() {
    // Test that all VM types can be created and manipulated

    let vm_with_ip = VmWithIp {
        vm_id: "test-vm-001".to_string(),
        ip_address: "172.26.0.100".to_string(),
    };

    let vm_status = VmStatusResponse {
        vm_id: "test-vm-001".to_string(),
        status: "running".to_string(),
        ip_address: "172.26.0.100".to_string(),
        created_at: "2025-01-18T10:00:00Z".to_string(),
        updated_at: Some("2025-01-18T10:05:00Z".to_string()),
    };

    let vm_metrics = VmMetricsResponse {
        vm_id: "test-vm-001".to_string(),
        status: "running".to_string(),
        cpu_usage_percent: 50.0,
        memory_usage_mb: 512,
        disk_usage_percent: 25.0,
        network_io_mbps: 10.5,
        uptime_seconds: 1800,
        process_count: 8,
        updated_at: Some("2025-01-18T10:05:00Z".to_string()),
    };

    // Verify data integrity
    assert_eq!(vm_with_ip.vm_id, vm_status.vm_id);
    assert_eq!(vm_with_ip.vm_id, vm_metrics.vm_id);
    assert_eq!(vm_with_ip.ip_address, vm_status.ip_address);
    assert_eq!(vm_status.status, vm_metrics.status);
}

/// Test VM execution flow simulation
#[test]
fn test_vm_execution_flow_simulation() {
    // Simulate a complete VM execution workflow

    // 1. Create execution request
    let request = VmExecuteRequest {
        code: "console.log('Hello, VM!')".to_string(),
        language: "javascript".to_string(),
        agent_id: "test-agent".to_string(),
        vm_id: Some("test-vm-002".to_string()),
        timeout_ms: Some(15000),
    };

    // 2. Simulate successful execution response
    let response = VmExecuteResponse {
        execution_id: "exec-test-001".to_string(),
        vm_id: "test-vm-002".to_string(),
        exit_code: 0,
        stdout: "Hello, VM!\n".to_string(),
        stderr: "".to_string(),
        duration_ms: 1200,
        started_at: "2025-01-18T11:00:00Z".to_string(),
        completed_at: "2025-01-18T11:00:01.2Z".to_string(),
        error: None,
    };

    // Verify execution flow
    assert_eq!(request.vm_id, Some("test-vm-002".to_string()));
    assert_eq!(response.vm_id, "test-vm-002".to_string());
    assert_eq!(request.language, "javascript");
    assert_eq!(response.exit_code, 0);
    assert!(response.stdout.contains("Hello, VM!"));
    assert!(response.stderr.is_empty());
    assert!(response.error.is_none());
}

/// Test VM agent execution simulation
#[test]
fn test_vm_agent_execution_simulation() {
    // Simulate agent task execution in VM

    let agent_request = VmAgentRequest {
        agent_id: "dev-agent".to_string(),
        task: "run integration tests".to_string(),
        vm_id: Some("test-vm-003".to_string()),
        timeout_ms: Some(300000), // 5 minutes for tests
    };

    let agent_response = VmAgentResponse {
        task_id: "agent-task-001".to_string(),
        agent_id: "dev-agent".to_string(),
        vm_id: Some("test-vm-003".to_string()),
        status: "completed".to_string(),
        result: "✅ All 25 integration tests passed\n⏱️ Duration: 2m 45s".to_string(),
        duration_ms: 165000,
        started_at: "2025-01-18T12:00:00Z".to_string(),
        completed_at: "2025-01-18T12:02:45Z".to_string(),
        snapshot_id: Some("snap-integration-001".to_string()),
        error: None,
    };

    // Verify agent execution
    assert_eq!(agent_request.agent_id, "dev-agent");
    assert_eq!(agent_response.agent_id, "dev-agent");
    assert_eq!(agent_response.status, "completed");
    assert!(agent_response.result.contains(""));
    assert!(agent_response.snapshot_id.is_some());
    assert!(agent_response.error.is_none());
}

/// Test VM pool management simulation
#[test]
fn test_vm_pool_management_simulation() {
    // Simulate VM pool operations

    // Initial pool state
    let initial_stats = VmPoolStatsResponse {
        total_ips: 253,
        allocated_ips: 5,
        available_ips: 248,
        utilization_percent: 2,
    };

    // Allocate new VM
    let allocation_request = VmAllocateRequest {
        vm_id: "test-vm-004".to_string(),
    };

    let allocation_response = VmAllocateResponse {
        vm_id: "test-vm-004".to_string(),
        ip_address: "172.26.0.105".to_string(),
    };

    // Updated pool state after allocation
    let updated_stats = VmPoolStatsResponse {
        total_ips: 253,
        allocated_ips: 6,
        available_ips: 247,
        utilization_percent: 2,
    };

    // Verify pool management flow
    assert_eq!(allocation_request.vm_id, allocation_response.vm_id);
    assert!(!allocation_response.ip_address.is_empty());
    assert_eq!(updated_stats.allocated_ips, initial_stats.allocated_ips + 1);
    assert_eq!(updated_stats.available_ips, initial_stats.available_ips - 1);
}

/// Test VM monitoring data simulation
#[test]
fn test_vm_monitoring_data_simulation() {
    // Simulate various VM states and metrics

    let scenarios = [
        // Healthy VM
        VmMetricsResponse {
            vm_id: "vm-healthy-001".to_string(),
            status: "running".to_string(),
            cpu_usage_percent: 25.5,
            memory_usage_mb: 512,
            disk_usage_percent: 15.2,
            network_io_mbps: 5.1,
            uptime_seconds: 3600,
            process_count: 12,
            updated_at: Some("2025-01-18T13:00:00Z".to_string()),
        },
        // Busy VM
        VmMetricsResponse {
            vm_id: "vm-busy-001".to_string(),
            status: "running".to_string(),
            cpu_usage_percent: 85.2,
            memory_usage_mb: 1536,
            disk_usage_percent: 45.8,
            network_io_mbps: 25.7,
            uptime_seconds: 7200,
            process_count: 25,
            updated_at: Some("2025-01-18T13:00:00Z".to_string()),
        },
        // Problematic VM
        VmMetricsResponse {
            vm_id: "vm-problem-001".to_string(),
            status: "degraded".to_string(),
            cpu_usage_percent: 95.8,
            memory_usage_mb: 2048,
            disk_usage_percent: 88.9,
            network_io_mbps: 0.1,
            uptime_seconds: 900,
            process_count: 150,
            updated_at: Some("2025-01-18T13:00:00Z".to_string()),
        },
    ];

    // Verify monitoring scenarios
    for (i, metrics) in scenarios.iter().enumerate() {
        assert!(!metrics.vm_id.is_empty());
        assert!(metrics.cpu_usage_percent >= 0.0 && metrics.cpu_usage_percent <= 100.0);
        assert!(metrics.memory_usage_mb > 0);
        assert!(metrics.disk_usage_percent >= 0.0 && metrics.disk_usage_percent <= 100.0);
        assert!(metrics.network_io_mbps >= 0.0);
        assert!(metrics.uptime_seconds > 0);
        assert!(metrics.process_count > 0);

        println!(
            "Scenario {}: VM {} - {}% CPU, {}MB RAM",
            i + 1,
            metrics.vm_id,
            metrics.cpu_usage_percent,
            metrics.memory_usage_mb
        );
    }
}

/// Test VM task management simulation
#[test]
fn test_vm_task_management_simulation() {
    // Simulate multiple tasks running on a VM

    let tasks_response = VmTasksResponse {
        tasks: vec![
            VmTask {
                id: "task-001".to_string(),
                vm_id: "test-vm-tasks".to_string(),
                status: "completed".to_string(),
                created_at: "2025-01-18T10:00:00Z".to_string(),
                updated_at: Some("2025-01-18T10:01:30Z".to_string()),
            },
            VmTask {
                id: "task-002".to_string(),
                vm_id: "test-vm-tasks".to_string(),
                status: "running".to_string(),
                created_at: "2025-01-18T10:02:00Z".to_string(),
                updated_at: None,
            },
            VmTask {
                id: "task-003".to_string(),
                vm_id: "test-vm-tasks".to_string(),
                status: "pending".to_string(),
                created_at: "2025-01-18T10:03:00Z".to_string(),
                updated_at: None,
            },
            VmTask {
                id: "task-004".to_string(),
                vm_id: "test-vm-tasks".to_string(),
                status: "failed".to_string(),
                created_at: "2025-01-18T10:04:00Z".to_string(),
                updated_at: Some("2025-01-18T10:04:15Z".to_string()),
            },
        ],
        vm_id: "test-vm-tasks".to_string(),
        total: 4,
    };

    // Verify task management
    assert_eq!(tasks_response.vm_id, "test-vm-tasks");
    assert_eq!(tasks_response.tasks.len(), 4);
    assert_eq!(tasks_response.total, 4);

    let completed_tasks = tasks_response
        .tasks
        .iter()
        .filter(|t| t.status == "completed")
        .count();
    let running_tasks = tasks_response
        .tasks
        .iter()
        .filter(|t| t.status == "running")
        .count();
    let failed_tasks = tasks_response
        .tasks
        .iter()
        .filter(|t| t.status == "failed")
        .count();

    assert_eq!(completed_tasks, 1);
    assert_eq!(running_tasks, 1);
    assert_eq!(failed_tasks, 1);
}

/// Test JSON serialization roundtrip for all VM types
#[test]
fn test_vm_types_json_roundtrip() {
    // Test all VM API types for JSON serialization/deserialization

    let test_data = vec![
        (
            "vm_with_ip",
            serde_json::to_value(VmWithIp {
                vm_id: "test-vm".to_string(),
                ip_address: "172.26.0.200".to_string(),
            })
            .unwrap(),
        ),
        (
            "vm_pool_stats",
            serde_json::to_value(VmPoolStatsResponse {
                total_ips: 100,
                allocated_ips: 25,
                available_ips: 75,
                utilization_percent: 25,
            })
            .unwrap(),
        ),
        (
            "vm_status",
            serde_json::to_value(VmStatusResponse {
                vm_id: "test-vm".to_string(),
                status: "running".to_string(),
                ip_address: "172.26.0.200".to_string(),
                created_at: "2025-01-18T14:00:00Z".to_string(),
                updated_at: Some("2025-01-18T14:05:00Z".to_string()),
            })
            .unwrap(),
        ),
    ];

    for (name, value) in test_data {
        // Verify it's valid JSON
        let json_str = serde_json::to_string(&value).unwrap();
        let parsed_value: serde_json::Value = serde_json::from_str(&json_str).unwrap();

        // Verify roundtrip integrity
        assert_eq!(value, parsed_value, "JSON roundtrip failed for {}", name);

        println!("{} - JSON serialization successful", name);
    }
}

/// Test error handling scenarios
#[test]
fn test_vm_error_scenarios() {
    // Test various error scenarios in VM operations

    // Execution with error
    let error_response = VmExecuteResponse {
        execution_id: "exec-error-001".to_string(),
        vm_id: "test-vm-error".to_string(),
        exit_code: 1,
        stdout: "".to_string(),
        stderr: "Error: Command not found\n".to_string(),
        duration_ms: 500,
        started_at: "2025-01-18T15:00:00Z".to_string(),
        completed_at: "2025-01-18T15:00:00.5Z".to_string(),
        error: Some("Command execution failed".to_string()),
    };

    // Agent execution with timeout
    let timeout_response = VmAgentResponse {
        task_id: "agent-timeout-001".to_string(),
        agent_id: "test-agent".to_string(),
        vm_id: Some("test-vm-timeout".to_string()),
        status: "failed".to_string(),
        result: "".to_string(),
        duration_ms: 60000, // Full timeout duration
        started_at: "2025-01-18T16:00:00Z".to_string(),
        completed_at: "2025-01-18T17:00:00Z".to_string(),
        snapshot_id: None,
        error: Some("Task execution timed out".to_string()),
    };

    // Verify error handling
    assert_eq!(error_response.exit_code, 1);
    assert!(!error_response.stderr.is_empty());
    assert!(error_response.error.is_some());

    assert_eq!(timeout_response.status, "failed");
    assert_eq!(timeout_response.duration_ms, 60000);
    assert!(timeout_response.error.is_some());
    assert!(timeout_response.snapshot_id.is_none());
}