use crate::core::RuntimeContext;
use crate::engine::{DagExecutor, MissionStep, StepType, StepStatus};
use serde_json::json;
use std::collections::HashMap;
use tokio;
#[tokio::test]
async fn test_generate_embedding_step_type() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let embedding_step = MissionStep {
id: "test_generate_embedding".to_string(),
name: Some("Test Generate Embedding".to_string()),
step_type: StepType::GenerateEmbedding,
parameters: json!({
"text": "This is a test sentence for embedding generation.",
"model": "text-embedding-ada-002"
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
let result = executor.execute_step(&embedding_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
assert!(step_result.output.get("text").is_some());
assert!(step_result.output.get("model").is_some());
}
#[tokio::test]
async fn test_similarity_search_step_type() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let search_step = MissionStep {
id: "test_similarity_search".to_string(),
name: Some("Test Similarity Search".to_string()),
step_type: StepType::SimilaritySearch,
parameters: json!({
"query_embedding": [0.1, 0.2, 0.3, 0.4, 0.5],
"database": "default",
"top_k": 5
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
let result = executor.execute_step(&search_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
assert!(step_result.output.get("top_k").is_some());
}
#[tokio::test]
async fn test_model_inference_step_type() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let inference_step = MissionStep {
id: "test_model_inference".to_string(),
name: Some("Test Model Inference".to_string()),
step_type: StepType::ModelInference,
parameters: json!({
"prompt": "What is the capital of France?",
"model": "gpt-3.5-turbo",
"max_tokens": 100
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
let result = executor.execute_step(&inference_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
assert!(step_result.output.get("prompt").is_some());
assert!(step_result.output.get("model").is_some());
}
#[tokio::test]
async fn test_ai_ml_operations_error_handling() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let invalid_model_step = MissionStep {
id: "test_invalid_model".to_string(),
name: Some("Test Invalid Model".to_string()),
step_type: StepType::GenerateEmbedding,
parameters: json!({
"text": "Test text",
"model": "nonexistent-model-123"
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
let result = executor.execute_step(&invalid_model_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
}
#[tokio::test]
async fn test_embedding_with_various_text_types() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let test_texts = vec![
"Short text",
"This is a much longer text that contains multiple sentences and should test the embedding model's ability to handle longer input sequences properly.",
"", "Text with special characters: !@#$%^&*()",
"Non-English text: Bonjour le monde! ¿Cómo estás?",
];
for (i, text) in test_texts.iter().enumerate() {
let embedding_step = MissionStep {
id: format!("test_embedding_text_{}", i),
name: Some(format!("Test Embedding Text {}", i)),
step_type: StepType::GenerateEmbedding,
parameters: json!({
"text": text,
"model": "text-embedding-ada-002"
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
let result = executor.execute_step(&embedding_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
assert_eq!(step_result.output.get("text").unwrap().as_str().unwrap(), *text);
}
}
#[tokio::test]
async fn test_similarity_search_with_different_metrics() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let metrics = vec!["cosine", "euclidean", "dot_product"];
let test_embedding = vec![0.1, 0.2, 0.3, 0.4, 0.5];
for metric in metrics {
let search_step = MissionStep {
id: format!("test_similarity_{}", metric),
name: Some(format!("Test Similarity Search {}", metric)),
step_type: StepType::SimilaritySearch,
parameters: json!({
"query_embedding": test_embedding,
"database": "default",
"top_k": 3,
"metric": metric,
"threshold": 0.7
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
let result = executor.execute_step(&search_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
assert!(step_result.output.get("metric").is_some());
}
}
#[tokio::test]
async fn test_embedding_batch_performance() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let batch_texts = vec![
"First batch text for performance testing",
"Second batch text for performance testing",
"Third batch text for performance testing",
"Fourth batch text for performance testing",
"Fifth batch text for performance testing"
];
let batch_embedding_step = MissionStep {
id: "test_batch_embedding".to_string(),
name: Some("Test Batch Embedding Performance".to_string()),
step_type: StepType::GenerateEmbedding,
parameters: json!({
"texts": batch_texts,
"model": "text-embedding-ada-002",
"batch_size": 5
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: Some(30000), };
let start_time = std::time::Instant::now();
let result = executor.execute_step(&batch_embedding_step).await;
let duration = start_time.elapsed();
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(duration.as_secs() < 30);
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
}
#[tokio::test]
async fn test_model_inference_memory_management() {
let context = RuntimeContext::new();
let executor = DagExecutor::new(context);
let large_prompt = "Context: ".to_string() + &"This is a very long context that repeats many times to test memory management. ".repeat(100);
let memory_test_step = MissionStep {
id: "test_memory_inference".to_string(),
name: Some("Test Memory Management Inference".to_string()),
step_type: StepType::ModelInference,
parameters: json!({
"prompt": large_prompt,
"model": "gpt-3.5-turbo",
"max_tokens": 50,
"stream": false
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: Some(60000), };
let result = executor.execute_step(&memory_test_step).await;
assert!(result.is_ok());
let step_result = result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
assert!(step_result.output.get("max_tokens").is_some());
}
#[tokio::test]
async fn test_concurrent_ai_operations() {
let context = RuntimeContext::new();
let mut handles = vec![];
for i in 0..3 {
let executor = DagExecutor::new(RuntimeContext::new());
let handle = tokio::spawn(async move {
let embedding_step = MissionStep {
id: format!("concurrent_embedding_{}", i),
name: Some(format!("Concurrent Embedding {}", i)),
step_type: StepType::GenerateEmbedding,
parameters: json!({
"text": format!("Concurrent test text {}", i),
"model": "text-embedding-ada-002"
}).as_object().unwrap().clone(),
depends_on: vec![],
timeout: None,
};
executor.execute_step(&embedding_step).await
});
handles.push(handle);
}
let results = futures::future::join_all(handles).await;
for result in results {
assert!(result.is_ok());
let execution_result = result.unwrap();
assert!(execution_result.is_ok());
let step_result = execution_result.unwrap();
assert!(matches!(step_result.status, StepStatus::Success | StepStatus::Failed));
}
}