use mecha10_core::error::{Mecha10Error, Result};
use std::path::PathBuf;
#[test]
fn test_node_init_error() {
let err = Mecha10Error::NodeInit("Failed to allocate resources".to_string());
let msg = err.to_string();
assert!(msg.contains("Node initialization failed"));
assert!(msg.contains("Failed to allocate resources"));
}
#[test]
fn test_node_failed_error() {
let err = Mecha10Error::NodeFailed {
node_name: "camera_node".to_string(),
message: "Camera disconnected".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Node 'camera_node' failed"));
assert!(msg.contains("Camera disconnected"));
}
#[test]
fn test_node_not_found_error() {
let err = Mecha10Error::NodeNotFound("missing_node".to_string());
let msg = err.to_string();
assert!(msg.contains("Node 'missing_node' not found"));
}
#[test]
fn test_config_validation_error_display() {
let err = Mecha10Error::ConfigValidation {
field: "max_speed".to_string(),
message: "Value out of range".to_string(),
expected: "0.0..=10.0".to_string(),
got: "15.0".to_string(),
suggestion: "Set max_speed between 0.0 and 10.0".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Configuration error in field 'max_speed'"));
assert!(msg.contains("Value out of range"));
assert!(msg.contains("Expected: 0.0..=10.0"));
assert!(msg.contains("Got: 15.0"));
assert!(msg.contains("Suggestion: Set max_speed between 0.0 and 10.0"));
}
#[test]
fn test_config_validation_helper() {
let err = Mecha10Error::config_validation(
"max_speed",
"Value out of range",
"0.0..=10.0",
"15.0",
"Set max_speed between 0.0 and 10.0",
);
let msg = err.to_string();
assert!(msg.contains("max_speed"));
assert!(msg.contains("Expected: 0.0..=10.0"));
assert!(msg.contains("Got: 15.0"));
assert!(msg.contains("Suggestion:"));
}
#[test]
fn test_config_not_found_error() {
let err = Mecha10Error::ConfigNotFound {
path: PathBuf::from("/etc/mecha10/config.yaml"),
env_var: "MECHA10_CONFIG".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Configuration file not found"));
assert!(msg.contains("/etc/mecha10/config.yaml"));
assert!(msg.contains("MECHA10_CONFIG"));
assert!(msg.contains("Suggestion:"));
}
#[test]
fn test_config_not_found_helper() {
let err = Mecha10Error::config_not_found("/config/app.yaml", "APP_CONFIG");
let msg = err.to_string();
assert!(msg.contains("/config/app.yaml"));
assert!(msg.contains("APP_CONFIG"));
}
#[test]
fn test_config_invalid_error() {
let err = Mecha10Error::ConfigInvalid(
"Missing required field 'name'".to_string(),
"https://schema.mecha.industries/v1".to_string(),
);
let msg = err.to_string();
assert!(msg.contains("Invalid configuration format"));
assert!(msg.contains("Missing required field 'name'"));
assert!(msg.contains("Suggestion: Validate against schema at https://schema.mecha.industries/v1"));
}
#[test]
fn test_configuration_error() {
let err = Mecha10Error::Configuration("Invalid settings".to_string());
let msg = err.to_string();
assert!(msg.contains("Configuration error: Invalid settings"));
}
#[test]
fn test_configuration_helper() {
let err = Mecha10Error::configuration("Missing required parameter");
let msg = err.to_string();
assert!(msg.contains("Missing required parameter"));
}
#[test]
fn test_messaging_error_display() {
let err = Mecha10Error::MessagingError {
message: "Failed to connect to broker".to_string(),
suggestion: "Check Redis is running".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Failed to connect to broker"));
assert!(msg.contains("Suggestion: Check Redis is running"));
}
#[test]
fn test_messaging_error_helper() {
let err = Mecha10Error::messaging_error("Connection timeout", "Verify network connectivity");
let msg = err.to_string();
assert!(msg.contains("Connection timeout"));
assert!(msg.contains("Verify network connectivity"));
}
#[test]
fn test_messaging_connection_failed_localhost() {
let err = Mecha10Error::MessagingConnectionFailed {
url: "localhost:6379".to_string(),
suggestion: "Start Redis with `redis-server`".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Failed to connect to message broker"));
assert!(msg.contains("localhost:6379"));
assert!(msg.contains("Suggestion:"));
}
#[test]
fn test_connection_failed_helper_localhost() {
let err = Mecha10Error::connection_failed("localhost:6379");
let msg = err.to_string();
assert!(msg.contains("localhost:6379"));
assert!(msg.contains("redis-server"));
assert!(msg.contains("Suggestion:"));
}
#[test]
fn test_connection_failed_helper_127_0_0_1() {
let err = Mecha10Error::connection_failed("127.0.0.1:6379");
let msg = err.to_string();
assert!(msg.contains("127.0.0.1:6379"));
assert!(msg.contains("redis-server"));
assert!(msg.contains("REDIS_URL"));
}
#[test]
fn test_connection_failed_helper_remote() {
let err = Mecha10Error::connection_failed("redis.example.com:6379");
let msg = err.to_string();
assert!(msg.contains("redis.example.com:6379"));
assert!(msg.contains("Check network connection"));
assert!(msg.contains("Redis is running"));
}
#[test]
fn test_publish_failed_error() {
let err = Mecha10Error::PublishFailed {
topic: "/sensors/camera".to_string(),
reason: "Connection lost".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Failed to publish message to topic '/sensors/camera'"));
assert!(msg.contains("Connection lost"));
}
#[test]
fn test_subscribe_failed_error() {
let err = Mecha10Error::SubscribeFailed {
topic: "/control/motor".to_string(),
reason: "Invalid topic format".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Failed to subscribe to topic '/control/motor'"));
assert!(msg.contains("Invalid topic format"));
}
#[test]
fn test_deserialization_failed_error() {
let err = Mecha10Error::DeserializationFailed {
topic: "/sensors/lidar".to_string(),
expected_type: "LidarScan".to_string(),
error: "Missing field 'points'".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Message deserialization failed for topic '/sensors/lidar'"));
assert!(msg.contains("Expected type: LidarScan"));
assert!(msg.contains("Error: Missing field 'points'"));
}
#[test]
fn test_serialization_failed_error() {
let err = Mecha10Error::SerializationFailed("Invalid UTF-8 data".to_string());
let msg = err.to_string();
assert!(msg.contains("Message serialization failed: Invalid UTF-8 data"));
}
#[test]
fn test_serialization_error_display() {
let err = Mecha10Error::SerializationError {
message: "Cannot serialize NaN value".to_string(),
suggestion: "Use finite numbers only".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Cannot serialize NaN value"));
assert!(msg.contains("Suggestion: Use finite numbers only"));
}
#[test]
fn test_circuit_breaker_open_error() {
let err = Mecha10Error::CircuitBreakerOpen {
service: "camera_service".to_string(),
message: "Too many failures".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Circuit breaker open for service 'camera_service'"));
assert!(msg.contains("Too many failures"));
}
#[test]
fn test_model_load_failed_error() {
let err = Mecha10Error::ModelLoadFailed {
uri: "mlflow://model/v1".to_string(),
reason: "Connection refused".to_string(),
suggestion: "Check MLflow server".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Failed to load model from 'mlflow://model/v1'"));
assert!(msg.contains("Connection refused"));
assert!(msg.contains("Suggestion: Check MLflow server"));
}
#[test]
fn test_model_load_failed_helper_mlflow() {
let err = Mecha10Error::model_load_failed("mlflow://yolov8-nano/production", "Connection refused");
let msg = err.to_string();
assert!(msg.contains("mlflow://yolov8-nano/production"));
assert!(msg.contains("Connection refused"));
assert!(msg.contains("MLflow"));
assert!(msg.contains("Suggestion:"));
}
#[test]
fn test_model_load_failed_helper_http() {
let err = Mecha10Error::model_load_failed("http://example.com/model.onnx", "404 Not Found");
let msg = err.to_string();
assert!(msg.contains("http://example.com/model.onnx"));
assert!(msg.contains("404 Not Found"));
assert!(msg.contains("Check network connection"));
}
#[test]
fn test_model_load_failed_helper_https() {
let err = Mecha10Error::model_load_failed("https://example.com/model.onnx", "SSL error");
let msg = err.to_string();
assert!(msg.contains("https://example.com/model.onnx"));
assert!(msg.contains("SSL error"));
assert!(msg.contains("Check network connection"));
}
#[test]
fn test_model_load_failed_helper_file() {
let err = Mecha10Error::model_load_failed("/path/to/model.onnx", "File not found");
let msg = err.to_string();
assert!(msg.contains("/path/to/model.onnx"));
assert!(msg.contains("File not found"));
assert!(msg.contains("Check file exists"));
}
#[test]
fn test_inference_failed_error() {
let err = Mecha10Error::InferenceFailed("Out of memory".to_string());
let msg = err.to_string();
assert!(msg.contains("Model inference failed: Out of memory"));
}
#[test]
fn test_model_not_found_error() {
let err = Mecha10Error::ModelNotFound {
model_name: "yolov8-nano".to_string(),
version: "production".to_string(),
mlflow_url: "http://localhost:5000".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Model not found in MLflow registry: yolov8-nano/production"));
assert!(msg.contains("Suggestion: Check MLflow UI at http://localhost:5000"));
}
#[test]
fn test_model_checksum_mismatch_error() {
let err = Mecha10Error::ModelChecksumMismatch {
expected: "abc123".to_string(),
got: "def456".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Model checksum mismatch"));
assert!(msg.contains("Expected: abc123"));
assert!(msg.contains("Got: def456"));
assert!(msg.contains("Suggestion: Re-download the model"));
}
#[test]
fn test_build_failed_error() {
let err = Mecha10Error::BuildFailed {
node_name: "vision_node".to_string(),
stderr: "error: cannot find type `Image` in this scope".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Build failed for node 'vision_node'"));
assert!(msg.contains("cannot find type `Image`"));
assert!(msg.contains("Suggestion: Check the error messages above"));
}
#[test]
fn test_hot_reload_failed_error() {
let err = Mecha10Error::HotReloadFailed("Compilation error".to_string());
let msg = err.to_string();
assert!(msg.contains("Hot-reload failed: Compilation error"));
}
#[test]
fn test_runtime_error() {
let err = Mecha10Error::Runtime("Unexpected state".to_string());
let msg = err.to_string();
assert!(msg.contains("Runtime error: Unexpected state"));
}
#[test]
fn test_timeout_error() {
let err = Mecha10Error::Timeout {
timeout_ms: 5000,
operation: "model loading".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Timeout after 5000ms waiting for: model loading"));
}
#[test]
fn test_shutdown_error() {
let err = Mecha10Error::Shutdown("Failed to stop service".to_string());
let msg = err.to_string();
assert!(msg.contains("Shutdown error: Failed to stop service"));
}
#[test]
fn test_file_not_found_error() {
let err = Mecha10Error::FileNotFound {
path: PathBuf::from("/data/config.yaml"),
suggestion: "Create the file or update the path".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("File not found: /data/config.yaml"));
assert!(msg.contains("Suggestion: Create the file or update the path"));
}
#[test]
fn test_file_not_found_helper() {
let err = Mecha10Error::file_not_found("/missing/file.txt", "Check the path");
let msg = err.to_string();
assert!(msg.contains("/missing/file.txt"));
assert!(msg.contains("Check the path"));
}
#[test]
fn test_io_error_conversion() {
let io_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "Access denied");
let err: Mecha10Error = io_err.into();
let msg = err.to_string();
assert!(msg.contains("IO error"));
assert!(msg.contains("Access denied"));
}
#[test]
fn test_io_error_display() {
let err = Mecha10Error::IoError {
message: "Failed to write to disk".to_string(),
suggestion: "Check disk space".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Failed to write to disk"));
assert!(msg.contains("Suggestion: Check disk space"));
}
#[test]
fn test_json_error_conversion() {
let json_str = "{invalid json}";
let json_err = serde_json::from_str::<serde_json::Value>(json_str).unwrap_err();
let err: Mecha10Error = json_err.into();
let msg = err.to_string();
assert!(msg.contains("JSON error"));
}
#[test]
fn test_yaml_error() {
let err = Mecha10Error::Yaml("Invalid YAML syntax at line 5".to_string());
let msg = err.to_string();
assert!(msg.contains("YAML error: Invalid YAML syntax at line 5"));
}
#[test]
fn test_redis_error() {
let err = Mecha10Error::Redis("Connection pool exhausted".to_string());
let msg = err.to_string();
assert!(msg.contains("Redis error: Connection pool exhausted"));
}
#[test]
fn test_database_error() {
let err = Mecha10Error::Database("Constraint violation".to_string());
let msg = err.to_string();
assert!(msg.contains("Database error: Constraint violation"));
}
#[test]
fn test_http_error() {
let err = Mecha10Error::Http("404 Not Found".to_string());
let msg = err.to_string();
assert!(msg.contains("HTTP error: 404 Not Found"));
}
#[test]
fn test_other_error() {
let err = Mecha10Error::Other("Custom error message".to_string());
let msg = err.to_string();
assert_eq!(msg, "Custom error message");
}
#[test]
fn test_anyhow_error_conversion() {
let anyhow_err = anyhow::anyhow!("Something went wrong");
let err: Mecha10Error = anyhow_err.into();
let msg = err.to_string();
assert!(msg.contains("Something went wrong"));
}
#[test]
fn test_result_type_ok() {
let result: Result<i32> = Ok(42);
assert!(result.is_ok());
assert_eq!(result.ok(), Some(42));
}
#[test]
fn test_result_type_err() {
let result: Result<i32> = Err(Mecha10Error::Runtime("Error".to_string()));
assert!(result.is_err());
}
#[test]
fn test_debug_formatting() {
let err = Mecha10Error::NodeInit("Test error".to_string());
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("NodeInit"));
assert!(debug_str.contains("Test error"));
}
#[test]
fn test_debug_formatting_complex() {
let err = Mecha10Error::ConfigValidation {
field: "test".to_string(),
message: "invalid".to_string(),
expected: "valid".to_string(),
got: "invalid".to_string(),
suggestion: "fix it".to_string(),
};
let debug_str = format!("{:?}", err);
assert!(debug_str.contains("ConfigValidation"));
}
#[test]
fn test_error_with_multiple_context_fields() {
let err = Mecha10Error::DeserializationFailed {
topic: "/sensors/camera/image".to_string(),
expected_type: "Image".to_string(),
error: "Missing field 'width'".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("/sensors/camera/image"));
assert!(msg.contains("Image"));
assert!(msg.contains("Missing field 'width'"));
}
#[test]
fn test_pathbuf_in_error() {
let path = PathBuf::from("/home/user/config.yaml");
let err = Mecha10Error::ConfigNotFound {
path: path.clone(),
env_var: "CONFIG_PATH".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("/home/user/config.yaml"));
}
#[test]
fn test_multiline_error_formatting() {
let err = Mecha10Error::ConfigValidation {
field: "timeout".to_string(),
message: "Invalid value".to_string(),
expected: "positive number".to_string(),
got: "-100".to_string(),
suggestion: "Use a positive timeout value".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("Expected:"));
assert!(msg.contains("Got:"));
assert!(msg.contains("Suggestion:"));
}
#[test]
fn test_suggestion_text_in_errors() {
let errors = vec![
Mecha10Error::connection_failed("localhost:6379"),
Mecha10Error::model_load_failed("mlflow://model", "error"),
Mecha10Error::file_not_found("/file", "create it"),
];
for err in errors {
let msg = err.to_string();
assert!(msg.contains("Suggestion:") || msg.contains("→"));
}
}
#[test]
fn test_error_with_special_characters() {
let err = Mecha10Error::NodeFailed {
node_name: "node-with-dashes_and_underscores".to_string(),
message: "Error with symbols: @#$%^&*()".to_string(),
};
let msg = err.to_string();
assert!(msg.contains("node-with-dashes_and_underscores"));
assert!(msg.contains("@#$%^&*()"));
}
#[test]
fn test_error_with_empty_strings() {
let err = Mecha10Error::NodeInit("".to_string());
let msg = err.to_string();
assert!(msg.contains("Node initialization failed"));
}
#[test]
fn test_error_with_very_long_message() {
let long_message = "x".repeat(1000);
let err = Mecha10Error::Runtime(long_message.clone());
let msg = err.to_string();
assert!(msg.contains(&long_message));
}
#[test]
fn test_connection_failed_with_port() {
let err = Mecha10Error::connection_failed("redis://localhost:6379/0");
let msg = err.to_string();
assert!(msg.contains("localhost"));
}
#[test]
fn test_config_validation_with_unicode() {
let err = Mecha10Error::config_validation("名前", "無効な値", "文字列", "123", "文字列を入力してください");
let msg = err.to_string();
assert!(msg.contains("名前"));
assert!(msg.contains("無効な値"));
}
#[test]
fn test_result_type_inference() {
fn returns_result() -> Result<String> {
Ok("success".to_string())
}
let result = returns_result();
assert!(result.is_ok());
}
#[test]
fn test_error_is_send_and_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<Mecha10Error>();
}
#[test]
fn test_error_is_static() {
fn assert_static<T: 'static>() {}
assert_static::<Mecha10Error>();
}
#[test]
fn test_io_to_mecha10_conversion() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let mecha10_err: Mecha10Error = io_err.into();
match mecha10_err {
Mecha10Error::Io(_) => {}
_ => panic!("Expected Io variant"),
}
}
#[test]
fn test_json_to_mecha10_conversion() {
let json_err = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
let mecha10_err: Mecha10Error = json_err.into();
match mecha10_err {
Mecha10Error::Json(_) => {}
_ => panic!("Expected Json variant"),
}
}
#[test]
fn test_anyhow_to_mecha10_conversion() {
let anyhow_err = anyhow::anyhow!("test error");
let mecha10_err: Mecha10Error = anyhow_err.into();
match mecha10_err {
Mecha10Error::Other(_) => {}
_ => panic!("Expected Other variant"),
}
}
#[test]
fn test_pattern_matching_on_errors() {
let err = Mecha10Error::NodeInit("test".to_string());
match err {
Mecha10Error::NodeInit(msg) => assert_eq!(msg, "test"),
_ => panic!("Expected NodeInit variant"),
}
}
#[test]
fn test_pattern_matching_on_complex_errors() {
let err = Mecha10Error::ConfigValidation {
field: "test".to_string(),
message: "msg".to_string(),
expected: "exp".to_string(),
got: "got".to_string(),
suggestion: "sug".to_string(),
};
match err {
Mecha10Error::ConfigValidation { field, .. } => {
assert_eq!(field, "test");
}
_ => panic!("Expected ConfigValidation variant"),
}
}
#[test]
fn test_error_propagation() {
fn inner_fn() -> Result<()> {
Err(Mecha10Error::Runtime("inner error".to_string()))
}
fn outer_fn() -> Result<()> {
inner_fn()?;
Ok(())
}
let result = outer_fn();
assert!(result.is_err());
}
#[test]
fn test_error_with_question_mark_operator() {
fn read_config() -> Result<String> {
let _io_result = std::fs::read_to_string("/nonexistent")?;
Ok("success".to_string())
}
let result = read_config();
assert!(result.is_err());
}