1use serde::{Deserialize, Serialize};
7
8use super::allocation::{BottleneckType, ImpactLevel, PerformanceBottleneck};
9use super::generic::MemoryAccessPattern;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct FunctionCallTrackingInfo {
14 pub function_name: String,
16 pub module_path: String,
18 pub total_call_count: u64,
20 pub call_frequency_per_sec: f64,
22 pub avg_execution_time_ns: f64,
24 pub total_execution_time_ns: u64,
26 pub call_stack_info: CallStackInfo,
28 pub memory_allocations_per_call: f64,
30 pub performance_characteristics: FunctionPerformanceCharacteristics,
32 pub call_patterns: Vec<CallPattern>,
34}
35
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
38pub struct CallStackInfo {
39 pub max_stack_depth: u32,
41 pub avg_stack_depth: f64,
43 pub common_call_sequences: Vec<CallSequence>,
45 pub recursive_calls: Vec<RecursiveCallInfo>,
47 pub stack_overflow_risk: StackOverflowRisk,
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub struct CallSequence {
54 pub function_sequence: Vec<String>,
56 pub frequency: u32,
58 pub avg_execution_time_ns: f64,
60 pub memory_usage_pattern: MemoryUsagePattern,
62}
63
64#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
66pub struct MemoryUsagePattern {
67 pub peak_memory_usage: usize,
69 pub avg_memory_usage: usize,
71 pub allocation_frequency: f64,
73 pub deallocation_frequency: f64,
75 pub leak_potential: LeakPotential,
77}
78
79#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub enum LeakPotential {
82 Low,
84 Medium,
86 High,
88 Critical,
90}
91
92#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
94pub struct RecursiveCallInfo {
95 pub function_name: String,
97 pub max_recursion_depth: u32,
99 pub avg_recursion_depth: f64,
101 pub tail_recursion_potential: bool,
103 pub stack_usage_per_level: usize,
105 pub recursion_performance_impact: RecursionPerformanceImpact,
107}
108
109#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111pub struct RecursionPerformanceImpact {
112 pub stack_overhead_per_call: usize,
114 pub call_overhead_ns: f64,
116 pub cache_impact: f64,
118 pub optimization_recommendations: Vec<String>,
120}
121
122#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
124pub enum StackOverflowRisk {
125 Low,
127 Medium,
129 High,
131 Critical,
133}
134
135#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
137pub struct FunctionPerformanceCharacteristics {
138 pub cpu_usage_percent: f64,
140 pub memory_characteristics: FunctionMemoryCharacteristics,
142 pub io_characteristics: IOCharacteristics,
144 pub concurrency_characteristics: ConcurrencyCharacteristics,
146 pub bottlenecks: Vec<PerformanceBottleneck>,
148}
149
150#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub struct FunctionMemoryCharacteristics {
153 pub stack_memory_usage: usize,
155 pub heap_allocations: u32,
157 pub access_pattern: MemoryAccessPattern,
159 pub cache_efficiency: f64,
161 pub memory_bandwidth_utilization: f64,
163}
164
165#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
167pub struct IOCharacteristics {
168 pub file_io_operations: u32,
170 pub network_io_operations: u32,
172 pub avg_io_wait_time_ns: f64,
174 pub io_throughput_bytes_per_sec: f64,
176 pub io_efficiency_score: f64,
178}
179
180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct ConcurrencyCharacteristics {
183 pub thread_safety_level: ThreadSafetyLevel,
185 pub lock_contention_frequency: f64,
187 pub parallel_execution_potential: f64,
189 pub synchronization_overhead_ns: f64,
191 pub deadlock_risk: DeadlockRisk,
193}
194
195#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
197pub enum ThreadSafetyLevel {
198 ThreadSafe,
200 ConditionallyThreadSafe,
202 NotThreadSafe,
204 Unknown,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
210pub enum DeadlockRisk {
211 None,
213 Low,
215 Medium,
217 High,
219}
220
221#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
223pub struct CallPattern {
224 pub pattern_type: CallPatternType,
226 pub description: String,
228 pub frequency: u32,
230 pub performance_impact: f64,
232 pub optimization_potential: f64,
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub enum CallPatternType {
239 Sequential,
241 Recursive,
243 Iterative,
245 Conditional,
247 Parallel,
249 Asynchronous,
251 Callback,
253 EventDriven,
255}
256
257impl From<crate::core::types::FunctionCallTrackingInfo> for FunctionCallTrackingInfo {
258 fn from(old: crate::core::types::FunctionCallTrackingInfo) -> Self {
259 Self {
260 function_name: old.function_name,
261 module_path: old.module_path,
262 total_call_count: old.total_call_count,
263 call_frequency_per_sec: old.call_frequency_per_sec,
264 avg_execution_time_ns: old.avg_execution_time_ns,
265 total_execution_time_ns: old.total_execution_time_ns,
266 call_stack_info: CallStackInfo {
267 max_stack_depth: old.call_stack_info.max_stack_depth,
268 avg_stack_depth: old.call_stack_info.avg_stack_depth,
269 common_call_sequences: old
270 .call_stack_info
271 .common_call_sequences
272 .into_iter()
273 .map(|s| CallSequence {
274 function_sequence: s.function_sequence,
275 frequency: s.frequency,
276 avg_execution_time_ns: s.avg_execution_time_ns,
277 memory_usage_pattern: MemoryUsagePattern {
278 peak_memory_usage: s.memory_usage_pattern.peak_memory_usage,
279 avg_memory_usage: s.memory_usage_pattern.avg_memory_usage,
280 allocation_frequency: s.memory_usage_pattern.allocation_frequency,
281 deallocation_frequency: s.memory_usage_pattern.deallocation_frequency,
282 leak_potential: match s.memory_usage_pattern.leak_potential {
283 crate::core::types::LeakPotential::Low => LeakPotential::Low,
284 crate::core::types::LeakPotential::Medium => LeakPotential::Medium,
285 crate::core::types::LeakPotential::High => LeakPotential::High,
286 crate::core::types::LeakPotential::Critical => {
287 LeakPotential::Critical
288 }
289 },
290 },
291 })
292 .collect(),
293 recursive_calls: old
294 .call_stack_info
295 .recursive_calls
296 .into_iter()
297 .map(|r| RecursiveCallInfo {
298 function_name: r.function_name,
299 max_recursion_depth: r.max_recursion_depth,
300 avg_recursion_depth: r.avg_recursion_depth,
301 tail_recursion_potential: r.tail_recursion_potential,
302 stack_usage_per_level: r.stack_usage_per_level,
303 recursion_performance_impact: RecursionPerformanceImpact {
304 stack_overhead_per_call: r
305 .recursion_performance_impact
306 .stack_overhead_per_call,
307 call_overhead_ns: r.recursion_performance_impact.call_overhead_ns,
308 cache_impact: r.recursion_performance_impact.cache_impact,
309 optimization_recommendations: r
310 .recursion_performance_impact
311 .optimization_recommendations,
312 },
313 })
314 .collect(),
315 stack_overflow_risk: match old.call_stack_info.stack_overflow_risk {
316 crate::core::types::StackOverflowRisk::Low => StackOverflowRisk::Low,
317 crate::core::types::StackOverflowRisk::Medium => StackOverflowRisk::Medium,
318 crate::core::types::StackOverflowRisk::High => StackOverflowRisk::High,
319 crate::core::types::StackOverflowRisk::Critical => StackOverflowRisk::Critical,
320 },
321 },
322 memory_allocations_per_call: old.memory_allocations_per_call,
323 performance_characteristics: FunctionPerformanceCharacteristics {
324 cpu_usage_percent: old.performance_characteristics.cpu_usage_percent,
325 memory_characteristics: FunctionMemoryCharacteristics {
326 stack_memory_usage: old
327 .performance_characteristics
328 .memory_characteristics
329 .stack_memory_usage,
330 heap_allocations: old
331 .performance_characteristics
332 .memory_characteristics
333 .heap_allocations,
334 access_pattern: match old
335 .performance_characteristics
336 .memory_characteristics
337 .access_pattern
338 {
339 crate::core::types::MemoryAccessPattern::Sequential => {
340 MemoryAccessPattern::Sequential
341 }
342 crate::core::types::MemoryAccessPattern::Random => {
343 MemoryAccessPattern::Random
344 }
345 crate::core::types::MemoryAccessPattern::Strided { stride } => {
346 MemoryAccessPattern::Strided { stride }
347 }
348 crate::core::types::MemoryAccessPattern::Clustered => {
349 MemoryAccessPattern::Clustered
350 }
351 crate::core::types::MemoryAccessPattern::Mixed => {
352 MemoryAccessPattern::Mixed
353 }
354 },
355 cache_efficiency: old
356 .performance_characteristics
357 .memory_characteristics
358 .cache_efficiency,
359 memory_bandwidth_utilization: old
360 .performance_characteristics
361 .memory_characteristics
362 .memory_bandwidth_utilization,
363 },
364 io_characteristics: IOCharacteristics {
365 file_io_operations: old
366 .performance_characteristics
367 .io_characteristics
368 .file_io_operations,
369 network_io_operations: old
370 .performance_characteristics
371 .io_characteristics
372 .network_io_operations,
373 avg_io_wait_time_ns: old
374 .performance_characteristics
375 .io_characteristics
376 .avg_io_wait_time_ns,
377 io_throughput_bytes_per_sec: old
378 .performance_characteristics
379 .io_characteristics
380 .io_throughput_bytes_per_sec,
381 io_efficiency_score: old
382 .performance_characteristics
383 .io_characteristics
384 .io_efficiency_score,
385 },
386 concurrency_characteristics: ConcurrencyCharacteristics {
387 thread_safety_level: match old
388 .performance_characteristics
389 .concurrency_characteristics
390 .thread_safety_level
391 {
392 crate::core::types::ThreadSafetyLevel::ThreadSafe => {
393 ThreadSafetyLevel::ThreadSafe
394 }
395 crate::core::types::ThreadSafetyLevel::ConditionallyThreadSafe => {
396 ThreadSafetyLevel::ConditionallyThreadSafe
397 }
398 crate::core::types::ThreadSafetyLevel::NotThreadSafe => {
399 ThreadSafetyLevel::NotThreadSafe
400 }
401 crate::core::types::ThreadSafetyLevel::Unknown => {
402 ThreadSafetyLevel::Unknown
403 }
404 },
405 lock_contention_frequency: old
406 .performance_characteristics
407 .concurrency_characteristics
408 .lock_contention_frequency,
409 parallel_execution_potential: old
410 .performance_characteristics
411 .concurrency_characteristics
412 .parallel_execution_potential,
413 synchronization_overhead_ns: old
414 .performance_characteristics
415 .concurrency_characteristics
416 .synchronization_overhead_ns,
417 deadlock_risk: match old
418 .performance_characteristics
419 .concurrency_characteristics
420 .deadlock_risk
421 {
422 crate::core::types::DeadlockRisk::None => DeadlockRisk::None,
423 crate::core::types::DeadlockRisk::Low => DeadlockRisk::Low,
424 crate::core::types::DeadlockRisk::Medium => DeadlockRisk::Medium,
425 crate::core::types::DeadlockRisk::High => DeadlockRisk::High,
426 },
427 },
428 bottlenecks: old
429 .performance_characteristics
430 .bottlenecks
431 .into_iter()
432 .map(|b| PerformanceBottleneck {
433 bottleneck_type: match b.bottleneck_type {
434 crate::core::types::BottleneckType::MemoryAllocation => {
435 BottleneckType::MemoryAllocation
436 }
437 crate::core::types::BottleneckType::MemoryDeallocation => {
438 BottleneckType::MemoryDeallocation
439 }
440 crate::core::types::BottleneckType::CacheMiss => {
441 BottleneckType::CacheMiss
442 }
443 crate::core::types::BottleneckType::BranchMisprediction => {
444 BottleneckType::BranchMisprediction
445 }
446 crate::core::types::BottleneckType::FunctionCall => {
447 BottleneckType::FunctionCall
448 }
449 crate::core::types::BottleneckType::DataMovement => {
450 BottleneckType::DataMovement
451 }
452 crate::core::types::BottleneckType::Synchronization => {
453 BottleneckType::Synchronization
454 }
455 crate::core::types::BottleneckType::IO => BottleneckType::IO,
456 },
457 location: b.location,
458 severity: match b.severity {
459 crate::core::types::ImpactLevel::Low => ImpactLevel::Low,
460 crate::core::types::ImpactLevel::Medium => ImpactLevel::Medium,
461 crate::core::types::ImpactLevel::High => ImpactLevel::High,
462 crate::core::types::ImpactLevel::Critical => ImpactLevel::Critical,
463 },
464 description: b.description,
465 optimization_suggestion: b.optimization_suggestion,
466 })
467 .collect(),
468 },
469 call_patterns: old
470 .call_patterns
471 .into_iter()
472 .map(|p| CallPattern {
473 pattern_type: match p.pattern_type {
474 crate::core::types::CallPatternType::Sequential => {
475 CallPatternType::Sequential
476 }
477 crate::core::types::CallPatternType::Recursive => {
478 CallPatternType::Recursive
479 }
480 crate::core::types::CallPatternType::Iterative => {
481 CallPatternType::Iterative
482 }
483 crate::core::types::CallPatternType::Conditional => {
484 CallPatternType::Conditional
485 }
486 crate::core::types::CallPatternType::Parallel => CallPatternType::Parallel,
487 crate::core::types::CallPatternType::Asynchronous => {
488 CallPatternType::Asynchronous
489 }
490 crate::core::types::CallPatternType::Callback => CallPatternType::Callback,
491 crate::core::types::CallPatternType::EventDriven => {
492 CallPatternType::EventDriven
493 }
494 },
495 description: p.description,
496 frequency: p.frequency,
497 performance_impact: p.performance_impact,
498 optimization_potential: p.optimization_potential,
499 })
500 .collect(),
501 }
502 }
503}
504
505#[cfg(test)]
506mod tests {
507 use super::*;
508
509 #[test]
510 fn test_function_call_tracking_info() {
511 let info = FunctionCallTrackingInfo {
512 function_name: "test_func".to_string(),
513 module_path: "test::module".to_string(),
514 total_call_count: 100,
515 call_frequency_per_sec: 10.0,
516 avg_execution_time_ns: 1000.0,
517 total_execution_time_ns: 100000,
518 call_stack_info: CallStackInfo {
519 max_stack_depth: 5,
520 avg_stack_depth: 3.0,
521 common_call_sequences: vec![],
522 recursive_calls: vec![],
523 stack_overflow_risk: StackOverflowRisk::Low,
524 },
525 memory_allocations_per_call: 2.0,
526 performance_characteristics: FunctionPerformanceCharacteristics {
527 cpu_usage_percent: 5.0,
528 memory_characteristics: FunctionMemoryCharacteristics {
529 stack_memory_usage: 1024,
530 heap_allocations: 5,
531 access_pattern: MemoryAccessPattern::Sequential,
532 cache_efficiency: 0.9,
533 memory_bandwidth_utilization: 0.5,
534 },
535 io_characteristics: IOCharacteristics {
536 file_io_operations: 0,
537 network_io_operations: 0,
538 avg_io_wait_time_ns: 0.0,
539 io_throughput_bytes_per_sec: 0.0,
540 io_efficiency_score: 1.0,
541 },
542 concurrency_characteristics: ConcurrencyCharacteristics {
543 thread_safety_level: ThreadSafetyLevel::ThreadSafe,
544 lock_contention_frequency: 0.0,
545 parallel_execution_potential: 0.8,
546 synchronization_overhead_ns: 0.0,
547 deadlock_risk: DeadlockRisk::None,
548 },
549 bottlenecks: vec![],
550 },
551 call_patterns: vec![],
552 };
553
554 assert_eq!(info.function_name, "test_func");
555 assert_eq!(info.total_call_count, 100);
556 }
557
558 #[test]
559 fn test_call_pattern_type() {
560 let patterns = vec![
561 CallPatternType::Sequential,
562 CallPatternType::Recursive,
563 CallPatternType::Parallel,
564 ];
565
566 for pattern in patterns {
567 assert!(!format!("{pattern:?}").is_empty());
568 }
569 }
570
571 #[test]
572 fn test_all_leak_potential_variants() {
573 let potentials = [
574 LeakPotential::Low,
575 LeakPotential::Medium,
576 LeakPotential::High,
577 LeakPotential::Critical,
578 ];
579
580 for potential in potentials {
581 let pattern = MemoryUsagePattern {
582 peak_memory_usage: 1024,
583 avg_memory_usage: 512,
584 allocation_frequency: 10.0,
585 deallocation_frequency: 8.0,
586 leak_potential: potential.clone(),
587 };
588 assert_eq!(pattern.leak_potential, potential);
589 }
590 }
591
592 #[test]
593 fn test_all_stack_overflow_risk_variants() {
594 let risks = [
595 StackOverflowRisk::Low,
596 StackOverflowRisk::Medium,
597 StackOverflowRisk::High,
598 StackOverflowRisk::Critical,
599 ];
600
601 for risk in risks {
602 let info = CallStackInfo {
603 max_stack_depth: 10,
604 avg_stack_depth: 5.0,
605 common_call_sequences: vec![],
606 recursive_calls: vec![],
607 stack_overflow_risk: risk.clone(),
608 };
609 assert_eq!(info.stack_overflow_risk, risk);
610 }
611 }
612
613 #[test]
614 fn test_all_thread_safety_level_variants() {
615 let levels = [
616 ThreadSafetyLevel::ThreadSafe,
617 ThreadSafetyLevel::ConditionallyThreadSafe,
618 ThreadSafetyLevel::NotThreadSafe,
619 ThreadSafetyLevel::Unknown,
620 ];
621
622 for level in levels.clone() {
623 let chars = ConcurrencyCharacteristics {
624 thread_safety_level: level.clone(),
625 lock_contention_frequency: 0.5,
626 parallel_execution_potential: 0.8,
627 synchronization_overhead_ns: 100.0,
628 deadlock_risk: DeadlockRisk::None,
629 };
630 assert_eq!(chars.thread_safety_level, level);
631 }
632 }
633
634 #[test]
635 fn test_all_deadlock_risk_variants() {
636 let risks = [
637 DeadlockRisk::None,
638 DeadlockRisk::Low,
639 DeadlockRisk::Medium,
640 DeadlockRisk::High,
641 ];
642
643 for risk in risks {
644 let chars = ConcurrencyCharacteristics {
645 thread_safety_level: ThreadSafetyLevel::ThreadSafe,
646 lock_contention_frequency: 0.5,
647 parallel_execution_potential: 0.8,
648 synchronization_overhead_ns: 100.0,
649 deadlock_risk: risk.clone(),
650 };
651 assert_eq!(chars.deadlock_risk, risk);
652 }
653 }
654
655 #[test]
656 fn test_all_call_pattern_type_variants() {
657 let patterns = [
658 CallPatternType::Sequential,
659 CallPatternType::Recursive,
660 CallPatternType::Iterative,
661 CallPatternType::Conditional,
662 CallPatternType::Parallel,
663 CallPatternType::Asynchronous,
664 CallPatternType::Callback,
665 CallPatternType::EventDriven,
666 ];
667
668 for pattern in patterns {
669 let cp = CallPattern {
670 pattern_type: pattern.clone(),
671 description: "Test pattern".to_string(),
672 frequency: 10,
673 performance_impact: 0.5,
674 optimization_potential: 0.3,
675 };
676 assert_eq!(cp.pattern_type, pattern);
677 }
678 }
679
680 #[test]
681 fn test_call_stack_info_creation() {
682 let info = CallStackInfo {
683 max_stack_depth: 100,
684 avg_stack_depth: 45.5,
685 common_call_sequences: vec![CallSequence {
686 function_sequence: vec!["main".to_string(), "foo".to_string()],
687 frequency: 50,
688 avg_execution_time_ns: 5000.0,
689 memory_usage_pattern: MemoryUsagePattern {
690 peak_memory_usage: 2048,
691 avg_memory_usage: 1024,
692 allocation_frequency: 5.0,
693 deallocation_frequency: 5.0,
694 leak_potential: LeakPotential::Low,
695 },
696 }],
697 recursive_calls: vec![],
698 stack_overflow_risk: StackOverflowRisk::Medium,
699 };
700
701 assert_eq!(info.max_stack_depth, 100);
702 assert_eq!(info.common_call_sequences.len(), 1);
703 }
704
705 #[test]
706 fn test_recursive_call_info_creation() {
707 let info = RecursiveCallInfo {
708 function_name: "fibonacci".to_string(),
709 max_recursion_depth: 50,
710 avg_recursion_depth: 25.5,
711 tail_recursion_potential: true,
712 stack_usage_per_level: 64,
713 recursion_performance_impact: RecursionPerformanceImpact {
714 stack_overhead_per_call: 64,
715 call_overhead_ns: 10.0,
716 cache_impact: 0.2,
717 optimization_recommendations: vec!["Convert to iterative".to_string()],
718 },
719 };
720
721 assert_eq!(info.function_name, "fibonacci");
722 assert!(info.tail_recursion_potential);
723 }
724
725 #[test]
726 fn test_memory_usage_pattern_creation() {
727 let pattern = MemoryUsagePattern {
728 peak_memory_usage: 10240,
729 avg_memory_usage: 5120,
730 allocation_frequency: 100.0,
731 deallocation_frequency: 95.0,
732 leak_potential: LeakPotential::High,
733 };
734
735 assert_eq!(pattern.peak_memory_usage, 10240);
736 assert!(matches!(pattern.leak_potential, LeakPotential::High));
737 }
738
739 #[test]
740 fn test_function_memory_characteristics_creation() {
741 let chars = FunctionMemoryCharacteristics {
742 stack_memory_usage: 2048,
743 heap_allocations: 10,
744 access_pattern: MemoryAccessPattern::Random,
745 cache_efficiency: 0.75,
746 memory_bandwidth_utilization: 0.6,
747 };
748
749 assert_eq!(chars.stack_memory_usage, 2048);
750 assert!(matches!(chars.access_pattern, MemoryAccessPattern::Random));
751 }
752
753 #[test]
754 fn test_io_characteristics_creation() {
755 let chars = IOCharacteristics {
756 file_io_operations: 100,
757 network_io_operations: 50,
758 avg_io_wait_time_ns: 5000.0,
759 io_throughput_bytes_per_sec: 1024000.0,
760 io_efficiency_score: 0.85,
761 };
762
763 assert_eq!(chars.file_io_operations, 100);
764 assert_eq!(chars.network_io_operations, 50);
765 }
766
767 #[test]
768 fn test_call_sequence_creation() {
769 let seq = CallSequence {
770 function_sequence: vec!["a".to_string(), "b".to_string(), "c".to_string()],
771 frequency: 25,
772 avg_execution_time_ns: 15000.0,
773 memory_usage_pattern: MemoryUsagePattern {
774 peak_memory_usage: 4096,
775 avg_memory_usage: 2048,
776 allocation_frequency: 2.0,
777 deallocation_frequency: 2.0,
778 leak_potential: LeakPotential::Low,
779 },
780 };
781
782 assert_eq!(seq.function_sequence.len(), 3);
783 assert_eq!(seq.frequency, 25);
784 }
785
786 #[test]
787 fn test_call_pattern_creation() {
788 let pattern = CallPattern {
789 pattern_type: CallPatternType::Recursive,
790 description: "Recursive tree traversal".to_string(),
791 frequency: 100,
792 performance_impact: 0.4,
793 optimization_potential: 0.7,
794 };
795
796 assert!(matches!(pattern.pattern_type, CallPatternType::Recursive));
797 assert_eq!(pattern.optimization_potential, 0.7);
798 }
799
800 #[test]
801 fn test_function_call_tracking_info_serialization() {
802 let info = FunctionCallTrackingInfo {
803 function_name: "serialize_test".to_string(),
804 module_path: "test::serialize".to_string(),
805 total_call_count: 50,
806 call_frequency_per_sec: 5.0,
807 avg_execution_time_ns: 2000.0,
808 total_execution_time_ns: 100000,
809 call_stack_info: CallStackInfo {
810 max_stack_depth: 3,
811 avg_stack_depth: 2.0,
812 common_call_sequences: vec![],
813 recursive_calls: vec![],
814 stack_overflow_risk: StackOverflowRisk::Low,
815 },
816 memory_allocations_per_call: 1.5,
817 performance_characteristics: FunctionPerformanceCharacteristics {
818 cpu_usage_percent: 10.0,
819 memory_characteristics: FunctionMemoryCharacteristics {
820 stack_memory_usage: 512,
821 heap_allocations: 2,
822 access_pattern: MemoryAccessPattern::Sequential,
823 cache_efficiency: 0.9,
824 memory_bandwidth_utilization: 0.4,
825 },
826 io_characteristics: IOCharacteristics {
827 file_io_operations: 0,
828 network_io_operations: 0,
829 avg_io_wait_time_ns: 0.0,
830 io_throughput_bytes_per_sec: 0.0,
831 io_efficiency_score: 1.0,
832 },
833 concurrency_characteristics: ConcurrencyCharacteristics {
834 thread_safety_level: ThreadSafetyLevel::ThreadSafe,
835 lock_contention_frequency: 0.0,
836 parallel_execution_potential: 0.9,
837 synchronization_overhead_ns: 0.0,
838 deadlock_risk: DeadlockRisk::None,
839 },
840 bottlenecks: vec![],
841 },
842 call_patterns: vec![],
843 };
844
845 let json = serde_json::to_string(&info).unwrap();
846 let deserialized: FunctionCallTrackingInfo = serde_json::from_str(&json).unwrap();
847 assert_eq!(deserialized.function_name, info.function_name);
848 assert_eq!(deserialized.total_call_count, info.total_call_count);
849 }
850
851 #[test]
852 fn test_leak_potential_serialization() {
853 let potentials = vec![
854 LeakPotential::Low,
855 LeakPotential::Medium,
856 LeakPotential::High,
857 LeakPotential::Critical,
858 ];
859
860 for potential in potentials {
861 let json = serde_json::to_string(&potential).unwrap();
862 let deserialized: LeakPotential = serde_json::from_str(&json).unwrap();
863 assert_eq!(deserialized, potential);
864 }
865 }
866
867 #[test]
868 fn test_stack_overflow_risk_serialization() {
869 let risks = vec![
870 StackOverflowRisk::Low,
871 StackOverflowRisk::Medium,
872 StackOverflowRisk::High,
873 StackOverflowRisk::Critical,
874 ];
875
876 for risk in risks {
877 let json = serde_json::to_string(&risk).unwrap();
878 let deserialized: StackOverflowRisk = serde_json::from_str(&json).unwrap();
879 assert_eq!(deserialized, risk);
880 }
881 }
882
883 #[test]
884 fn test_thread_safety_level_serialization() {
885 let levels = vec![
886 ThreadSafetyLevel::ThreadSafe,
887 ThreadSafetyLevel::ConditionallyThreadSafe,
888 ThreadSafetyLevel::NotThreadSafe,
889 ThreadSafetyLevel::Unknown,
890 ];
891
892 for level in levels {
893 let json = serde_json::to_string(&level).unwrap();
894 let deserialized: ThreadSafetyLevel = serde_json::from_str(&json).unwrap();
895 assert_eq!(deserialized, level);
896 }
897 }
898
899 #[test]
900 fn test_deadlock_risk_serialization() {
901 let risks = vec![
902 DeadlockRisk::None,
903 DeadlockRisk::Low,
904 DeadlockRisk::Medium,
905 DeadlockRisk::High,
906 ];
907
908 for risk in risks {
909 let json = serde_json::to_string(&risk).unwrap();
910 let deserialized: DeadlockRisk = serde_json::from_str(&json).unwrap();
911 assert_eq!(deserialized, risk);
912 }
913 }
914
915 #[test]
916 fn test_call_pattern_type_serialization() {
917 let patterns = vec![
918 CallPatternType::Sequential,
919 CallPatternType::Recursive,
920 CallPatternType::Iterative,
921 CallPatternType::Conditional,
922 CallPatternType::Parallel,
923 CallPatternType::Asynchronous,
924 CallPatternType::Callback,
925 CallPatternType::EventDriven,
926 ];
927
928 for pattern in patterns {
929 let json = serde_json::to_string(&pattern).unwrap();
930 let deserialized: CallPatternType = serde_json::from_str(&json).unwrap();
931 assert_eq!(deserialized, pattern);
932 }
933 }
934
935 #[test]
936 fn test_function_call_tracking_info_clone() {
937 let info = FunctionCallTrackingInfo {
938 function_name: "clone_test".to_string(),
939 module_path: "test::clone".to_string(),
940 total_call_count: 10,
941 call_frequency_per_sec: 1.0,
942 avg_execution_time_ns: 100.0,
943 total_execution_time_ns: 1000,
944 call_stack_info: CallStackInfo {
945 max_stack_depth: 1,
946 avg_stack_depth: 1.0,
947 common_call_sequences: vec![],
948 recursive_calls: vec![],
949 stack_overflow_risk: StackOverflowRisk::Low,
950 },
951 memory_allocations_per_call: 0.0,
952 performance_characteristics: FunctionPerformanceCharacteristics {
953 cpu_usage_percent: 0.0,
954 memory_characteristics: FunctionMemoryCharacteristics {
955 stack_memory_usage: 0,
956 heap_allocations: 0,
957 access_pattern: MemoryAccessPattern::Sequential,
958 cache_efficiency: 0.0,
959 memory_bandwidth_utilization: 0.0,
960 },
961 io_characteristics: IOCharacteristics {
962 file_io_operations: 0,
963 network_io_operations: 0,
964 avg_io_wait_time_ns: 0.0,
965 io_throughput_bytes_per_sec: 0.0,
966 io_efficiency_score: 0.0,
967 },
968 concurrency_characteristics: ConcurrencyCharacteristics {
969 thread_safety_level: ThreadSafetyLevel::Unknown,
970 lock_contention_frequency: 0.0,
971 parallel_execution_potential: 0.0,
972 synchronization_overhead_ns: 0.0,
973 deadlock_risk: DeadlockRisk::None,
974 },
975 bottlenecks: vec![],
976 },
977 call_patterns: vec![],
978 };
979
980 let cloned = info.clone();
981 assert_eq!(cloned.function_name, info.function_name);
982 assert_eq!(cloned.total_call_count, info.total_call_count);
983 }
984
985 #[test]
986 fn test_function_call_tracking_info_debug() {
987 let info = FunctionCallTrackingInfo {
988 function_name: "debug_test".to_string(),
989 module_path: "test::debug".to_string(),
990 total_call_count: 1,
991 call_frequency_per_sec: 1.0,
992 avg_execution_time_ns: 1.0,
993 total_execution_time_ns: 1,
994 call_stack_info: CallStackInfo {
995 max_stack_depth: 1,
996 avg_stack_depth: 1.0,
997 common_call_sequences: vec![],
998 recursive_calls: vec![],
999 stack_overflow_risk: StackOverflowRisk::Low,
1000 },
1001 memory_allocations_per_call: 0.0,
1002 performance_characteristics: FunctionPerformanceCharacteristics {
1003 cpu_usage_percent: 0.0,
1004 memory_characteristics: FunctionMemoryCharacteristics {
1005 stack_memory_usage: 0,
1006 heap_allocations: 0,
1007 access_pattern: MemoryAccessPattern::Sequential,
1008 cache_efficiency: 0.0,
1009 memory_bandwidth_utilization: 0.0,
1010 },
1011 io_characteristics: IOCharacteristics {
1012 file_io_operations: 0,
1013 network_io_operations: 0,
1014 avg_io_wait_time_ns: 0.0,
1015 io_throughput_bytes_per_sec: 0.0,
1016 io_efficiency_score: 0.0,
1017 },
1018 concurrency_characteristics: ConcurrencyCharacteristics {
1019 thread_safety_level: ThreadSafetyLevel::Unknown,
1020 lock_contention_frequency: 0.0,
1021 parallel_execution_potential: 0.0,
1022 synchronization_overhead_ns: 0.0,
1023 deadlock_risk: DeadlockRisk::None,
1024 },
1025 bottlenecks: vec![],
1026 },
1027 call_patterns: vec![],
1028 };
1029
1030 let debug_str = format!("{:?}", info);
1031 assert!(debug_str.contains("FunctionCallTrackingInfo"));
1032 assert!(debug_str.contains("function_name"));
1033 }
1034
1035 #[test]
1036 fn test_recursion_performance_impact_creation() {
1037 let impact = RecursionPerformanceImpact {
1038 stack_overhead_per_call: 128,
1039 call_overhead_ns: 15.0,
1040 cache_impact: 0.35,
1041 optimization_recommendations: vec![
1042 "Use tail recursion".to_string(),
1043 "Convert to iteration".to_string(),
1044 ],
1045 };
1046
1047 assert_eq!(impact.stack_overhead_per_call, 128);
1048 assert_eq!(impact.optimization_recommendations.len(), 2);
1049 }
1050
1051 #[test]
1052 fn test_memory_access_pattern_variants() {
1053 let patterns = [
1054 MemoryAccessPattern::Sequential,
1055 MemoryAccessPattern::Random,
1056 MemoryAccessPattern::Strided { stride: 64 },
1057 MemoryAccessPattern::Clustered,
1058 MemoryAccessPattern::Mixed,
1059 ];
1060
1061 for pattern in patterns {
1062 let chars = FunctionMemoryCharacteristics {
1063 stack_memory_usage: 1024,
1064 heap_allocations: 5,
1065 access_pattern: pattern.clone(),
1066 cache_efficiency: 0.8,
1067 memory_bandwidth_utilization: 0.5,
1068 };
1069 assert_eq!(chars.access_pattern, pattern);
1070 }
1071 }
1072
1073 #[test]
1074 fn test_performance_bottleneck_in_function() {
1075 let bottleneck = PerformanceBottleneck {
1076 bottleneck_type: BottleneckType::MemoryAllocation,
1077 location: "test_function:42".to_string(),
1078 severity: ImpactLevel::High,
1079 description: "Excessive memory allocations".to_string(),
1080 optimization_suggestion: "Use object pool".to_string(),
1081 };
1082
1083 let chars = FunctionPerformanceCharacteristics {
1084 cpu_usage_percent: 50.0,
1085 memory_characteristics: FunctionMemoryCharacteristics {
1086 stack_memory_usage: 2048,
1087 heap_allocations: 100,
1088 access_pattern: MemoryAccessPattern::Random,
1089 cache_efficiency: 0.5,
1090 memory_bandwidth_utilization: 0.8,
1091 },
1092 io_characteristics: IOCharacteristics {
1093 file_io_operations: 0,
1094 network_io_operations: 0,
1095 avg_io_wait_time_ns: 0.0,
1096 io_throughput_bytes_per_sec: 0.0,
1097 io_efficiency_score: 1.0,
1098 },
1099 concurrency_characteristics: ConcurrencyCharacteristics {
1100 thread_safety_level: ThreadSafetyLevel::ThreadSafe,
1101 lock_contention_frequency: 0.0,
1102 parallel_execution_potential: 0.5,
1103 synchronization_overhead_ns: 0.0,
1104 deadlock_risk: DeadlockRisk::None,
1105 },
1106 bottlenecks: vec![bottleneck],
1107 };
1108
1109 assert_eq!(chars.bottlenecks.len(), 1);
1110 assert!(matches!(
1111 chars.bottlenecks[0].bottleneck_type,
1112 BottleneckType::MemoryAllocation
1113 ));
1114 }
1115
1116 #[test]
1117 fn test_boundary_values_call_count() {
1118 let info = FunctionCallTrackingInfo {
1119 function_name: "boundary_test".to_string(),
1120 module_path: "test::boundary".to_string(),
1121 total_call_count: u64::MAX,
1122 call_frequency_per_sec: f64::MAX,
1123 avg_execution_time_ns: f64::MIN,
1124 total_execution_time_ns: u64::MAX,
1125 call_stack_info: CallStackInfo {
1126 max_stack_depth: u32::MAX,
1127 avg_stack_depth: f64::MAX,
1128 common_call_sequences: vec![],
1129 recursive_calls: vec![],
1130 stack_overflow_risk: StackOverflowRisk::Critical,
1131 },
1132 memory_allocations_per_call: f64::INFINITY,
1133 performance_characteristics: FunctionPerformanceCharacteristics {
1134 cpu_usage_percent: 100.0,
1135 memory_characteristics: FunctionMemoryCharacteristics {
1136 stack_memory_usage: usize::MAX,
1137 heap_allocations: u32::MAX,
1138 access_pattern: MemoryAccessPattern::Mixed,
1139 cache_efficiency: 1.0,
1140 memory_bandwidth_utilization: 1.0,
1141 },
1142 io_characteristics: IOCharacteristics {
1143 file_io_operations: u32::MAX,
1144 network_io_operations: u32::MAX,
1145 avg_io_wait_time_ns: f64::MAX,
1146 io_throughput_bytes_per_sec: f64::MAX,
1147 io_efficiency_score: 0.0,
1148 },
1149 concurrency_characteristics: ConcurrencyCharacteristics {
1150 thread_safety_level: ThreadSafetyLevel::NotThreadSafe,
1151 lock_contention_frequency: f64::MAX,
1152 parallel_execution_potential: 0.0,
1153 synchronization_overhead_ns: f64::MAX,
1154 deadlock_risk: DeadlockRisk::High,
1155 },
1156 bottlenecks: vec![],
1157 },
1158 call_patterns: vec![],
1159 };
1160
1161 assert_eq!(info.total_call_count, u64::MAX);
1162 assert_eq!(info.call_stack_info.max_stack_depth, u32::MAX);
1163 }
1164}