mecha10-core 0.6.2

Mecha10 core runtime and foundational types
Documentation
// Tests for mecha10_core::node

use mecha10_core::error::Mecha10Error;
use mecha10_core::node::*;
use mecha10_core::prelude::now_micros;
use mecha10_core::types::{HealthStatus, NodeState};
use mecha10_core::Context;

use async_trait::async_trait;
use serde::Deserialize;

#[derive(Debug)]
struct TestNode {
    run_count: usize,
}

#[derive(Debug, Deserialize)]
struct TestConfig {
    value: i32,
}

#[async_trait]
impl NodeImpl for TestNode {
    type Config = TestConfig;

    async fn init(config: Self::Config) -> Result<Self, Mecha10Error> {
        assert_eq!(config.value, 42);
        Ok(Self { run_count: 0 })
    }

    async fn run(&mut self, _ctx: &Context) -> Result<(), Mecha10Error> {
        self.run_count += 1;
        Ok(())
    }

    async fn shutdown(&mut self) -> Result<(), Mecha10Error> {
        assert_eq!(self.run_count, 1);
        Ok(())
    }

    async fn health_check(&self) -> HealthStatus {
        HealthStatus {
            healthy: true,
            last_check: now_micros(),
            failure_count: 0,
            message: Some(format!("Test node is healthy (run_count: {})", self.run_count)),
        }
    }
}

#[tokio::test]
async fn test_health_check() {
    let config = TestConfig { value: 42 };
    let node: Node<TestNode> = Node::from_config(config).await.unwrap();

    let health = node.health_check().await;
    assert!(health.healthy);
    assert!(health.message.is_some());
    assert!(health.message.unwrap().contains("healthy"));
}

#[test]
fn test_node_state_checks() {
    assert!(matches!(NodeState::Running, NodeState::Running));
    assert!(matches!(NodeState::Starting, NodeState::Starting));
    assert!(matches!(NodeState::Crashed, NodeState::Crashed));
    assert!(matches!(NodeState::Stopped, NodeState::Stopped));
}