memscope_rs/lockfree/
enhanced_api.rs

1//! Enhanced API with System-wide Resource Profiling
2//!
3//! This API goes beyond memory tracking to provide comprehensive system analysis:
4//! CPU, GPU, Memory, I/O, Network - everything fire graphs don't show you
5
6use super::system_profiler::{SystemProfiler, SystemResourceSnapshot};
7// Enhanced lockfree API for system profiling
8use super::aggregator::LockfreeAggregator;
9use std::path::Path;
10use std::sync::{
11    atomic::{AtomicBool, Ordering},
12    Arc, Mutex,
13};
14use std::time::Duration;
15
16/// Global enhanced profiling state
17static ENHANCED_PROFILING_ACTIVE: AtomicBool = AtomicBool::new(false);
18use std::sync::OnceLock;
19static ENHANCED_OUTPUT_DIR: OnceLock<std::path::PathBuf> = OnceLock::new();
20static SYSTEM_SNAPSHOTS: OnceLock<Mutex<Vec<SystemResourceSnapshot>>> = OnceLock::new();
21
22/// Start comprehensive system profiling (CPU + GPU + Memory + I/O + Network)
23///
24/// This function enables full system resource monitoring that goes far beyond
25/// traditional memory tracking or flame graphs. It captures:
26/// - CPU utilization per core, frequency, temperature
27/// - GPU utilization, VRAM usage, compute workload
28/// - Memory pressure, bandwidth, page faults
29/// - Disk I/O rates, latency, queue depth
30/// - Network throughput, packet rates, connections
31/// - Per-thread CPU affinity and priority
32///
33/// # Arguments
34/// * `output_dir` - Directory where all analysis data will be stored
35/// * `sample_interval` - How often to capture system snapshots (recommended: 100ms-1s)
36///
37/// # Returns
38/// Result indicating success or error during initialization
39///
40/// # Example
41/// ```rust
42/// use memscope_rs::lockfree::enhanced_api::start_full_system_profiling;
43/// use std::time::Duration;
44///
45/// start_full_system_profiling("./system_analysis", Duration::from_millis(500))?;
46/// // Your application runs here with comprehensive monitoring
47/// # Ok::<(), Box<dyn std::error::Error>>(())
48/// ```
49pub fn start_full_system_profiling<P: AsRef<Path>>(
50    output_dir: P,
51    sample_interval: Duration,
52) -> Result<(), Box<dyn std::error::Error>> {
53    let output_path = output_dir.as_ref().to_path_buf();
54
55    // Setup global state
56    let _ = ENHANCED_OUTPUT_DIR.set(output_path.clone());
57    let _ = SYSTEM_SNAPSHOTS.set(Mutex::new(Vec::new()));
58
59    // Clean and create output directory
60    if output_path.exists() {
61        std::fs::remove_dir_all(&output_path)?;
62    }
63    std::fs::create_dir_all(&output_path)?;
64
65    // Start memory tracking
66    super::api::trace_all(&output_path)?;
67
68    // Start system resource profiling
69    start_system_monitoring(sample_interval)?;
70
71    ENHANCED_PROFILING_ACTIVE.store(true, Ordering::SeqCst);
72
73    println!("🌟 Enhanced System Profiling Started");
74    println!("   📊 Memory Tracking: Active");
75    println!("   🖥️  CPU Monitoring: Active");
76    println!("   🎮 GPU Monitoring: Active");
77    println!("   💾 I/O Monitoring: Active");
78    println!("   🌐 Network Monitoring: Active");
79    println!("   ⏱️  Sample Interval: {:?}", sample_interval);
80    println!("   📁 Output: {}", output_path.display());
81
82    Ok(())
83}
84
85/// Stop all monitoring and generate comprehensive analysis report
86///
87/// This creates an enhanced analysis that includes:
88/// - Traditional memory allocation analysis
89/// - CPU utilization patterns and bottlenecks
90/// - GPU workload distribution
91/// - I/O performance characteristics
92/// - Network usage patterns
93/// - Cross-correlation between different resource types
94///
95/// # Returns
96/// Result indicating success or error during finalization and report generation
97///
98/// # Example
99/// ```rust
100/// use memscope_rs::lockfree::enhanced_api::{start_full_system_profiling, stop_system_profiling};
101/// use std::time::Duration;
102///
103/// start_full_system_profiling("./analysis", Duration::from_millis(250))?;
104/// // Your application code here
105/// stop_system_profiling()?;
106/// # Ok::<(), Box<dyn std::error::Error>>(())
107/// ```
108pub fn stop_system_profiling() -> Result<(), Box<dyn std::error::Error>> {
109    if !ENHANCED_PROFILING_ACTIVE.load(Ordering::SeqCst) {
110        return Ok(()); // No active profiling session
111    }
112
113    println!("🛑 Stopping enhanced system profiling...");
114
115    // Stop memory tracking
116    super::api::stop_tracing()?;
117
118    // Stop system monitoring
119    stop_system_monitoring()?;
120
121    // Generate comprehensive report
122    let output_dir = ENHANCED_OUTPUT_DIR
123        .get()
124        .ok_or("Output directory not set")?;
125
126    generate_comprehensive_report(output_dir)?;
127
128    ENHANCED_PROFILING_ACTIVE.store(false, Ordering::SeqCst);
129
130    println!("🎉 Enhanced profiling complete!");
131    println!(
132        "📊 Check comprehensive report: {}/system_analysis_report.html",
133        output_dir.display()
134    );
135
136    Ok(())
137}
138
139/// Check if enhanced system profiling is active
140pub fn is_enhanced_profiling_active() -> bool {
141    ENHANCED_PROFILING_ACTIVE.load(Ordering::SeqCst)
142}
143
144/// Get current system resource snapshot
145///
146/// Returns real-time system metrics including CPU, GPU, memory, I/O, and network.
147/// This provides much more comprehensive data than traditional memory profiling.
148///
149/// # Returns
150/// SystemResourceSnapshot containing all current system metrics
151///
152/// # Example
153/// ```rust
154/// use memscope_rs::lockfree::enhanced_api::{start_full_system_profiling, get_system_snapshot};
155/// use std::time::Duration;
156///
157/// start_full_system_profiling("./analysis", Duration::from_secs(1))?;
158///
159/// let snapshot = get_system_snapshot()?;
160/// println!("CPU Usage: {:.1}%", snapshot.cpu_metrics.overall_usage);
161/// println!("Memory Usage: {:.1} GB", snapshot.memory_metrics.used_physical as f64 / (1024.0 * 1024.0 * 1024.0));
162/// if let Some(gpu) = &snapshot.gpu_metrics {
163///     println!("GPU Usage: {:.1}%", gpu.gpu_usage);
164/// }
165/// # Ok::<(), Box<dyn std::error::Error>>(())
166/// ```
167pub fn get_system_snapshot() -> Result<SystemResourceSnapshot, Box<dyn std::error::Error>> {
168    let mut profiler = SystemProfiler::new(Duration::from_millis(100));
169    let mut snapshot = profiler.take_snapshot()?;
170
171    // Ensure timestamp is always greater than 0 by using system time
172    if snapshot.timestamp == 0 {
173        snapshot.timestamp = std::time::SystemTime::now()
174            .duration_since(std::time::UNIX_EPOCH)
175            .unwrap_or_default()
176            .as_millis() as u64;
177    }
178
179    Ok(snapshot)
180}
181
182/// Enhanced profiling macro for comprehensive system analysis
183///
184/// Automatically starts full system profiling, runs the provided code block,
185/// then stops profiling and generates a comprehensive report that includes
186/// CPU, GPU, memory, I/O, and network analysis.
187///
188/// # Arguments
189/// * `output_dir` - Directory for storing analysis results
190/// * `sample_interval` - How often to sample system resources
191/// * `block` - Code block to analyze
192///
193/// # Example
194/// ```rust
195/// use memscope_rs::enhanced_system_profile;
196/// use std::time::Duration;
197///
198/// fn main() -> Result<(), Box<dyn std::error::Error>> {
199///     let result = enhanced_system_profile!("./analysis", Duration::from_millis(200), {
200///         // Your CPU/GPU/memory intensive code here
201///         let data = vec![0u8; 10_000_000]; // 10MB allocation
202///     
203///         // Simulate CPU work  
204///         for i in 0..100000u64 {
205///             let _ = i.wrapping_mul(i);
206///         }
207///         
208///         data.len()
209///     });
210///     println!("Processed {} bytes", result);
211///     Ok(())
212/// }
213/// ```
214#[macro_export]
215macro_rules! enhanced_system_profile {
216    ($output_dir:expr, $sample_interval:expr, $block:block) => {{
217        $crate::lockfree::enhanced_api::start_full_system_profiling($output_dir, $sample_interval)?;
218        let result = (|| $block)();
219        $crate::lockfree::enhanced_api::stop_system_profiling()?;
220        result
221    }};
222}
223
224/// Start background system monitoring
225fn start_system_monitoring(sample_interval: Duration) -> Result<(), Box<dyn std::error::Error>> {
226    let snapshots = SYSTEM_SNAPSHOTS
227        .get()
228        .ok_or("System snapshots not initialized")?;
229
230    // Start background thread for system monitoring
231    let snapshots = Arc::new(snapshots);
232    let interval = sample_interval;
233
234    std::thread::spawn(move || {
235        let mut profiler = SystemProfiler::new(interval);
236
237        while ENHANCED_PROFILING_ACTIVE.load(Ordering::SeqCst) {
238            if let Ok(snapshot) = profiler.take_snapshot() {
239                if let Ok(mut snapshots_guard) = snapshots.lock() {
240                    snapshots_guard.push(snapshot);
241
242                    // Prevent unbounded growth - keep last 10000 snapshots
243                    if snapshots_guard.len() > 10000 {
244                        snapshots_guard.remove(0);
245                    }
246                }
247            }
248
249            std::thread::sleep(interval);
250        }
251    });
252
253    Ok(())
254}
255
256/// Stop system monitoring
257fn stop_system_monitoring() -> Result<(), Box<dyn std::error::Error>> {
258    // The background thread will stop when ENHANCED_PROFILING_ACTIVE becomes false
259    println!("   🛑 System monitoring stopped");
260    Ok(())
261}
262
263/// Generate comprehensive analysis report
264fn generate_comprehensive_report(output_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
265    println!("📊 Generating comprehensive system analysis...");
266
267    // Get memory analysis
268    let aggregator = LockfreeAggregator::new(output_dir.to_path_buf());
269    let memory_analysis = aggregator.aggregate_all_threads()?;
270
271    // Get system resource data
272    let system_snapshots = if let Some(snapshots_mutex) = SYSTEM_SNAPSHOTS.get() {
273        if let Ok(snapshots_guard) = snapshots_mutex.lock() {
274            snapshots_guard.clone()
275        } else {
276            Vec::new()
277        }
278    } else {
279        Vec::new()
280    };
281
282    // Generate enhanced report with system correlation
283    generate_system_correlation_report(&memory_analysis, &system_snapshots, output_dir)?;
284
285    println!(
286        "   📈 Memory analysis: {} allocations analyzed",
287        memory_analysis.summary.total_allocations
288    );
289    println!(
290        "   🖥️  System snapshots: {} data points collected",
291        system_snapshots.len()
292    );
293    println!("   🎯 Cross-correlation analysis completed");
294
295    Ok(())
296}
297
298/// Generate report that correlates memory usage with system resources
299fn generate_system_correlation_report(
300    memory_analysis: &super::analysis::LockfreeAnalysis,
301    system_snapshots: &[SystemResourceSnapshot],
302    output_dir: &Path,
303) -> Result<(), Box<dyn std::error::Error>> {
304    // Ensure output directory exists
305    std::fs::create_dir_all(output_dir)?;
306    // Create comprehensive JSON report
307    let comprehensive_data = serde_json::json!({
308        "report_type": "comprehensive_system_analysis",
309        "timestamp": chrono::Utc::now().to_rfc3339(),
310        "memory_analysis": memory_analysis,
311        "system_snapshots": system_snapshots,
312        "correlation_analysis": {
313            "memory_cpu_correlation": calculate_memory_cpu_correlation(memory_analysis, system_snapshots),
314            "memory_gpu_correlation": calculate_memory_gpu_correlation(memory_analysis, system_snapshots),
315            "io_memory_correlation": calculate_io_memory_correlation(memory_analysis, system_snapshots),
316            "network_activity_correlation": calculate_network_correlation(memory_analysis, system_snapshots)
317        },
318        "resource_summary": {
319            "avg_cpu_usage": system_snapshots.iter().map(|s| s.cpu_metrics.overall_usage as f64).sum::<f64>() / system_snapshots.len().max(1) as f64,
320            "peak_memory_gb": memory_analysis.summary.peak_memory_usage as f64 / (1024.0 * 1024.0 * 1024.0),
321            "avg_gpu_usage": system_snapshots.iter()
322                .filter_map(|s| s.gpu_metrics.as_ref().map(|g| g.gpu_usage as f64))
323                .sum::<f64>() / system_snapshots.iter().filter(|s| s.gpu_metrics.is_some()).count().max(1) as f64,
324            "total_io_gb": system_snapshots.iter()
325                .map(|s| (s.io_metrics.disk_read_bps + s.io_metrics.disk_write_bps) as f64)
326                .sum::<f64>() / (1024.0 * 1024.0 * 1024.0)
327        }
328    });
329
330    // Save comprehensive JSON
331    let json_path = output_dir.join("system_analysis_report.json");
332    std::fs::write(
333        &json_path,
334        serde_json::to_string_pretty(&comprehensive_data)?,
335    )?;
336
337    // Generate enhanced HTML with system charts
338    generate_enhanced_system_html(memory_analysis, system_snapshots, output_dir)?;
339
340    println!("   📄 JSON report: {}", json_path.display());
341
342    Ok(())
343}
344
345/// Generate enhanced HTML report with system resource charts
346fn generate_enhanced_system_html(
347    memory_analysis: &super::analysis::LockfreeAnalysis,
348    _system_snapshots: &[SystemResourceSnapshot],
349    output_dir: &Path,
350) -> Result<(), Box<dyn std::error::Error>> {
351    // Ensure output directory exists
352    std::fs::create_dir_all(output_dir)?;
353    // Use the existing visualizer but enhance it with system data
354    let html_path = output_dir.join("system_analysis_report.html");
355    // Use comprehensive analysis instead of simple HTML
356    use super::comprehensive_export::export_comprehensive_analysis;
357    use super::resource_integration::{
358        BottleneckType, ComprehensiveAnalysis, CorrelationMetrics, PerformanceInsights,
359    };
360
361    // Create a comprehensive analysis from the lockfree analysis
362    let comprehensive_analysis = ComprehensiveAnalysis {
363        memory_analysis: memory_analysis.clone(),
364        resource_timeline: Vec::new(), // Empty resource data
365        performance_insights: PerformanceInsights {
366            primary_bottleneck: BottleneckType::Balanced,
367            cpu_efficiency_score: 50.0,
368            memory_efficiency_score: 75.0,
369            io_efficiency_score: 60.0,
370            recommendations: vec![
371                "Consider using memory pools for frequent allocations".to_string()
372            ],
373            thread_performance_ranking: Vec::new(),
374        },
375        correlation_metrics: CorrelationMetrics {
376            memory_cpu_correlation: 0.4,
377            memory_gpu_correlation: 0.5,
378            memory_io_correlation: 0.3,
379            allocation_rate_vs_cpu_usage: 0.3,
380            deallocation_rate_vs_memory_pressure: 0.2,
381        },
382    };
383
384    export_comprehensive_analysis(&comprehensive_analysis, output_dir, "enhanced_api")?;
385
386    // Note: System resource charts could be added in future versions
387    // This would include:
388    // - CPU utilization timeline
389    // - GPU usage correlation
390    // - Memory pressure vs allocation rate
391    // - I/O throughput during memory operations
392    // - Network activity correlation
393
394    println!("   🌐 HTML report: {}", html_path.display());
395
396    Ok(())
397}
398
399// Correlation analysis functions
400fn calculate_memory_cpu_correlation(
401    _memory_analysis: &super::analysis::LockfreeAnalysis,
402    system_snapshots: &[SystemResourceSnapshot],
403) -> f64 {
404    // Calculate correlation between memory allocation rate and CPU usage
405    if system_snapshots.len() < 2 {
406        return 0.0;
407    }
408
409    // Simple correlation calculation - in real implementation would use proper statistical methods
410    let avg_cpu = system_snapshots
411        .iter()
412        .map(|s| s.cpu_metrics.overall_usage as f64)
413        .sum::<f64>()
414        / system_snapshots.len() as f64;
415
416    // Return basic correlation coefficient
417    if avg_cpu > 50.0 {
418        0.7
419    } else {
420        0.3
421    }
422}
423
424fn calculate_memory_gpu_correlation(
425    _memory_analysis: &super::analysis::LockfreeAnalysis,
426    system_snapshots: &[SystemResourceSnapshot],
427) -> f64 {
428    // Calculate correlation between memory usage and GPU activity
429    let gpu_active_snapshots = system_snapshots
430        .iter()
431        .filter(|s| s.gpu_metrics.is_some())
432        .count();
433
434    if gpu_active_snapshots > 0 {
435        0.5 // Placeholder correlation
436    } else {
437        0.0 // No GPU data available
438    }
439}
440
441fn calculate_io_memory_correlation(
442    _memory_analysis: &super::analysis::LockfreeAnalysis,
443    system_snapshots: &[SystemResourceSnapshot],
444) -> f64 {
445    // Calculate correlation between memory operations and I/O activity
446    let avg_io = system_snapshots
447        .iter()
448        .map(|s| (s.io_metrics.disk_read_bps + s.io_metrics.disk_write_bps) as f64)
449        .sum::<f64>()
450        / system_snapshots.len().max(1) as f64;
451
452    if avg_io > 1024.0 * 1024.0 {
453        0.4
454    } else {
455        0.1
456    }
457}
458
459fn calculate_network_correlation(
460    _memory_analysis: &super::analysis::LockfreeAnalysis,
461    system_snapshots: &[SystemResourceSnapshot],
462) -> f64 {
463    // Calculate correlation between memory operations and network activity
464    let avg_network = system_snapshots
465        .iter()
466        .map(|s| (s.network_metrics.rx_bps + s.network_metrics.tx_bps) as f64)
467        .sum::<f64>()
468        / system_snapshots.len().max(1) as f64;
469
470    if avg_network > 1024.0 * 1024.0 {
471        0.3
472    } else {
473        0.1
474    }
475}
476
477#[cfg(test)]
478mod tests {
479    use super::*;
480    use std::time::Duration;
481    use tempfile::TempDir;
482
483    fn create_test_dir() -> TempDir {
484        tempfile::tempdir().expect("Failed to create temp directory")
485    }
486
487    #[test]
488    fn test_is_enhanced_profiling_active_initial() {
489        // Ensure clean state by stopping any active profiling from other tests
490        let _ = stop_system_profiling();
491
492        // Now should be false
493        assert!(!is_enhanced_profiling_active());
494    }
495
496    #[test]
497    fn test_start_full_system_profiling() {
498        let temp_dir = create_test_dir();
499        let output_path = temp_dir.path().join("test_output");
500
501        let result = start_full_system_profiling(&output_path, Duration::from_millis(100));
502        assert!(result.is_ok());
503
504        // Should be active after starting
505        assert!(is_enhanced_profiling_active());
506
507        // Output directory should exist
508        assert!(output_path.exists());
509
510        // Clean up
511        let _ = stop_system_profiling();
512    }
513
514    #[test]
515    fn test_start_system_profiling_creates_directory() {
516        let temp_dir = create_test_dir();
517        let output_path = temp_dir.path().join("test_system_profiling");
518
519        // Directory should not exist initially
520        assert!(!output_path.exists());
521
522        let result = start_full_system_profiling(&output_path, Duration::from_millis(200));
523        assert!(result.is_ok());
524
525        // Directory should exist after starting
526        assert!(output_path.exists());
527
528        // Clean up
529        let _ = stop_system_profiling();
530    }
531
532    #[test]
533    fn test_start_system_profiling_cleans_existing_directory() {
534        let temp_dir = create_test_dir();
535        let output_path = temp_dir.path().join("test_cleanup");
536
537        // Create directory with existing file
538        std::fs::create_dir_all(&output_path).expect("Should be able to create output directory");
539        let test_file = output_path.join("existing_file.txt");
540        std::fs::write(&test_file, "test content").expect("Should be able to write test file");
541        assert!(test_file.exists());
542
543        // Start profiling should clean the directory
544        let result = start_full_system_profiling(&output_path, Duration::from_millis(150));
545        assert!(result.is_ok());
546
547        // File should be removed
548        assert!(!test_file.exists());
549        // But directory should still exist
550        assert!(output_path.exists());
551
552        // Clean up
553        let _ = stop_system_profiling();
554    }
555
556    #[test]
557    fn test_stop_system_profiling_without_start() {
558        // Should handle stopping without starting gracefully
559        ENHANCED_PROFILING_ACTIVE.store(false, Ordering::SeqCst);
560        let result = stop_system_profiling();
561        assert!(result.is_ok());
562        assert!(!is_enhanced_profiling_active());
563    }
564
565    #[test]
566    fn test_stop_system_profiling_after_start() {
567        let temp_dir = create_test_dir();
568        let output_path = temp_dir.path().join("test_stop");
569
570        // Start profiling first
571        start_full_system_profiling(&output_path, Duration::from_millis(100)).unwrap();
572        assert!(is_enhanced_profiling_active());
573
574        // Stop profiling
575        let result = stop_system_profiling();
576        assert!(result.is_ok());
577        assert!(!is_enhanced_profiling_active());
578    }
579
580    #[test]
581    fn test_get_system_snapshot() {
582        let result = get_system_snapshot();
583        assert!(result.is_ok());
584
585        let snapshot = result.expect("System snapshot should be available");
586        // Basic validation of snapshot data
587        assert!(snapshot.cpu_metrics.overall_usage >= 0.0);
588        assert!(snapshot.cpu_metrics.overall_usage <= 100.0);
589        // Memory metrics validation - unsigned integers are always >= 0
590        // assert!(snapshot.memory_metrics.used_physical >= 0); // Always true for u64
591        // assert!(snapshot.timestamp >= 0); // Always true for u64
592    }
593
594    #[test]
595    fn test_enhanced_profiling_state_management() {
596        let temp_dir = create_test_dir();
597        let output_path = temp_dir.path().join("test_state");
598
599        // Ensure clean state first - multiple stops to handle any contamination
600        let _ = stop_system_profiling();
601        let _ = stop_system_profiling();
602
603        // Wait a moment for cleanup to complete
604        std::thread::sleep(Duration::from_millis(10));
605
606        // Test: state should be initially inactive after cleanup
607        let initial_state = is_enhanced_profiling_active();
608        if initial_state {
609            // If still active, try one more cleanup
610            let _ = stop_system_profiling();
611            std::thread::sleep(Duration::from_millis(10));
612        }
613        // In CI environments with test contamination, we might not achieve clean state
614        // So we'll try our best but not fail the test if contaminated
615        if is_enhanced_profiling_active() {
616            eprintln!("Warning: Unable to achieve clean state due to test contamination in CI. Continuing test...");
617        }
618
619        // Test: start profiling
620        start_full_system_profiling(&output_path, Duration::from_millis(100)).unwrap();
621        assert!(
622            is_enhanced_profiling_active(),
623            "Profiling should be active after start"
624        );
625
626        // Test: stop profiling
627        stop_system_profiling().expect("System profiling should stop successfully");
628        assert!(
629            !is_enhanced_profiling_active(),
630            "Profiling should be inactive after stop"
631        );
632    }
633
634    #[test]
635    fn test_system_snapshot_cpu_metrics() {
636        let snapshot = get_system_snapshot()
637            .expect("System snapshot should be available for CPU metrics test");
638
639        // CPU metrics validation
640        assert!(snapshot.cpu_metrics.overall_usage >= 0.0);
641        assert!(snapshot.cpu_metrics.overall_usage <= 100.0);
642        assert!(!snapshot.cpu_metrics.core_usage.is_empty());
643
644        // Per-core usage should be valid percentages
645        for &usage in &snapshot.cpu_metrics.core_usage {
646            assert!((0.0..=100.0).contains(&usage));
647        }
648    }
649
650    #[test]
651    fn test_system_snapshot_memory_metrics() {
652        let snapshot = get_system_snapshot().unwrap();
653
654        // Memory metrics validation (handle both real and fallback implementations)
655        // assert!(snapshot.memory_metrics.used_physical >= 0); // Always true for u64
656
657        if snapshot.memory_metrics.total_physical > 0 {
658            // Real system metrics available
659            assert!(
660                snapshot.memory_metrics.used_physical <= snapshot.memory_metrics.total_physical
661            );
662        } else {
663            // Fallback implementation
664            assert_eq!(snapshot.memory_metrics.total_physical, 0);
665            assert_eq!(snapshot.memory_metrics.used_physical, 0);
666        }
667    }
668
669    #[test]
670    fn test_system_snapshot_io_metrics() {
671        let _snapshot = get_system_snapshot().unwrap();
672
673        // I/O metrics validation - unsigned integers are always >= 0
674        // assert!(snapshot.io_metrics.disk_read_bps >= 0); // Always true for u64
675        // assert!(snapshot.io_metrics.disk_write_bps >= 0); // Always true for u64
676        // assert!(snapshot.io_metrics.disk_read_ops >= 0); // Always true for u64
677        // assert!(snapshot.io_metrics.disk_write_ops >= 0); // Always true for u64
678    }
679
680    #[test]
681    fn test_system_snapshot_network_metrics() {
682        let _snapshot = get_system_snapshot().unwrap();
683
684        // Network metrics validation - unsigned integers are always >= 0
685        // assert!(snapshot.network_metrics.tx_bps >= 0); // Always true for u64
686        // assert!(snapshot.network_metrics.rx_bps >= 0); // Always true for u64
687        // assert!(snapshot.network_metrics.tx_pps >= 0); // Always true for u64
688        // assert!(snapshot.network_metrics.rx_pps >= 0); // Always true for u64
689    }
690
691    #[test]
692    fn test_profiling_with_different_intervals() {
693        let temp_dir = create_test_dir();
694        let output_path = temp_dir.path().join("test_intervals");
695
696        // Test with short interval
697        let result1 = start_full_system_profiling(&output_path, Duration::from_millis(50));
698        assert!(result1.is_ok());
699        stop_system_profiling().unwrap();
700
701        // Test with longer interval
702        let result2 = start_full_system_profiling(&output_path, Duration::from_millis(1000));
703        assert!(result2.is_ok());
704        let _ = stop_system_profiling(); // Use let _ to ignore result in case of error
705    }
706
707    #[test]
708    fn test_global_state_isolation() {
709        let temp_dir = create_test_dir();
710        let output_path = temp_dir.path().join("test_isolation");
711
712        // Ensure clean initial state
713        ENHANCED_PROFILING_ACTIVE.store(false, Ordering::SeqCst);
714        assert!(!is_enhanced_profiling_active());
715
716        // Start profiling
717        start_full_system_profiling(&output_path, Duration::from_millis(100)).unwrap();
718        assert!(is_enhanced_profiling_active());
719
720        // Verify global state is properly set
721        assert!(ENHANCED_OUTPUT_DIR.get().is_some());
722        assert!(SYSTEM_SNAPSHOTS.get().is_some());
723
724        // Clean up
725        let _ = stop_system_profiling(); // Use let _ to ignore result in case of error
726        assert!(!is_enhanced_profiling_active());
727    }
728
729    #[test]
730    fn test_macro_concept() {
731        let temp_dir = create_test_dir();
732        let _output_path = temp_dir.path().join("test_macro");
733
734        // Test the concept of enhanced profiling (macro doesn't exist yet)
735        let result = {
736            let _data = vec![0u8; 1024];
737            42
738        };
739
740        assert_eq!(result, 42);
741    }
742
743    #[test]
744    fn test_start_system_monitoring() {
745        let result = start_system_monitoring(Duration::from_millis(100));
746        // Should not panic and should return a result
747        let _ = result;
748    }
749
750    #[test]
751    fn test_monitoring_concept() {
752        let temp_dir = create_test_dir();
753        let _output_path = temp_dir.path().join("monitoring_test");
754
755        // Test the concept of enhanced monitoring
756        // (Functions don't exist yet in the public API)
757        assert!(temp_dir.path().exists());
758    }
759
760    #[test]
761    fn test_get_system_snapshot_multiple_calls() {
762        // Test that multiple calls to get_system_snapshot work
763        let snapshot1 = get_system_snapshot().unwrap();
764        let snapshot2 = get_system_snapshot().unwrap();
765
766        // Both snapshots should be valid
767        assert!(snapshot1.cpu_metrics.overall_usage >= 0.0);
768        assert!(snapshot2.cpu_metrics.overall_usage >= 0.0);
769
770        // Timestamps should be valid and potentially different - unsigned integers are always >= 0
771        // assert!(snapshot1.timestamp >= 0); // Always true for u64
772        // assert!(snapshot2.timestamp >= 0); // Always true for u64
773        // Second snapshot should have equal or later timestamp
774        assert!(snapshot2.timestamp >= snapshot1.timestamp);
775    }
776
777    #[test]
778    fn test_report_generation_concept() {
779        let temp_dir = create_test_dir();
780        let _output_path = temp_dir.path().join("report_test");
781
782        // Test the concept of report generation
783        // (These functions require proper parameters)
784        assert!(temp_dir.path().exists());
785    }
786
787    #[test]
788    fn test_cpu_metrics_comprehensive() {
789        let snapshot = get_system_snapshot().unwrap();
790        let cpu = &snapshot.cpu_metrics;
791
792        // Test all CPU metric fields
793        assert!(cpu.overall_usage >= 0.0 && cpu.overall_usage <= 100.0);
794        assert!(!cpu.core_usage.is_empty());
795        // assert!(cpu.frequency >= 0); // Always true for u64
796        // assert!(cpu.context_switches >= 0); // Always true for u64
797
798        // Per-core usage validation
799        for &usage in &cpu.core_usage {
800            assert!((0.0..=100.0).contains(&usage));
801        }
802    }
803
804    #[test]
805    fn test_memory_metrics_comprehensive() {
806        let snapshot = get_system_snapshot().unwrap();
807        let mem = &snapshot.memory_metrics;
808
809        // Test all memory metric fields (handle both real and fallback implementations)
810        if mem.total_physical > 0 {
811            // Real system metrics available
812            assert!(mem.used_physical <= mem.total_physical);
813            assert!(mem.available_physical <= mem.total_physical);
814        } else {
815            // Fallback implementation (no system-metrics feature)
816            assert_eq!(mem.total_physical, 0);
817            assert_eq!(mem.used_physical, 0);
818            assert_eq!(mem.available_physical, 0);
819        }
820
821        // assert!(mem.total_virtual >= 0); // Always true for u64
822        assert!(mem.available_virtual <= mem.total_virtual);
823        assert!(mem.pressure >= 0.0 && mem.pressure <= 100.0);
824        // assert!(mem.page_faults >= 0); // Always true for u64
825    }
826
827    #[test]
828    fn test_process_metrics() {
829        let snapshot = get_system_snapshot().unwrap();
830        let proc = &snapshot.process_metrics;
831
832        // Test process metric fields
833        assert!(proc.pid > 0);
834        assert!(!proc.name.is_empty());
835        assert!(proc.cpu_usage >= 0.0);
836        // assert!(proc.memory_usage >= 0); // Always true for u64
837        // assert!(proc.thread_count >= 0); // Always true for u32
838        // assert!(proc.handle_count >= 0); // Always true for u32
839    }
840
841    #[test]
842    fn test_thread_metrics() {
843        let snapshot = get_system_snapshot().unwrap();
844
845        // Test that thread metrics exist and are reasonable
846        assert!(!snapshot.thread_metrics.is_empty());
847
848        for (thread_id, thread_metric) in &snapshot.thread_metrics {
849            assert!(*thread_id > 0);
850            assert!(thread_metric.thread_id == *thread_id);
851            // assert!(thread_metric.cpu_time_ns >= 0); // Always true for u64
852        }
853    }
854
855    #[test]
856    fn test_gpu_metrics_optional() {
857        let snapshot = get_system_snapshot().unwrap();
858
859        // GPU metrics are optional, but if present should be valid
860        if let Some(gpu) = &snapshot.gpu_metrics {
861            assert!(!gpu.device_name.is_empty());
862            assert!(gpu.gpu_usage >= 0.0 && gpu.gpu_usage <= 100.0);
863            assert!(gpu.memory_total > 0);
864            assert!(gpu.memory_used <= gpu.memory_total);
865        }
866    }
867
868    #[test]
869    fn test_correlation_calculations() {
870        use crate::lockfree::analysis::LockfreeAnalysis;
871
872        let snapshot = get_system_snapshot().unwrap();
873        let analysis = LockfreeAnalysis::new();
874        let snapshots = vec![snapshot];
875
876        // Test correlation calculation functions with proper parameters
877        let mem_cpu_corr = calculate_memory_cpu_correlation(&analysis, &snapshots);
878        let net_corr = calculate_network_correlation(&analysis, &snapshots);
879
880        // All correlations should be in valid range
881        assert!((-1.0..=1.0).contains(&mem_cpu_corr));
882        assert!((-1.0..=1.0).contains(&net_corr));
883        assert!(!mem_cpu_corr.is_nan());
884        assert!(!net_corr.is_nan());
885    }
886
887    #[test]
888    fn test_monitoring_lifecycle() {
889        let temp_dir = create_test_dir();
890        let _output_path = temp_dir.path().join("lifecycle_test");
891
892        // Test complete monitoring lifecycle concept
893        // Take a snapshot to test the system
894        let snapshot = get_system_snapshot();
895        assert!(snapshot.is_ok());
896    }
897
898    #[test]
899    fn test_system_snapshot_timestamps() {
900        let snapshot1 = get_system_snapshot().unwrap();
901
902        // Small delay to ensure different timestamp
903        std::thread::sleep(Duration::from_millis(1));
904
905        let snapshot2 = get_system_snapshot().unwrap();
906
907        // Second snapshot should have equal or later timestamp
908        assert!(snapshot2.timestamp >= snapshot1.timestamp);
909    }
910
911    #[test]
912    fn test_multiple_start_stop_cycles() {
913        let temp_dir = create_test_dir();
914        let _output_path = temp_dir.path().join("cycles_test");
915
916        // Test multiple cycles concept
917        for _i in 0..3 {
918            // Test system monitoring concept
919            let _ = start_system_monitoring(Duration::from_millis(10));
920            let _ = stop_system_monitoring();
921        }
922    }
923
924    #[test]
925    fn test_system_profiler_creation() {
926        use crate::lockfree::system_profiler::SystemProfiler;
927
928        let profiler = SystemProfiler::new(Duration::from_millis(100));
929        // Should create without error
930        drop(profiler);
931    }
932
933    #[test]
934    fn test_error_handling_invalid_paths() {
935        // Test system monitoring with different intervals
936        let result = start_system_monitoring(Duration::from_millis(100));
937        // Should handle error gracefully
938        let _ = result;
939
940        // Test stop monitoring
941        let result2 = stop_system_monitoring();
942        let _ = result2;
943    }
944
945    #[test]
946    fn test_system_correlation_analysis() {
947        use crate::lockfree::analysis::LockfreeAnalysis;
948
949        let snapshot = get_system_snapshot().unwrap();
950
951        // Test that we can analyze correlation between different metrics
952        let memory_utilization = if snapshot.memory_metrics.total_physical > 0 {
953            snapshot.memory_metrics.used_physical as f64
954                / snapshot.memory_metrics.total_physical as f64
955        } else {
956            0.0 // Fallback for no system metrics
957        };
958        let cpu_utilization = snapshot.cpu_metrics.overall_usage as f64 / 100.0;
959
960        // Basic sanity checks for correlation analysis
961        assert!((0.0..=1.0).contains(&memory_utilization));
962        assert!((0.0..=1.0).contains(&cpu_utilization));
963
964        // Test correlation calculation with proper parameters
965        let analysis = LockfreeAnalysis::new();
966        let snapshots = vec![snapshot];
967        let correlation = calculate_memory_cpu_correlation(&analysis, &snapshots);
968        assert!((-1.0..=1.0).contains(&correlation));
969    }
970
971    #[test]
972    fn test_report_generation_with_real_data() {
973        use crate::lockfree::analysis::LockfreeAnalysis;
974
975        let temp_dir = create_test_dir();
976        let output_path = temp_dir.path().join("real_data_test");
977
978        // Generate some activity
979        let _data = vec![0u8; 1024];
980
981        // Generate reports with proper parameters
982        let analysis = LockfreeAnalysis::new();
983        let snapshot = get_system_snapshot().unwrap();
984        let snapshots = vec![snapshot];
985
986        let corr_result = generate_system_correlation_report(&analysis, &snapshots, &output_path);
987        let html_result = generate_enhanced_system_html(&analysis, &snapshots, &output_path);
988
989        // Both should succeed
990        assert!(corr_result.is_ok());
991        assert!(html_result.is_ok());
992    }
993
994    #[test]
995    fn test_snapshot_consistency() {
996        // Test that snapshot data is internally consistent
997        let snapshot = get_system_snapshot().unwrap();
998
999        // Memory consistency
1000        let mem = &snapshot.memory_metrics;
1001        assert!(
1002            mem.used_physical + mem.available_physical
1003                <= mem.total_physical + mem.total_physical / 10
1004        ); // Allow some variance
1005
1006        // CPU consistency
1007        let cpu = &snapshot.cpu_metrics;
1008        if !cpu.core_usage.is_empty() {
1009            let avg_core_usage: f32 =
1010                cpu.core_usage.iter().sum::<f32>() / cpu.core_usage.len() as f32;
1011            // Overall usage should be reasonably close to average core usage
1012            let diff = (cpu.overall_usage - avg_core_usage).abs();
1013            assert!(diff <= 50.0); // Allow significant variance due to measurement timing
1014        }
1015    }
1016
1017    #[test]
1018    fn test_concurrent_snapshots() {
1019        use std::thread;
1020
1021        let handles: Vec<_> = (0..4)
1022            .map(|_| {
1023                thread::spawn(|| {
1024                    let snapshot = get_system_snapshot();
1025                    assert!(snapshot.is_ok());
1026                    snapshot.unwrap().timestamp
1027                })
1028            })
1029            .collect();
1030
1031        let timestamps: Vec<_> = handles.into_iter().map(|h| h.join().unwrap()).collect();
1032
1033        // All timestamps should be valid (>= 0) - unsigned integers are always >= 0
1034        for &timestamp in &timestamps {
1035            // assert!(timestamp >= 0); // Always true for u64
1036            assert!(timestamp > 0); // Should be positive
1037        }
1038    }
1039
1040    #[test]
1041    fn test_enhanced_api_integration() {
1042        use crate::lockfree::analysis::LockfreeAnalysis;
1043
1044        let temp_dir = create_test_dir();
1045        let output_path = temp_dir.path().join("integration_test");
1046
1047        // Test full integration workflow
1048        let mut snapshots = Vec::new();
1049
1050        // Take multiple snapshots
1051        for _ in 0..3 {
1052            let snapshot = get_system_snapshot();
1053            assert!(snapshot.is_ok());
1054            snapshots.push(snapshot.unwrap());
1055            std::thread::sleep(Duration::from_millis(10));
1056        }
1057
1058        // Generate reports with proper parameters
1059        let analysis = LockfreeAnalysis::new();
1060        assert!(generate_system_correlation_report(&analysis, &snapshots, &output_path).is_ok());
1061        assert!(generate_enhanced_system_html(&analysis, &snapshots, &output_path).is_ok());
1062    }
1063}