feat: vendor midstream and sublinear-time-solver libraries

Add ruvnet/midstream (AIMDS real-time inference) and
ruvnet/sublinear-time-solver (sublinear optimization algorithms)
as vendored dependencies under vendor/.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-02 23:32:45 -05:00
parent 14902e6b4e
commit e91bb8a1d5
1600 changed files with 1852646 additions and 0 deletions
+723
View File
@@ -0,0 +1,723 @@
//! Comprehensive Integration Tests for MidStream System
//!
//! Tests end-to-end workflows across all crates:
//! - temporal-compare: Sequence analysis and pattern matching
//! - nanosecond-scheduler: Real-time scheduling with nanosecond precision
//! - temporal-attractor-studio: Dynamical systems and attractor analysis
//! - temporal-neural-solver: Temporal logic verification and neural reasoning
//! - strange-loop: Meta-learning and self-reference
//! - quic-multistream: High-performance multiplexed streaming
use std::time::Duration;
// Import from published crates
use midstreamer_temporal_compare::{TemporalComparator, Sequence, ComparisonAlgorithm};
use midstreamer_scheduler::{RealtimeScheduler, SchedulerConfig, Priority, Deadline};
use midstreamer_attractor::{AttractorAnalyzer, PhasePoint, AttractorType};
use midstreamer_neural_solver::{TemporalNeuralSolver, TemporalFormula, TemporalState, VerificationStrictness};
use midstreamer_strange_loop::{StrangeLoop, MetaLevel, StrangeLoopConfig};
/// Test 1: Scheduler + Temporal Compare Integration
///
/// Scenario:
/// - Use temporal patterns to predict task priority
/// - Schedule tasks based on historical pattern similarity
/// - Verify scheduling order respects pattern-based priorities
#[test]
fn test_scheduler_temporal_integration() {
println!("\n=== Test 1: Scheduler + Temporal Compare Integration ===");
let scheduler: RealtimeScheduler<String> = RealtimeScheduler::default();
let comparator: TemporalComparator<String> = TemporalComparator::new(100, 1000);
// Historical execution patterns
let mut seq1: Sequence<String> = Sequence::new();
seq1.push("init".to_string(), 0);
seq1.push("process".to_string(), 100);
seq1.push("complete".to_string(), 200);
let mut seq2: Sequence<String> = Sequence::new();
seq2.push("init".to_string(), 0);
seq2.push("process".to_string(), 100);
seq2.push("complete".to_string(), 200);
// Compare sequences to detect patterns
let result = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::DTW).unwrap();
println!(" Pattern similarity (DTW): {:.4}", result.distance);
assert!(result.distance < 1.0, "Should detect identical patterns");
// Schedule tasks with priority based on pattern confidence
let priority = if result.distance < 0.5 {
Priority::High
} else {
Priority::Medium
};
let task_id = scheduler.schedule(
"pattern_based_task".to_string(),
Deadline::from_millis(100),
priority,
).unwrap();
println!(" ✓ Task {} scheduled with {:?} priority", task_id, priority);
assert_eq!(scheduler.queue_size(), 1);
// Verify task retrieval
let task = scheduler.next_task().unwrap();
assert_eq!(task.id, task_id);
assert_eq!(task.priority, priority);
println!(" ✓ Task retrieved successfully with correct priority");
println!("=== Test 1 PASSED ===\n");
}
/// Test 2: Scheduler + Attractor Analysis Integration
///
/// Scenario:
/// - Analyze system behavior dynamics while scheduling tasks
/// - Detect attractors in task execution patterns
/// - Adjust scheduling based on stability analysis
#[test]
fn test_scheduler_attractor_integration() {
println!("\n=== Test 2: Scheduler + Attractor Analysis Integration ===");
let scheduler: RealtimeScheduler<f64> = RealtimeScheduler::default();
let mut analyzer = AttractorAnalyzer::new(3, 1000);
// Simulate task scheduling with dynamic behavior
for i in 0..150 {
let t = i as f64 * 0.1;
// Add phase point tracking system state
let point = PhasePoint::new(
vec![
t.sin(), // CPU load
t.cos(), // Memory usage
(-t / 10.0).exp(), // Queue depth (decaying)
],
i as u64 * 100,
);
analyzer.add_point(point).unwrap();
// Schedule task with priority based on queue depth
let priority = if i < 50 {
Priority::High
} else if i < 100 {
Priority::Medium
} else {
Priority::Low
};
scheduler.schedule(
i as f64,
Deadline::from_millis((i + 10) as u64),
priority,
).unwrap();
}
// Analyze attractor to understand system stability
let attractor_info = analyzer.analyze().unwrap();
println!(" Attractor type: {:?}", attractor_info.attractor_type);
println!(" Stable: {}", attractor_info.is_stable);
println!(" Confidence: {:.2}", attractor_info.confidence);
println!(" Max Lyapunov: {:.4}", attractor_info.max_lyapunov_exponent().unwrap_or(0.0));
// Verify behavior analysis
assert_eq!(attractor_info.dimension, 3);
assert!(attractor_info.confidence > 0.5);
// Verify scheduler processed all tasks
assert_eq!(scheduler.queue_size(), 150);
println!(" ✓ Scheduled 150 tasks with attractor-aware prioritization");
// Get scheduler stats
let stats = scheduler.stats();
println!(" ✓ Scheduler stats: {} total tasks, {} in queue",
stats.total_tasks, stats.queue_size);
assert_eq!(stats.total_tasks, 150);
println!("=== Test 2 PASSED ===\n");
}
/// Test 3: Attractor + Neural Solver Integration
///
/// Scenario:
/// - Detect behavioral attractors in system dynamics
/// - Verify temporal properties using neural solver
/// - Ensure attractor stability matches temporal invariants
#[test]
fn test_attractor_solver_integration() {
println!("\n=== Test 3: Attractor + Neural Solver Integration ===");
let mut analyzer = AttractorAnalyzer::new(2, 1000);
let mut solver = TemporalNeuralSolver::new(1000, 500, VerificationStrictness::High);
// Simulate limit cycle behavior (periodic oscillation)
for i in 0..200 {
let t = i as f64 * 0.1;
// Create periodic trajectory
let point = PhasePoint::new(
vec![t.sin(), t.cos()],
i as u64 * 10,
);
analyzer.add_point(point).unwrap();
// Record temporal state
let mut state = TemporalState::new(i, i * 10);
state.set_proposition("oscillating", true);
state.set_proposition("bounded", t.sin().abs() <= 1.0 && t.cos().abs() <= 1.0);
state.set_proposition("periodic", i % 63 < 5); // Approximate period detection
solver.add_state(state);
}
// Analyze attractor
let attractor_info = analyzer.analyze().unwrap();
println!(" Attractor type: {:?}", attractor_info.attractor_type);
println!(" Trajectory points: {}", analyzer.trajectory_length());
// Verify temporal properties match attractor behavior
let bounded_formula = TemporalFormula::globally(TemporalFormula::atom("bounded"));
let bounded_result = solver.verify(&bounded_formula).unwrap();
let oscillating_formula = TemporalFormula::globally(TemporalFormula::atom("oscillating"));
let oscillating_result = solver.verify(&oscillating_formula).unwrap();
println!(" ✓ Bounded property: {}", bounded_result.satisfied);
println!(" ✓ Oscillating property: {}", oscillating_result.satisfied);
assert!(bounded_result.satisfied, "Limit cycle should remain bounded");
assert!(oscillating_result.satisfied, "System should always oscillate");
// Verify eventually periodic
let periodic_formula = TemporalFormula::finally(TemporalFormula::atom("periodic"));
let periodic_result = solver.verify(&periodic_formula).unwrap();
assert!(periodic_result.satisfied, "Should detect periodic behavior");
println!(" ✓ Attractor analysis matches temporal verification");
println!("=== Test 3 PASSED ===\n");
}
/// Test 4: Temporal Compare + Neural Solver Integration
///
/// Scenario:
/// - Use pattern matching to identify sequences
/// - Verify sequence properties with temporal logic
/// - Ensure pattern similarity correlates with verification confidence
#[test]
fn test_temporal_solver_integration() {
println!("\n=== Test 4: Temporal Compare + Neural Solver Integration ===");
let comparator: TemporalComparator<String> = TemporalComparator::new(100, 1000);
let mut solver = TemporalNeuralSolver::new(1000, 500, VerificationStrictness::Medium);
// Create sequences representing system states
let mut seq1: Sequence<String> = Sequence::new();
seq1.push("safe".to_string(), 0);
seq1.push("safe".to_string(), 100);
seq1.push("safe".to_string(), 200);
seq1.push("unsafe".to_string(), 300);
let mut seq2: Sequence<String> = Sequence::new();
seq2.push("safe".to_string(), 0);
seq2.push("safe".to_string(), 100);
seq2.push("safe".to_string(), 200);
seq2.push("safe".to_string(), 300);
// Compare sequences
let distance = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::EditDistance).unwrap();
println!(" Edit distance: {:.4}", distance.distance);
assert_eq!(distance.distance, 1.0, "Should differ by one element");
// Verify temporal properties
for i in 0..4 {
let mut state = TemporalState::new(i, i * 100);
let is_safe = seq2.elements[i as usize].value == "safe";
state.set_proposition("safe", is_safe);
solver.add_state(state);
}
// G safe - should be true for seq2
let safety_formula = TemporalFormula::globally(TemporalFormula::atom("safe"));
let result = solver.verify(&safety_formula).unwrap();
println!(" ✓ Safety property verified: {}", result.satisfied);
println!(" ✓ Confidence: {:.2}", result.confidence);
assert!(result.satisfied, "seq2 should maintain safety");
println!("=== Test 4 PASSED ===\n");
}
/// Test 5: Full System Integration with Strange Loop
///
/// Scenario:
/// - Meta-learning from complete workflow execution
/// - Integrate all crates in hierarchical meta-analysis
/// - Verify self-referential optimization
#[test]
fn test_full_system_strange_loop() {
println!("\n=== Test 5: Full System Integration with Strange Loop ===");
let mut strange_loop = StrangeLoop::new(StrangeLoopConfig {
max_levels: 5,
max_knowledge_per_level: 100,
enable_reflection: true,
learning_rate: 0.1,
});
let scheduler: RealtimeScheduler<String> = RealtimeScheduler::default();
let mut analyzer = AttractorAnalyzer::new(3, 1000);
let mut solver = TemporalNeuralSolver::default();
// Level 0: Base-level workflow
println!(" Level 0: Base workflow execution...");
let workflow_steps = vec![
"schedule".to_string(),
"execute".to_string(),
"analyze".to_string(),
"verify".to_string(),
];
strange_loop.learn_at_level(MetaLevel::base(), &workflow_steps).unwrap();
// Schedule tasks for each workflow step
for (i, step) in workflow_steps.iter().enumerate() {
scheduler.schedule(
step.clone(),
Deadline::from_millis((i as u64 + 1) * 100),
Priority::High,
).unwrap();
}
// Analyze dynamics
for i in 0..150 {
let point = PhasePoint::new(
vec![i as f64, (i as f64).sin(), (i as f64).cos()],
i as u64,
);
analyzer.add_point(point).unwrap();
}
let attractor_info = analyzer.analyze().unwrap();
// Verify workflow properties
for i in 0..workflow_steps.len() {
let mut state = TemporalState::new(i as u64, i as u64 * 100);
state.set_proposition("scheduled", i >= 0);
state.set_proposition("executed", i >= 1);
state.set_proposition("analyzed", i >= 2);
state.set_proposition("verified", i >= 3);
solver.add_state(state);
}
// Level 1: Meta-learning from workflow patterns
println!(" Level 1: Meta-learning from patterns...");
let meta_patterns = vec![
format!("attractor:{:?}", attractor_info.attractor_type),
format!("stable:{}", attractor_info.is_stable),
];
strange_loop.learn_at_level(MetaLevel(1), &meta_patterns).unwrap();
// Level 2: Analyze behavioral dynamics
println!(" Level 2: Behavioral dynamics analysis...");
let trajectory_data: Vec<Vec<f64>> = (0..150)
.map(|i| vec![i as f64, (i as f64).sin(), (i as f64).cos()])
.collect();
let behavior_type = strange_loop.analyze_behavior(trajectory_data).unwrap();
println!(" ✓ Detected behavior: {}", behavior_type);
// Verify meta-learning effectiveness
let summary = strange_loop.get_summary();
println!(" ✓ Meta-learning summary:");
println!(" - Total levels: {}", summary.total_levels);
println!(" - Total knowledge: {}", summary.total_knowledge);
println!(" - Learning iterations: {}", summary.learning_iterations);
assert!(summary.total_levels >= 2);
assert!(summary.total_knowledge > 0);
assert!(summary.learning_iterations > 0);
// Verify workflow completion
let eventually_verified = TemporalFormula::finally(TemporalFormula::atom("verified"));
let result = solver.verify(&eventually_verified).unwrap();
assert!(result.satisfied, "Workflow should eventually verify");
println!(" ✓ Complete system integration verified");
println!("=== Test 5 PASSED ===\n");
}
/// Test 6: Error Propagation Across Crates
///
/// Scenario:
/// - Test error handling in each crate
/// - Verify errors propagate correctly across boundaries
/// - Ensure graceful degradation
#[test]
fn test_error_propagation() {
println!("\n=== Test 6: Error Propagation ===");
// Test 1: Attractor analyzer dimension mismatch
let mut analyzer = AttractorAnalyzer::new(3, 1000);
let invalid_point = PhasePoint::new(vec![1.0, 2.0], 100);
let result = analyzer.add_point(invalid_point);
assert!(result.is_err(), "Should error on dimension mismatch");
println!(" ✓ Attractor dimension validation works");
// Test 2: Attractor analyzer insufficient data
let analyzer2 = AttractorAnalyzer::new(2, 1000);
let result = analyzer2.analyze();
assert!(result.is_err(), "Should error on insufficient data");
println!(" ✓ Attractor insufficient data detection works");
// Test 3: Temporal solver empty trace
let solver = TemporalNeuralSolver::default();
let formula = TemporalFormula::atom("test");
let result = solver.verify(&formula);
assert!(result.is_err(), "Should error on empty trace");
println!(" ✓ Temporal solver empty trace detection works");
// Test 4: Scheduler queue full
let scheduler: RealtimeScheduler<String> = RealtimeScheduler::new(SchedulerConfig {
max_queue_size: 5,
..Default::default()
});
for i in 0..10 {
let result = scheduler.schedule(
format!("task_{}", i),
Deadline::from_millis(100),
Priority::Medium,
);
if i >= 5 {
assert!(result.is_err(), "Should error when queue is full");
}
}
println!(" ✓ Scheduler queue overflow detection works");
// Test 5: Strange loop max depth
let mut strange_loop = StrangeLoop::default();
let deep_level = MetaLevel(10);
let data = vec!["test".to_string()];
let result = strange_loop.learn_at_level(deep_level, &data);
assert!(result.is_err(), "Should error on max depth exceeded");
println!(" ✓ Strange loop depth limit enforcement works");
// Test 6: Temporal comparator sequence too long
let comparator: TemporalComparator<i32> = TemporalComparator::new(100, 100);
let mut long_seq: Sequence<i32> = Sequence::new();
for i in 0..200 {
long_seq.push(i, i as u64);
}
let mut short_seq: Sequence<i32> = Sequence::new();
short_seq.push(1, 0);
let result = comparator.compare(&long_seq, &short_seq, ComparisonAlgorithm::DTW);
assert!(result.is_err(), "Should error on sequence too long");
println!(" ✓ Temporal comparator length validation works");
println!("=== Test 6 PASSED ===\n");
}
/// Test 7: Performance and Scalability
///
/// Scenario:
/// - Test throughput under load
/// - Verify latency requirements (<1ms for scheduler)
/// - Ensure cache effectiveness
#[test]
fn test_performance_scalability() {
println!("\n=== Test 7: Performance and Scalability ===");
use std::time::Instant;
// Test 1: Scheduler throughput
let start = Instant::now();
let scheduler: RealtimeScheduler<u64> = RealtimeScheduler::default();
for i in 0..1000 {
scheduler.schedule(
i,
Deadline::from_millis(100),
Priority::Medium,
).unwrap();
}
let duration = start.elapsed();
println!(" ✓ Scheduled 1000 tasks in {:?}", duration);
println!(" ✓ Average latency: {:?} per task", duration / 1000);
assert!(duration.as_millis() < 100, "Should schedule fast");
// Test 2: Temporal comparison with caching
let start = Instant::now();
let comparator: TemporalComparator<i32> = TemporalComparator::new(1000, 10000);
let mut seq1: Sequence<i32> = Sequence::new();
let mut seq2: Sequence<i32> = Sequence::new();
for i in 0..100 {
seq1.push(i, i as u64);
seq2.push(i, i as u64);
}
// First comparison - cache miss
let _result1 = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::DTW).unwrap();
// Second comparison - cache hit
let _result2 = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::DTW).unwrap();
let duration = start.elapsed();
println!(" ✓ Compared 100-element sequences (2x) in {:?}", duration);
let stats = comparator.cache_stats();
println!(" ✓ Cache hits: {}, misses: {}", stats.hits, stats.misses);
println!(" ✓ Cache hit rate: {:.2}%", stats.hit_rate() * 100.0);
assert!(stats.hits >= 1, "Should have at least one cache hit");
// Test 3: Attractor analysis performance
let start = Instant::now();
let mut analyzer = AttractorAnalyzer::new(3, 10000);
for i in 0..1000 {
let point = PhasePoint::new(
vec![(i as f64).sin(), (i as f64).cos(), i as f64 * 0.01],
i,
);
analyzer.add_point(point).unwrap();
}
let duration = start.elapsed();
println!(" ✓ Added 1000 phase points in {:?}", duration);
let start = Instant::now();
let _info = analyzer.analyze().unwrap();
let analysis_duration = start.elapsed();
println!(" ✓ Analyzed trajectory in {:?}", analysis_duration);
println!("=== Test 7 PASSED ===\n");
}
/// Test 8: Pattern Detection Pipeline
///
/// Scenario:
/// - Detect patterns using temporal compare
/// - Analyze pattern stability with attractors
/// - Verify pattern properties with solver
#[test]
fn test_pattern_detection_pipeline() {
println!("\n=== Test 8: Pattern Detection Pipeline ===");
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
// Time series with repeating pattern
let series = vec![1.0, 2.0, 3.0, 2.0, 1.0, 1.0, 2.0, 3.0, 2.0, 1.0, 5.0, 6.0];
let pattern = vec![1.0, 2.0, 3.0, 2.0, 1.0];
// Find similar patterns
let matches = comparator.find_similar(&series, &pattern, 1.0);
println!(" Found {} pattern matches", matches.len());
for (idx, dist) in &matches {
println!(" Match at index {} with distance {:.4}", idx, dist);
}
assert!(matches.len() >= 2, "Should find repeated pattern");
assert_eq!(matches[0].0, 0, "First match at index 0");
assert_eq!(matches[1].0, 5, "Second match at index 5");
// Test pattern detection
let detected = comparator.detect_pattern(&series, &pattern, 1.0);
assert!(detected, "Pattern should be detected");
let no_match = comparator.detect_pattern(&series, &vec![10.0, 20.0, 30.0], 1.0);
assert!(!no_match, "Non-existent pattern should not be detected");
println!(" ✓ Pattern detection pipeline verified");
println!("=== Test 8 PASSED ===\n");
}
/// Test 9: State Management and Recovery
///
/// Scenario:
/// - Test state persistence and recovery
/// - Verify clear/reset operations
/// - Ensure no memory leaks
#[test]
fn test_state_management() {
println!("\n=== Test 9: State Management and Recovery ===");
// Test 1: Attractor analyzer clear
let mut analyzer = AttractorAnalyzer::new(2, 1000);
for i in 0..50 {
analyzer.add_point(PhasePoint::new(vec![i as f64, i as f64], i)).unwrap();
}
assert_eq!(analyzer.trajectory_length(), 50);
analyzer.clear();
assert_eq!(analyzer.trajectory_length(), 0);
println!(" ✓ Attractor analyzer clear works");
// Test 2: Temporal solver trace clear
let mut solver = TemporalNeuralSolver::default();
for i in 0..20 {
let mut state = TemporalState::new(i, i * 100);
state.set_proposition("test", true);
solver.add_state(state);
}
assert_eq!(solver.trace_length(), 20);
solver.clear_trace();
assert_eq!(solver.trace_length(), 0);
println!(" ✓ Temporal solver clear works");
// Test 3: Strange loop reset
let mut strange_loop = StrangeLoop::default();
strange_loop.learn_at_level(MetaLevel::base(), &vec!["a".to_string()]).unwrap();
let before = strange_loop.get_summary();
assert!(before.total_knowledge > 0);
strange_loop.reset();
let after = strange_loop.get_summary();
assert_eq!(after.total_knowledge, 0);
println!(" ✓ Strange loop reset works");
// Test 4: Scheduler clear
let scheduler: RealtimeScheduler<String> = RealtimeScheduler::default();
for i in 0..10 {
scheduler.schedule(
format!("task_{}", i),
Deadline::from_millis(100),
Priority::Medium,
).unwrap();
}
assert_eq!(scheduler.queue_size(), 10);
scheduler.clear();
assert_eq!(scheduler.queue_size(), 0);
println!(" ✓ Scheduler clear works");
// Test 5: Temporal comparator cache clear
let comparator: TemporalComparator<i32> = TemporalComparator::new(100, 1000);
let mut seq1: Sequence<i32> = Sequence::new();
let mut seq2: Sequence<i32> = Sequence::new();
seq1.push(1, 0);
seq2.push(1, 0);
comparator.compare(&seq1, &seq2, ComparisonAlgorithm::DTW).unwrap();
let stats_before = comparator.cache_stats();
assert!(stats_before.size > 0 || stats_before.misses > 0);
comparator.clear_cache();
let stats_after = comparator.cache_stats();
assert_eq!(stats_after.size, 0);
println!(" ✓ Temporal comparator cache clear works");
println!("=== Test 9 PASSED ===\n");
}
/// Test 10: Deadline and Priority Handling
///
/// Scenario:
/// - Schedule tasks with various deadlines
/// - Verify priority-based execution order
/// - Test deadline miss detection
#[test]
fn test_deadline_priority_handling() {
println!("\n=== Test 10: Deadline and Priority Handling ===");
let scheduler: RealtimeScheduler<String> = RealtimeScheduler::default();
scheduler.start();
// Schedule tasks with different priorities
let low_id = scheduler.schedule(
"low_priority".to_string(),
Deadline::from_millis(100),
Priority::Low,
).unwrap();
let high_id = scheduler.schedule(
"high_priority".to_string(),
Deadline::from_millis(100),
Priority::High,
).unwrap();
let critical_id = scheduler.schedule(
"critical_priority".to_string(),
Deadline::from_millis(100),
Priority::Critical,
).unwrap();
// Verify priority ordering
let task1 = scheduler.next_task().unwrap();
assert_eq!(task1.id, critical_id, "Critical priority should execute first");
assert_eq!(task1.priority, Priority::Critical);
let task2 = scheduler.next_task().unwrap();
assert_eq!(task2.id, high_id, "High priority should execute second");
let task3 = scheduler.next_task().unwrap();
assert_eq!(task3.id, low_id, "Low priority should execute last");
println!(" ✓ Priority-based execution order verified");
// Test deadline miss detection
std::thread::sleep(Duration::from_millis(10));
let past_deadline = Deadline::from_micros(1);
scheduler.schedule(
"late_task".to_string(),
past_deadline,
Priority::High,
).unwrap();
let late_task = scheduler.next_task().unwrap();
scheduler.execute_task(late_task, |_payload| {
// Task execution
});
let stats = scheduler.stats();
println!(" ✓ Completed tasks: {}", stats.completed_tasks);
println!(" ✓ Average latency: {} ns", stats.average_latency_ns);
scheduler.stop();
assert!(!scheduler.is_running());
println!(" ✓ Scheduler lifecycle management works");
println!("=== Test 10 PASSED ===\n");
}
#[cfg(test)]
mod summary {
#[test]
fn print_test_summary() {
println!("\n");
println!("╔═══════════════════════════════════════════════════════════════╗");
println!("║ MidStream Integration Test Suite ║");
println!("╠═══════════════════════════════════════════════════════════════╣");
println!("║ ║");
println!("║ ✓ Test 1: Scheduler + Temporal Compare ║");
println!("║ ✓ Test 2: Scheduler + Attractor Analysis ║");
println!("║ ✓ Test 3: Attractor + Neural Solver ║");
println!("║ ✓ Test 4: Temporal Compare + Neural Solver ║");
println!("║ ✓ Test 5: Full System with Strange Loop ║");
println!("║ ✓ Test 6: Error Propagation ║");
println!("║ ✓ Test 7: Performance and Scalability ║");
println!("║ ✓ Test 8: Pattern Detection Pipeline ║");
println!("║ ✓ Test 9: State Management and Recovery ║");
println!("║ ✓ Test 10: Deadline and Priority Handling ║");
println!("║ ║");
println!("║ Coverage: ║");
println!("║ - Cross-crate integration: ✓ ║");
println!("║ - Real-world scenarios: ✓ ║");
println!("║ - Error handling: ✓ ║");
println!("║ - Performance validation: ✓ ║");
println!("║ - State management: ✓ ║");
println!("║ ║");
println!("╚═══════════════════════════════════════════════════════════════╝");
println!("\n");
}
}
+310
View File
@@ -0,0 +1,310 @@
//! Comprehensive simulation tests for various real-world scenarios
use midstream::{
LeanAgenticSystem, LeanAgenticConfig, AgentContext,
KnowledgeGraph, Entity, EntityType, Relation,
};
use std::time::Instant;
#[tokio::test]
async fn test_weather_intent_simulation() {
let config = LeanAgenticConfig::default();
let system = LeanAgenticSystem::new(config);
let mut context = AgentContext::new("weather_session".to_string());
let messages = vec![
"What's the weather like today?",
"How about tomorrow?",
"Will it rain this weekend?",
"Should I bring an umbrella?",
];
for (i, msg) in messages.iter().enumerate() {
let result = system.process_stream_chunk(msg, context.clone()).await;
assert!(result.is_ok(), "Message {} failed: {:?}", i, result);
let res = result.unwrap();
println!("Message: {}", msg);
println!(" Action: {}", res.action.description);
println!(" Reward: {:.3}", res.reward);
println!(" Verified: {}", res.verified);
context.add_message(msg.to_string());
}
// Verify learning occurred
let stats = system.get_stats().await;
assert!(stats.total_actions >= messages.len() as u64);
println!("\nFinal stats: {:?}", stats);
}
#[tokio::test]
async fn test_knowledge_accumulation_simulation() {
let config = LeanAgenticConfig::default();
let system = LeanAgenticSystem::new(config);
let mut context = AgentContext::new("learning_session".to_string());
let learning_sequence = vec![
"My name is Alice and I work at Google",
"I live in San Francisco",
"I prefer detailed weather forecasts",
"My favorite color is blue",
"I usually wake up at 7 AM",
];
for msg in &learning_sequence {
let result = system.process_stream_chunk(msg, context.clone()).await.unwrap();
context.add_message(msg.to_string());
context.set_preference("detail_level".to_string(), 0.9);
}
let stats = system.get_stats().await;
// Verify knowledge was accumulated
assert!(stats.total_entities > 0, "No entities extracted");
assert!(stats.learning_iterations > 0, "No learning occurred");
println!("Knowledge accumulation results:");
println!(" Entities: {}", stats.total_entities);
println!(" Learning iterations: {}", stats.learning_iterations);
println!(" Average reward: {:.3}", stats.average_reward);
}
#[tokio::test]
async fn test_high_frequency_streaming_simulation() {
let config = LeanAgenticConfig {
enable_formal_verification: false, // Disable for speed
learning_rate: 0.05,
..Default::default()
};
let system = LeanAgenticSystem::new(config);
let context = AgentContext::new("streaming_session".to_string());
let start = Instant::now();
let num_chunks = 1000;
for i in 0..num_chunks {
let chunk = format!("Stream chunk {}", i);
let result = system.process_stream_chunk(&chunk, context.clone()).await;
assert!(result.is_ok(), "Chunk {} failed", i);
}
let duration = start.elapsed();
let chunks_per_sec = num_chunks as f64 / duration.as_secs_f64();
println!("\nHigh-frequency streaming results:");
println!(" Total chunks: {}", num_chunks);
println!(" Duration: {:?}", duration);
println!(" Throughput: {:.2} chunks/sec", chunks_per_sec);
println!(" Avg latency: {:.2} ms/chunk", duration.as_millis() as f64 / num_chunks as f64);
// Verify minimum throughput
assert!(chunks_per_sec > 50.0, "Throughput too low: {:.2} chunks/sec", chunks_per_sec);
}
#[tokio::test]
async fn test_concurrent_sessions_simulation() {
let config = LeanAgenticConfig::default();
let system = LeanAgenticSystem::new(config);
let num_sessions = 100;
let mut handles = vec![];
let start = Instant::now();
for i in 0..num_sessions {
let sys = &system;
let handle = tokio::spawn(async move {
let context = AgentContext::new(format!("session_{}", i));
let messages = vec![
"Hello",
"What's the weather?",
"Thank you",
];
for msg in messages {
sys.process_stream_chunk(msg, context.clone()).await.unwrap();
}
});
handles.push(handle);
}
for handle in handles {
handle.await.unwrap();
}
let duration = start.elapsed();
println!("\nConcurrent sessions results:");
println!(" Sessions: {}", num_sessions);
println!(" Duration: {:?}", duration);
println!(" Avg per session: {:.2} ms", duration.as_millis() as f64 / num_sessions as f64);
let stats = system.get_stats().await;
println!(" Total actions: {}", stats.total_actions);
}
#[tokio::test]
async fn test_learning_convergence_simulation() {
let config = LeanAgenticConfig {
learning_rate: 0.1, // Higher learning rate for faster convergence
..Default::default()
};
let system = LeanAgenticSystem::new(config);
let mut context = AgentContext::new("convergence_session".to_string());
// Repeat the same pattern to test learning convergence
let pattern = "What is the weather in Tokyo?";
let mut rewards = vec![];
for iteration in 0..100 {
let result = system.process_stream_chunk(pattern, context.clone()).await.unwrap();
rewards.push(result.reward);
if iteration % 10 == 0 {
println!("Iteration {}: reward = {:.3}", iteration, result.reward);
}
context.add_message(pattern.to_string());
}
// Check if rewards are improving (basic convergence check)
let early_avg: f64 = rewards[0..20].iter().sum::<f64>() / 20.0;
let late_avg: f64 = rewards[80..100].iter().sum::<f64>() / 20.0;
println!("\nLearning convergence results:");
println!(" Early average reward (0-20): {:.3}", early_avg);
println!(" Late average reward (80-100): {:.3}", late_avg);
println!(" Improvement: {:.3}", late_avg - early_avg);
// Rewards should stabilize or improve
assert!(late_avg >= early_avg * 0.8, "Learning degraded significantly");
}
#[tokio::test]
async fn test_knowledge_graph_scaling() {
let mut kg = KnowledgeGraph::new();
let start = Instant::now();
let num_entities = 10000;
// Add many entities
for i in 0..num_entities {
let entity = Entity {
id: format!("entity_{}", i),
name: format!("Entity {}", i),
entity_type: if i % 3 == 0 {
EntityType::Person
} else if i % 3 == 1 {
EntityType::Organization
} else {
EntityType::Concept
},
attributes: std::collections::HashMap::new(),
confidence: 0.9,
};
kg.update(vec![entity]).await.unwrap();
}
let insert_duration = start.elapsed();
// Add relations
let relation_start = Instant::now();
for i in 0..1000 {
kg.add_relation(Relation {
id: format!("rel_{}", i),
subject: format!("entity_{}", i * 10),
predicate: "relates_to".to_string(),
object: format!("entity_{}", i * 10 + 1),
confidence: 0.85,
source: "test".to_string(),
});
}
let relation_duration = relation_start.elapsed();
// Query performance
let query_start = Instant::now();
let results = kg.query_entities(EntityType::Person);
let query_duration = query_start.elapsed();
println!("\nKnowledge graph scaling results:");
println!(" Entities inserted: {}", num_entities);
println!(" Insert time: {:?}", insert_duration);
println!(" Insert rate: {:.2} entities/sec", num_entities as f64 / insert_duration.as_secs_f64());
println!(" Relations added: 1000");
println!(" Relation time: {:?}", relation_duration);
println!(" Query time: {:?}", query_duration);
println!(" Results found: {}", results.len());
assert_eq!(kg.entity_count(), num_entities);
assert_eq!(kg.relation_count(), 1000);
}
#[tokio::test]
async fn test_adaptive_behavior_simulation() {
let config = LeanAgenticConfig {
learning_rate: 0.05,
..Default::default()
};
let system = LeanAgenticSystem::new(config);
let mut context = AgentContext::new("adaptive_session".to_string());
// Phase 1: Weather queries
println!("\nPhase 1: Weather queries");
for i in 0..10 {
let msg = format!("What's the weather in city {}?", i);
let result = system.process_stream_chunk(&msg, context.clone()).await.unwrap();
context.add_message(msg);
if i == 0 || i == 9 {
println!(" Iteration {}: reward = {:.3}", i, result.reward);
}
}
// Phase 2: Switch to learning/memory queries
println!("\nPhase 2: Learning queries");
for i in 0..10 {
let msg = format!("Remember that I like {}", i);
let result = system.process_stream_chunk(&msg, context.clone()).await.unwrap();
context.add_message(msg);
if i == 0 || i == 9 {
println!(" Iteration {}: reward = {:.3}", i, result.reward);
}
}
let stats = system.get_stats().await;
println!("\nAdaptive behavior stats:");
println!(" Total actions: {}", stats.total_actions);
println!(" Average reward: {:.3}", stats.average_reward);
println!(" Entities learned: {}", stats.total_entities);
assert!(stats.total_actions >= 20);
}
#[tokio::test]
async fn test_memory_efficiency() {
use std::mem::size_of;
println!("\nMemory efficiency analysis:");
println!(" AgentContext: {} bytes", size_of::<AgentContext>());
println!(" Entity: {} bytes", size_of::<Entity>());
println!(" Relation: {} bytes", size_of::<Relation>());
// Test memory growth with many sessions
let config = LeanAgenticConfig::default();
let system = LeanAgenticSystem::new(config);
for i in 0..100 {
let context = AgentContext::new(format!("session_{}", i));
system.process_stream_chunk("test", context).await.unwrap();
}
let stats = system.get_stats().await;
println!(" Sessions processed: 100");
println!(" Total entities: {}", stats.total_entities);
println!(" Estimated memory per session: ~{} KB",
(stats.total_entities * size_of::<Entity>()) / 100 / 1024);
}
+271
View File
@@ -0,0 +1,271 @@
/// Integration tests for temporal-compare pattern detection APIs
///
/// This test suite verifies that the find_similar() and detect_pattern() APIs
/// work correctly with the published crate.
use midstreamer_temporal_compare::{TemporalComparator, Pattern, SimilarityMatch};
#[test]
fn test_find_similar_with_f64() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
// Create a time series with repeating patterns
let series = vec![1.0, 2.0, 3.0, 4.0, 5.0, 3.0, 4.0, 5.0, 6.0, 7.0];
let pattern = vec![3.0, 4.0, 5.0];
// Find similar patterns with a reasonable threshold
let matches = comparator.find_similar(&series, &pattern, 1.0);
// Verify we found the expected matches
assert!(!matches.is_empty(), "Should find at least one match");
assert_eq!(matches.len(), 2, "Should find exactly 2 matches");
// Verify the indices are correct
assert_eq!(matches[0].0, 2, "First match should be at index 2");
assert_eq!(matches[1].0, 5, "Second match should be at index 5");
// Verify distances are within threshold
for (idx, distance) in &matches {
assert!(*distance <= 1.0, "Distance {} at index {} exceeds threshold", distance, idx);
}
}
#[test]
fn test_detect_pattern_exists() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
let series = vec![1.0, 2.0, 3.0, 4.0, 5.0, 3.0, 4.0, 5.0];
let pattern = vec![3.0, 4.0, 5.0];
// Detect if pattern exists
let found = comparator.detect_pattern(&series, &pattern, 0.5);
assert!(found, "Pattern should be detected in the series");
}
#[test]
fn test_detect_pattern_not_exists() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
let series = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let pattern = vec![10.0, 20.0, 30.0];
// Detect if pattern exists with strict threshold
let found = comparator.detect_pattern(&series, &pattern, 0.5);
assert!(!found, "Pattern should not be detected (too different)");
}
#[test]
fn test_find_similar_generic_with_integers() {
let comparator: TemporalComparator<i32> = TemporalComparator::new(100, 1000);
let haystack = vec![1, 2, 3, 4, 5, 3, 4, 5, 6];
let needle = vec![3, 4, 5];
// Use the generic API with normalized threshold
let matches = comparator.find_similar_generic(&haystack, &needle, 0.1).unwrap();
assert_eq!(matches.len(), 2, "Should find 2 exact matches");
assert_eq!(matches[0].start_index, 2);
assert_eq!(matches[1].start_index, 5);
// Verify similarity scores
for m in &matches {
assert!(m.similarity > 0.9, "Exact matches should have high similarity");
}
}
#[test]
fn test_detect_recurring_patterns() {
let comparator: TemporalComparator<char> = TemporalComparator::new(100, 1000);
// Create sequence with recurring patterns
let sequence = vec!['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'];
// Detect patterns of length 3
let patterns = comparator.detect_recurring_patterns(&sequence, 3, 3).unwrap();
assert!(!patterns.is_empty(), "Should detect recurring patterns");
// Find the 'abc' pattern
let abc_pattern = patterns.iter()
.find(|p| p.sequence == vec!['a', 'b', 'c']);
assert!(abc_pattern.is_some(), "Should find 'abc' pattern");
let pattern = abc_pattern.unwrap();
assert_eq!(pattern.frequency(), 3, "Pattern should occur 3 times");
assert!(pattern.confidence > 0.0, "Should have positive confidence");
}
#[test]
fn test_detect_fuzzy_patterns() {
let comparator: TemporalComparator<i32> = TemporalComparator::new(100, 1000);
// Sequence with similar but not identical patterns
let sequence = vec![1, 2, 3, 1, 2, 4, 1, 2, 3];
// Detect fuzzy patterns (should group [1,2,3] and [1,2,4] together)
let patterns = comparator.detect_fuzzy_patterns(&sequence, 3, 3, 0.7).unwrap();
assert!(!patterns.is_empty(), "Should detect fuzzy patterns");
// Should find at least one pattern that occurs multiple times
let has_multiple = patterns.iter().any(|p| p.frequency() >= 2);
assert!(has_multiple, "Should find patterns with multiple occurrences");
}
#[test]
fn test_pattern_struct_api() {
let sequence = vec![1, 2, 3];
let occurrences = vec![0, 5, 10];
let confidence = 0.85;
let pattern = Pattern::new(sequence.clone(), occurrences.clone(), confidence);
// Verify Pattern API
assert_eq!(pattern.sequence, sequence);
assert_eq!(pattern.occurrences, occurrences);
assert_eq!(pattern.confidence, confidence);
assert_eq!(pattern.frequency(), 3);
assert_eq!(pattern.length(), 3);
}
#[test]
fn test_similarity_match_struct() {
let match1 = SimilarityMatch::new(0, 0.5);
assert_eq!(match1.start_index, 0);
assert_eq!(match1.distance, 0.5);
assert!(match1.similarity > 0.0 && match1.similarity <= 1.0);
// Lower distance should give higher similarity
let match2 = SimilarityMatch::new(0, 0.1);
assert!(match2.similarity > match1.similarity,
"Lower distance should yield higher similarity");
}
#[test]
fn test_edge_case_empty_pattern() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
let series = vec![1.0, 2.0, 3.0];
let pattern: Vec<f64> = vec![];
let matches = comparator.find_similar(&series, &pattern, 1.0);
assert!(matches.is_empty(), "Empty pattern should return no matches");
let found = comparator.detect_pattern(&series, &pattern, 1.0);
assert!(!found, "Empty pattern should not be detected");
}
#[test]
fn test_edge_case_pattern_longer_than_series() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
let series = vec![1.0, 2.0];
let pattern = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let matches = comparator.find_similar(&series, &pattern, 1.0);
assert!(matches.is_empty(), "Pattern longer than series should return no matches");
}
#[test]
fn test_approximate_matching_with_threshold() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
// Series with approximate match
let series = vec![1.0, 2.0, 3.1, 4.2, 5.0, 6.0];
let pattern = vec![3.0, 4.0, 5.0];
// Strict threshold - should not match
let strict_matches = comparator.find_similar(&series, &pattern, 0.1);
assert!(strict_matches.is_empty(), "Strict threshold should reject approximate match");
// Loose threshold - should match
let loose_matches = comparator.find_similar(&series, &pattern, 1.5);
assert!(!loose_matches.is_empty(), "Loose threshold should accept approximate match");
}
#[test]
fn test_results_sorted_by_quality() {
let comparator: TemporalComparator<f64> = TemporalComparator::new(100, 1000);
// Series with exact and approximate matches
let series = vec![1.0, 2.0, 3.0, 4.0, 5.0, 3.5, 4.5, 5.5];
let pattern = vec![3.0, 4.0, 5.0];
let matches = comparator.find_similar(&series, &pattern, 2.0);
assert!(!matches.is_empty(), "Should find matches");
// Verify results are sorted by distance (best first)
for i in 0..matches.len().saturating_sub(1) {
assert!(matches[i].1 <= matches[i + 1].1,
"Results should be sorted by distance (ascending)");
}
// First match should be the exact one
assert!(matches[0].1 < 0.1, "Best match should have very low distance");
}
#[test]
fn test_caching_behavior() {
let comparator: TemporalComparator<i32> = TemporalComparator::new(100, 1000);
let haystack = vec![1, 2, 3, 4, 5];
let needle = vec![3, 4, 5];
// Clear cache to start fresh
comparator.clear_cache();
// First call - should be cache miss
let _ = comparator.find_similar_generic(&haystack, &needle, 0.1).unwrap();
// Second call - should be cache hit
let _ = comparator.find_similar_generic(&haystack, &needle, 0.1).unwrap();
let stats = comparator.cache_stats();
assert!(stats.hits > 0, "Should have cache hits");
assert!(stats.hits + stats.misses > 0, "Should have cache activity");
}
#[test]
fn test_comprehensive_workflow() {
let comparator: TemporalComparator<i32> = TemporalComparator::new(100, 1000);
// Create a rich sequence
let sequence = vec![
1, 2, 3, 4, // Pattern A
1, 2, 3, 4, // Pattern A repeat
5, 6, 7, // Pattern B
5, 6, 7, // Pattern B repeat
1, 2, 3, 4, // Pattern A again
];
// Test 1: Exact pattern detection
let exact_patterns = comparator.detect_recurring_patterns(&sequence, 3, 4).unwrap();
assert!(!exact_patterns.is_empty(), "Should detect exact patterns");
// Test 2: Fuzzy pattern detection
let fuzzy_patterns = comparator.detect_fuzzy_patterns(&sequence, 3, 4, 0.8).unwrap();
assert!(!fuzzy_patterns.is_empty(), "Should detect fuzzy patterns");
// Test 3: Similarity search
let needle = vec![1, 2, 3, 4];
let matches = comparator.find_similar_generic(&sequence, &needle, 0.1).unwrap();
assert_eq!(matches.len(), 3, "Should find 3 occurrences of pattern");
// Test 4: Simple detection
let found = comparator.detect_pattern(
&sequence.iter().map(|&x| x as f64).collect::<Vec<_>>(),
&needle.iter().map(|&x| x as f64).collect::<Vec<_>>(),
1.0
);
assert!(found, "Pattern should be detected");
// Test 5: Verify caching is working
let stats = comparator.cache_stats();
assert!(stats.size > 0, "Cache should have entries");
}
+467
View File
@@ -0,0 +1,467 @@
//! Integration tests for temporal comparison and scheduling
//!
//! Tests real-world scenarios combining temporal analysis and scheduling
use midstream::{
TemporalComparator, Sequence, ComparisonAlgorithm,
RealtimeScheduler, SchedulingPolicy, Priority,
Action, AgentContext, AgenticLoop, LeanAgenticConfig,
};
use std::collections::HashMap;
use std::time::Duration;
#[tokio::test]
async fn test_temporal_conversation_pattern_matching() {
// Simulate detecting similar conversation patterns
let mut comparator = TemporalComparator::<String>::new();
// Add historical conversation sequences
comparator.add_sequence(Sequence {
data: vec![
"greeting".to_string(),
"weather_query".to_string(),
"location_query".to_string(),
"weather_response".to_string(),
],
timestamp: 1000,
id: "conv1".to_string(),
});
comparator.add_sequence(Sequence {
data: vec![
"greeting".to_string(),
"weather_query".to_string(),
"location_query".to_string(),
"weather_response".to_string(),
"followup".to_string(),
],
timestamp: 2000,
id: "conv2".to_string(),
});
comparator.add_sequence(Sequence {
data: vec![
"greeting".to_string(),
"calendar_query".to_string(),
"calendar_response".to_string(),
],
timestamp: 3000,
id: "conv3".to_string(),
});
// Query with new conversation
let query = vec![
"greeting".to_string(),
"weather_query".to_string(),
"location_query".to_string(),
];
let similar = comparator.find_similar(&query, 0.7, ComparisonAlgorithm::LCS);
// Should find conv1 and conv2 as similar (weather conversations)
assert!(similar.len() >= 2);
println!("Found {} similar conversations", similar.len());
for (idx, score) in similar.iter() {
println!("Conversation {}: similarity = {}", idx, score);
assert!(*score >= 0.7);
}
}
#[tokio::test]
async fn test_temporal_action_sequence_analysis() {
// Test analyzing agent action sequences over time
let mut comparator = TemporalComparator::<String>::new();
// Normal behavior pattern
let normal_sequence = vec![
"plan".to_string(),
"verify".to_string(),
"execute".to_string(),
"observe".to_string(),
"learn".to_string(),
];
// Anomalous behavior (skips verification)
let anomalous_sequence = vec![
"plan".to_string(),
"execute".to_string(),
"observe".to_string(),
"learn".to_string(),
];
// Compare sequences
let similarity = comparator.compare(
&normal_sequence,
&anomalous_sequence,
ComparisonAlgorithm::LCS,
);
println!("Similarity between normal and anomalous: {}", similarity);
// LCS should show high similarity but not perfect
assert!(similarity > 0.6);
assert!(similarity < 1.0);
// Edit distance should show difference
let distance = comparator.compare(
&normal_sequence,
&anomalous_sequence,
ComparisonAlgorithm::EditDistance,
);
println!("Edit distance: {}", distance);
assert!(distance > 0.0); // Should detect the missing step
}
#[tokio::test]
async fn test_scheduler_with_deadlines() {
// Test real-time scheduling with various deadline constraints
let scheduler = RealtimeScheduler::new(SchedulingPolicy::EarliestDeadlineFirst);
// Schedule critical task with tight deadline
let critical_action = Action {
action_type: "critical_response".to_string(),
description: "User safety check".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: Some("safe".to_string()),
expected_reward: 1.0,
};
let critical_id = scheduler.schedule(
critical_action,
Priority::Critical,
Duration::from_millis(50), // Very tight deadline
Duration::from_millis(10),
).await;
// Schedule normal task with relaxed deadline
let normal_action = Action {
action_type: "normal_query".to_string(),
description: "Regular information request".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: None,
expected_reward: 0.7,
};
scheduler.schedule(
normal_action,
Priority::Medium,
Duration::from_secs(5), // Relaxed deadline
Duration::from_millis(100),
).await;
// EDF should prioritize the critical task due to earlier deadline
let next = scheduler.next_task().await.unwrap();
assert_eq!(next.id, critical_id);
assert_eq!(next.action.action_type, "critical_response");
println!("Scheduler correctly prioritized critical task with tight deadline");
}
#[tokio::test]
async fn test_scheduler_priority_override() {
// Test that priority scheduling overrides based on priority level
let scheduler = RealtimeScheduler::new(SchedulingPolicy::FixedPriority);
// Schedule low priority task first
scheduler.schedule(
Action {
action_type: "background_task".to_string(),
description: "Background processing".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: None,
expected_reward: 0.3,
},
Priority::Background,
Duration::from_secs(10),
Duration::from_millis(100),
).await;
// Schedule high priority task second
scheduler.schedule(
Action {
action_type: "urgent_task".to_string(),
description: "Urgent response needed".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: None,
expected_reward: 0.9,
},
Priority::Critical,
Duration::from_secs(10),
Duration::from_millis(50),
).await;
// Should get high priority task first despite being scheduled later
let next = scheduler.next_task().await.unwrap();
assert_eq!(next.action.action_type, "urgent_task");
println!("Priority scheduling correctly prioritized critical task");
}
#[tokio::test]
async fn test_combined_temporal_and_scheduling() {
// Integration test: Use temporal patterns to inform scheduling decisions
let mut comparator = TemporalComparator::<String>::new();
let scheduler = RealtimeScheduler::new(SchedulingPolicy::EarliestDeadlineFirst);
// Historical pattern: queries that led to good outcomes
comparator.add_sequence(Sequence {
data: vec![
"user_query".to_string(),
"context_check".to_string(),
"knowledge_lookup".to_string(),
"response".to_string(),
],
timestamp: 1000,
id: "good_pattern".to_string(),
});
// Current query sequence
let current = vec!["user_query".to_string(), "context_check".to_string()];
// Find similar patterns
let similar = comparator.find_similar(&current, 0.5, ComparisonAlgorithm::LCS);
if !similar.is_empty() {
println!("Found similar successful pattern, scheduling with high priority");
// Schedule next expected action with higher priority
scheduler.schedule(
Action {
action_type: "knowledge_lookup".to_string(),
description: "Predicted next action from pattern".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: Some("success".to_string()),
expected_reward: 0.85,
},
Priority::High, // Higher priority based on pattern match
Duration::from_millis(100),
Duration::from_millis(20),
).await;
}
let stats = scheduler.get_stats().await;
assert_eq!(stats.total_scheduled, 1);
println!("Successfully combined temporal pattern matching with scheduling");
}
#[tokio::test]
async fn test_scheduler_deadline_checking() {
// Test the can_meet_deadline functionality
let scheduler = RealtimeScheduler::new(SchedulingPolicy::EarliestDeadlineFirst);
// Empty queue - should be able to meet deadline
let can_meet = scheduler.can_meet_deadline(
Duration::from_millis(10),
Duration::from_secs(1),
).await;
assert!(can_meet);
// Add many tasks
for i in 0..50 {
scheduler.schedule(
Action {
action_type: format!("task_{}", i),
description: format!("Task {}", i),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: None,
expected_reward: 0.7,
},
Priority::Medium,
Duration::from_secs(10),
Duration::from_millis(50), // Each task takes 50ms
).await;
}
// Now with 50 tasks * 50ms = 2500ms pending work
let can_meet_tight = scheduler.can_meet_deadline(
Duration::from_millis(10),
Duration::from_millis(100), // Want to finish in 100ms
).await;
assert!(!can_meet_tight); // Should not be able to meet tight deadline
let can_meet_loose = scheduler.can_meet_deadline(
Duration::from_millis(10),
Duration::from_secs(10), // Generous deadline
).await;
assert!(can_meet_loose); // Should be able to meet loose deadline
println!("Deadline checking correctly estimates feasibility");
}
#[tokio::test]
async fn test_temporal_caching() {
// Test that temporal comparison caching works correctly
let mut comparator = TemporalComparator::<i32>::new();
let seq1: Vec<i32> = (0..100).collect();
let seq2: Vec<i32> = (0..100).map(|x| x + 1).collect();
// First comparison - not cached
let result1 = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::DTW);
// Second comparison - should be cached
let result2 = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::DTW);
assert_eq!(result1, result2);
let stats = comparator.cache_stats();
println!("Cache stats: {:?}", stats);
// Should have cached the result
assert_eq!(stats.dtw_count, 1); // Only computed once
// Try different algorithm - should compute again
let _result3 = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::LCS);
let stats2 = comparator.cache_stats();
assert_eq!(stats2.lcs_count, 1);
assert_eq!(stats2.total_comparisons, 2); // DTW + LCS
println!("Caching working correctly: {} total comparisons", stats2.total_comparisons);
}
#[tokio::test]
async fn test_pattern_detection_in_stream() {
// Simulate detecting recurring patterns in a stream
let comparator = TemporalComparator::<String>::new();
// Simulated stream of user intents
let intent_stream = vec![
"weather", "location", "weather", "news", "sports",
"weather", "location", "weather", "calendar", "weather",
"location", "weather",
].into_iter().map(|s| s.to_string()).collect::<Vec<_>>();
// Pattern we're looking for
let pattern = vec!["weather".to_string(), "location".to_string(), "weather".to_string()];
let positions = comparator.detect_pattern(&intent_stream, &pattern);
println!("Found pattern at positions: {:?}", positions);
assert!(!positions.is_empty());
// Should find the pattern at position 0 and position 9
assert!(positions.contains(&0));
assert!(positions.contains(&9));
println!("Successfully detected {} pattern occurrences in stream", positions.len());
}
#[tokio::test]
async fn test_scheduler_stats_tracking() {
// Test that scheduler correctly tracks statistics
let scheduler = RealtimeScheduler::new(SchedulingPolicy::EarliestDeadlineFirst);
// Schedule and execute several tasks
for i in 0..10 {
let task_id = scheduler.schedule(
Action {
action_type: format!("task_{}", i),
description: format!("Task {}", i),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: None,
expected_reward: 0.7,
},
Priority::Medium,
Duration::from_secs(1),
Duration::from_millis(10),
).await;
// Mark as executed with varying durations
scheduler.mark_executed(task_id, Duration::from_micros(100 * (i + 1))).await;
}
let stats = scheduler.get_stats().await;
assert_eq!(stats.total_scheduled, 10);
assert_eq!(stats.total_executed, 10);
assert!(stats.average_latency_ns > 0);
assert!(stats.max_latency_ns >= stats.min_latency_ns);
println!("Scheduler stats: {:?}", stats);
println!("Average latency: {} μs", stats.average_latency_ns / 1000);
}
#[tokio::test]
async fn test_real_world_conversation_flow() {
// Simulate a realistic conversation flow with scheduling
let mut comparator = TemporalComparator::<String>::new();
let scheduler = RealtimeScheduler::new(SchedulingPolicy::EarliestDeadlineFirst);
// Add historical successful conversation patterns
comparator.add_sequence(Sequence {
data: vec![
"greeting".to_string(),
"clarification".to_string(),
"action".to_string(),
"confirmation".to_string(),
],
timestamp: 1000,
id: "success_pattern".to_string(),
});
// Current conversation
let current_flow = vec!["greeting".to_string(), "clarification".to_string()];
// Check similarity to successful patterns
let similar = comparator.find_similar(&current_flow, 0.6, ComparisonAlgorithm::LCS);
if !similar.is_empty() {
// We found a similar successful pattern, schedule next actions accordingly
// Schedule the predicted next action (from pattern)
scheduler.schedule(
Action {
action_type: "action".to_string(),
description: "Execute predicted action from pattern".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: Some("confirmation".to_string()),
expected_reward: 0.8,
},
Priority::High,
Duration::from_millis(200),
Duration::from_millis(50),
).await;
// Schedule confirmation as follow-up
scheduler.schedule(
Action {
action_type: "confirmation".to_string(),
description: "Confirm action completion".to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: Some("success".to_string()),
expected_reward: 0.9,
},
Priority::Medium,
Duration::from_millis(500),
Duration::from_millis(30),
).await;
println!("Scheduled actions based on historical success pattern");
}
// Execute scheduled tasks
let mut executed_count = 0;
while let Some(task) = scheduler.next_task().await {
println!("Executing: {}", task.action.action_type);
scheduler.mark_executed(task.id, Duration::from_millis(10)).await;
executed_count += 1;
}
assert_eq!(executed_count, 2);
println!("Successfully completed conversation flow based on patterns");
}
+349
View File
@@ -0,0 +1,349 @@
//! WASM Integration Tests for MidStream System
//!
//! Tests WASM-specific functionality including:
//! - WebAssembly compilation and execution
//! - Browser compatibility
//! - Memory constraints
//! - Performance in WASM environments
//! - QUIC/WebTransport integration
#![cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
use std::collections::HashMap;
// WASM-specific imports
use midstreamer_temporal_compare::{TemporalComparator, Sequence, ComparisonAlgorithm};
use midstreamer_scheduler::{RealtimeScheduler, SchedulingPolicy, Priority};
use midstreamer_attractor::{AttractorAnalyzer, PhasePoint};
use midstreamer_neural_solver::{TemporalNeuralSolver, TemporalFormula, TemporalState, VerificationStrictness};
use midstreamer_strange_loop::{StrangeLoop, MetaLevel};
wasm_bindgen_test_configure!(run_in_browser);
/// Test 1: WASM Temporal Comparison
#[wasm_bindgen_test]
async fn test_wasm_temporal_comparison() {
console_log!("=== WASM Temporal Comparison Test ===");
let mut comparator = TemporalComparator::<String>::new(50, 500);
// Add sequences
comparator.add_sequence(Sequence {
data: vec!["a".to_string(), "b".to_string(), "c".to_string()],
timestamp: 1000,
id: "seq1".to_string(),
});
comparator.add_sequence(Sequence {
data: vec!["a".to_string(), "b".to_string(), "d".to_string()],
timestamp: 2000,
id: "seq2".to_string(),
});
// Find similar sequences
let query = vec!["a".to_string(), "b".to_string()];
let similar = comparator.find_similar(&query, 0.7, ComparisonAlgorithm::LCS);
console_log!("Found {} similar sequences in WASM", similar.len());
assert!(similar.len() >= 2);
console_log!("✓ WASM temporal comparison successful");
}
/// Test 2: WASM Scheduler
#[wasm_bindgen_test]
async fn test_wasm_scheduler() {
console_log!("=== WASM Scheduler Test ===");
let scheduler = RealtimeScheduler::new(SchedulingPolicy::FixedPriority);
// Schedule multiple tasks
for i in 0..10 {
scheduler.schedule(
create_action(&format!("wasm_task_{}", i), "WASM task"),
Priority::Medium,
std::time::Duration::from_secs(1),
std::time::Duration::from_millis(10),
).await;
}
let stats = scheduler.get_stats().await;
console_log!("Scheduled {} tasks in WASM", stats.total_scheduled);
assert_eq!(stats.total_scheduled, 10);
console_log!("✓ WASM scheduler successful");
}
/// Test 3: WASM Attractor Analysis
#[wasm_bindgen_test]
fn test_wasm_attractor_analysis() {
console_log!("=== WASM Attractor Analysis Test ===");
let mut analyzer = AttractorAnalyzer::new(2, 1000);
// Add points
for i in 0..150 {
let point = PhasePoint::new(
vec![
(i as f64 * 0.1).sin(),
(i as f64 * 0.1).cos(),
],
i as u64,
);
analyzer.add_point(point).unwrap();
}
let result = analyzer.analyze();
assert!(result.is_ok());
let info = result.unwrap();
console_log!("Detected attractor: {:?}", info.attractor_type);
console_log!("Confidence: {}", info.confidence);
console_log!("✓ WASM attractor analysis successful");
}
/// Test 4: WASM Temporal Logic Verification
#[wasm_bindgen_test]
fn test_wasm_temporal_verification() {
console_log!("=== WASM Temporal Verification Test ===");
let mut solver = TemporalNeuralSolver::new(1000, 500, VerificationStrictness::Medium);
// Create trace
for i in 0..10 {
let mut state = TemporalState::new(i, i * 100);
state.set_proposition("safe", true);
state.set_proposition("ready", i >= 5);
solver.add_state(state);
}
// Verify safety
let formula = TemporalFormula::globally(TemporalFormula::atom("safe"));
let result = solver.verify(&formula).unwrap();
console_log!("Safety verified: {}", result.satisfied);
assert!(result.satisfied);
console_log!("✓ WASM temporal verification successful");
}
/// Test 5: WASM Meta-Learning
#[wasm_bindgen_test]
fn test_wasm_meta_learning() {
console_log!("=== WASM Meta-Learning Test ===");
let mut strange_loop = StrangeLoop::default();
let data = vec![
"pattern1".to_string(),
"pattern2".to_string(),
"pattern1".to_string(),
];
let result = strange_loop.learn_at_level(MetaLevel::base(), &data);
assert!(result.is_ok());
let summary = strange_loop.get_summary();
console_log!("Learned {} patterns", summary.total_knowledge);
console_log!("✓ WASM meta-learning successful");
}
/// Test 6: WASM Memory Constraints
#[wasm_bindgen_test]
fn test_wasm_memory_limits() {
console_log!("=== WASM Memory Limits Test ===");
// Test with limited memory allocation
let comparator = TemporalComparator::<i32>::new(100, 1000); // Smaller limits for WASM
// Add moderate amount of data
for i in 0..50 {
let seq: Vec<i32> = (0..100).map(|x| x + i).collect();
comparator.add_sequence(Sequence {
data: seq,
timestamp: i as u64 * 1000,
id: format!("seq_{}", i),
});
}
console_log!("✓ WASM memory constraints handled");
}
/// Test 7: WASM Performance
#[wasm_bindgen_test]
fn test_wasm_performance() {
console_log!("=== WASM Performance Test ===");
use web_sys::window;
let window = window().expect("should have window");
let performance = window.performance().expect("should have performance");
let start = performance.now();
// Perform computations
let comparator = TemporalComparator::<i32>::new(100, 1000);
let seq1: Vec<i32> = (0..500).collect();
let seq2: Vec<i32> = (0..500).map(|x| x + 1).collect();
let _similarity = comparator.compare(&seq1, &seq2, ComparisonAlgorithm::LCS);
let duration = performance.now() - start;
console_log!("Comparison took {} ms in WASM", duration);
assert!(duration < 5000.0, "Should complete within 5 seconds");
console_log!("✓ WASM performance acceptable");
}
/// Test 8: WASM Concurrent Operations
#[wasm_bindgen_test]
async fn test_wasm_concurrent_ops() {
console_log!("=== WASM Concurrent Operations Test ===");
use wasm_bindgen_futures::spawn_local;
use std::sync::Arc;
use std::sync::atomic::{AtomicU32, Ordering};
let counter = Arc::new(AtomicU32::new(0));
// Spawn multiple concurrent tasks
let mut handles = vec![];
for i in 0..5 {
let counter_clone = counter.clone();
let future = async move {
let mut comparator = TemporalComparator::<i32>::new(10, 100);
let seq: Vec<i32> = (0..10).map(|x| x + i).collect();
comparator.add_sequence(Sequence {
data: seq,
timestamp: i as u64,
id: format!("concurrent_{}", i),
});
counter_clone.fetch_add(1, Ordering::SeqCst);
};
spawn_local(future);
}
// Wait a bit for tasks to complete
wasm_timer::Delay::new(std::time::Duration::from_millis(100)).await.ok();
let count = counter.load(Ordering::SeqCst);
console_log!("Completed {} concurrent operations", count);
console_log!("✓ WASM concurrent operations successful");
}
/// Test 9: WASM Error Handling
#[wasm_bindgen_test]
fn test_wasm_error_handling() {
console_log!("=== WASM Error Handling Test ===");
// Test dimension mismatch
let mut analyzer = AttractorAnalyzer::new(3, 100);
let invalid_point = PhasePoint::new(vec![1.0, 2.0], 0);
let result = analyzer.add_point(invalid_point);
assert!(result.is_err());
console_log!("✓ Dimension mismatch handled correctly");
// Test empty trace
let solver = TemporalNeuralSolver::default();
let formula = TemporalFormula::atom("test");
let result = solver.verify(&formula);
assert!(result.is_err());
console_log!("✓ Empty trace handled correctly");
console_log!("✓ WASM error handling successful");
}
/// Test 10: WASM Integration Workflow
#[wasm_bindgen_test]
async fn test_wasm_integration_workflow() {
console_log!("=== WASM Integration Workflow Test ===");
// Step 1: Pattern detection
let mut comparator = TemporalComparator::<String>::new(50, 500);
comparator.add_sequence(Sequence {
data: vec!["init".to_string(), "process".to_string(), "complete".to_string()],
timestamp: 1000,
id: "workflow".to_string(),
});
// Step 2: Schedule based on pattern
let scheduler = RealtimeScheduler::new(SchedulingPolicy::EarliestDeadlineFirst);
scheduler.schedule(
create_action("wasm_workflow", "Workflow task"),
Priority::High,
std::time::Duration::from_secs(1),
std::time::Duration::from_millis(50),
).await;
// Step 3: Verify behavior
let mut solver = TemporalNeuralSolver::default();
let mut state = TemporalState::new(1, 100);
state.set_proposition("completed", true);
solver.add_state(state);
let formula = TemporalFormula::atom("completed");
let result = solver.verify(&formula).unwrap();
console_log!("Workflow completed: {}", result.satisfied);
assert!(result.satisfied);
console_log!("✓ WASM integration workflow successful");
}
// Helper functions
fn create_action(action_type: &str, description: &str) -> nanosecond_scheduler::Action {
nanosecond_scheduler::Action {
action_type: action_type.to_string(),
description: description.to_string(),
parameters: HashMap::new(),
tool_calls: vec![],
expected_outcome: None,
expected_reward: 0.8,
}
}
#[macro_export]
macro_rules! console_log {
($($t:tt)*) => {
web_sys::console::log_1(&format!($($t)*).into());
}
}
#[cfg(test)]
mod wasm_summary {
use wasm_bindgen_test::*;
#[wasm_bindgen_test]
fn wasm_test_summary() {
console_log!("\n");
console_log!("╔═══════════════════════════════════════════════════════════════╗");
console_log!("║ MidStream WASM Integration Test Suite ║");
console_log!("╠═══════════════════════════════════════════════════════════════╣");
console_log!("║ ║");
console_log!("║ ✓ WASM Temporal Comparison ║");
console_log!("║ ✓ WASM Scheduler ║");
console_log!("║ ✓ WASM Attractor Analysis ║");
console_log!("║ ✓ WASM Temporal Verification ║");
console_log!("║ ✓ WASM Meta-Learning ║");
console_log!("║ ✓ WASM Memory Limits ║");
console_log!("║ ✓ WASM Performance ║");
console_log!("║ ✓ WASM Concurrent Operations ║");
console_log!("║ ✓ WASM Error Handling ║");
console_log!("║ ✓ WASM Integration Workflow ║");
console_log!("║ ║");
console_log!("╚═══════════════════════════════════════════════════════════════╝");
console_log!("\n");
}
}