Skip to main content

mockforge_k8s_operator/
lib.rs

1//! MockForge Kubernetes Operator
2//!
3//! Kubernetes operator for managing chaos orchestrations as CRDs.
4
5pub mod controller;
6pub mod crd;
7pub mod metrics;
8pub mod reconciler;
9pub mod webhook;
10
11pub use controller::Controller;
12pub use crd::{ChaosOrchestration, ChaosOrchestrationSpec, ChaosOrchestrationStatus};
13pub use metrics::OperatorMetrics;
14pub use reconciler::Reconciler;
15pub use webhook::WebhookHandler;
16
17use thiserror::Error;
18
19#[derive(Error, Debug)]
20pub enum OperatorError {
21    #[error("Kubernetes error: {0}")]
22    Kube(#[from] kube::Error),
23
24    #[error("Serialization error: {0}")]
25    Serialization(#[from] serde_json::Error),
26
27    #[error("Orchestration error: {0}")]
28    Orchestration(String),
29
30    #[error("Resource not found: {0}")]
31    NotFound(String),
32
33    #[error("Validation error: {0}")]
34    Validation(String),
35
36    #[error("Metrics error: {0}")]
37    Metrics(#[from] prometheus::Error),
38}
39
40pub type Result<T> = std::result::Result<T, OperatorError>;
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn test_operator_error_orchestration() {
48        let error = OperatorError::Orchestration("test failure".to_string());
49        assert_eq!(error.to_string(), "Orchestration error: test failure");
50    }
51
52    #[test]
53    fn test_operator_error_not_found() {
54        let error = OperatorError::NotFound("resource".to_string());
55        assert_eq!(error.to_string(), "Resource not found: resource");
56    }
57
58    #[test]
59    fn test_operator_error_validation() {
60        let error = OperatorError::Validation("invalid spec".to_string());
61        assert_eq!(error.to_string(), "Validation error: invalid spec");
62    }
63
64    #[test]
65    fn test_operator_error_serialization() {
66        let json_error = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
67        let error = OperatorError::Serialization(json_error);
68        assert!(error.to_string().contains("Serialization error:"));
69    }
70
71    #[test]
72    fn test_operator_error_debug() {
73        let error = OperatorError::NotFound("test".to_string());
74        let debug = format!("{:?}", error);
75        assert!(debug.contains("NotFound"));
76    }
77
78    // Test Result type alias
79    #[test]
80    fn test_result_ok() {
81        let result: Result<i32> = Ok(42);
82        assert!(result.is_ok());
83        assert_eq!(result.unwrap(), 42);
84    }
85
86    #[test]
87    fn test_result_err() {
88        let result: Result<i32> = Err(OperatorError::NotFound("test".to_string()));
89        assert!(result.is_err());
90    }
91
92    // Test From trait implementations
93    #[test]
94    fn test_from_serde_json_error() {
95        let json_error = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
96        let op_error: OperatorError = json_error.into();
97        assert!(matches!(op_error, OperatorError::Serialization(_)));
98    }
99
100    #[test]
101    fn test_from_prometheus_error() {
102        // Create a prometheus error by trying to create an invalid metric
103        let registry = prometheus::Registry::new();
104        // Register same metric twice to force an error
105        let counter1 = prometheus::IntCounter::new("test_counter", "Test counter").unwrap();
106        let counter2 = prometheus::IntCounter::new("test_counter", "Test counter").unwrap();
107        registry.register(Box::new(counter1)).unwrap();
108        let prometheus_error = registry.register(Box::new(counter2)).unwrap_err();
109
110        let op_error: OperatorError = prometheus_error.into();
111        assert!(matches!(op_error, OperatorError::Metrics(_)));
112    }
113}