Skip to main content

memscope_rs/capture/types/
lifecycle.rs

1//! Object lifecycle tracking types.
2//!
3//! This module contains types for tracking object lifecycles,
4//! including lifecycle events, patterns, and efficiency metrics.
5
6use serde::{Deserialize, Serialize};
7
8use super::generic::SourceLocation;
9
10/// Object lifecycle event tracking.
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct ObjectLifecycleInfo {
13    /// Object identifier.
14    pub object_id: usize,
15    /// Object type name.
16    pub type_name: String,
17    /// Lifecycle events.
18    pub lifecycle_events: Vec<LifecycleEvent>,
19    /// Total lifetime duration.
20    pub total_lifetime_ns: Option<u64>,
21    /// Lifecycle stage durations.
22    pub stage_durations: LifecycleStageDurations,
23    /// Lifecycle efficiency metrics.
24    pub efficiency_metrics: LifecycleEfficiencyMetrics,
25    /// Lifecycle patterns.
26    pub lifecycle_patterns: Vec<LifecyclePattern>,
27}
28
29/// Lifecycle event information.
30#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub struct LifecycleEvent {
32    /// Event type.
33    pub event_type: LifecycleEventType,
34    /// Timestamp when event occurred.
35    pub timestamp: u64,
36    /// Location where event occurred.
37    pub location: SourceLocation,
38    /// Memory state at event time.
39    pub memory_state: MemoryState,
40    /// Performance metrics at event time.
41    pub performance_metrics: EventPerformanceMetrics,
42    /// Call stack at event time.
43    pub call_stack: Vec<String>,
44}
45
46/// Types of lifecycle events.
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48pub enum LifecycleEventType {
49    /// Object creation.
50    Creation,
51    /// Object initialization.
52    Initialization,
53    /// Object first use.
54    FirstUse,
55    /// Object move.
56    Move,
57    /// Object copy.
58    Copy,
59    /// Object clone.
60    Clone,
61    /// Object borrow.
62    Borrow,
63    /// Object mutable borrow.
64    MutableBorrow,
65    /// Object borrow release.
66    BorrowRelease,
67    /// Object modification.
68    Modification,
69    /// Object last use.
70    LastUse,
71    /// Object drop.
72    Drop,
73    /// Object destruction.
74    Destruction,
75    /// Object memory reclaim.
76    MemoryReclaim,
77}
78
79/// Memory state at event time.
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub struct MemoryState {
82    /// Memory location.
83    pub memory_location: MemoryLocationType,
84    /// Memory address.
85    pub memory_address: usize,
86    /// Object size.
87    pub object_size: usize,
88    /// Reference count (if applicable).
89    pub reference_count: Option<u32>,
90    /// Borrow state.
91    pub borrow_state: BorrowState,
92}
93
94/// Borrow state information.
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96pub enum BorrowState {
97    /// Object is not borrowed.
98    NotBorrowed,
99    /// Object is shared borrowed.
100    SharedBorrow {
101        /// Number of shared borrows.
102        count: u32,
103    },
104    /// Object is mutably borrowed.
105    MutableBorrow,
106    /// Object has been moved out.
107    MovedOut,
108}
109
110/// Memory location type.
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112pub enum MemoryLocationType {
113    /// Stack memory location.
114    Stack,
115    /// Heap memory location.
116    Heap,
117    /// Register memory location.
118    Register,
119    /// Static memory location.
120    Static,
121    /// Thread-local memory location.
122    ThreadLocal,
123}
124
125/// Performance metrics at event time.
126#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub struct EventPerformanceMetrics {
128    /// CPU cycles consumed by event.
129    pub cpu_cycles: u64,
130    /// Memory bandwidth used.
131    pub memory_bandwidth_bytes: usize,
132    /// Cache misses caused by event.
133    pub cache_misses: u32,
134    /// Event processing time.
135    pub processing_time_ns: u64,
136}
137
138/// Lifecycle stage durations.
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140pub struct LifecycleStageDurations {
141    /// Time from creation to first use.
142    pub creation_to_first_use_ns: Option<u64>,
143    /// Time spent in active use.
144    pub active_use_duration_ns: Option<u64>,
145    /// Time from last use to destruction.
146    pub last_use_to_destruction_ns: Option<u64>,
147    /// Time spent borrowed.
148    pub borrowed_duration_ns: u64,
149    /// Time spent idle.
150    pub idle_duration_ns: u64,
151}
152
153/// Lifecycle efficiency metrics.
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub struct LifecycleEfficiencyMetrics {
156    /// Utilization ratio (active time / total time).
157    pub utilization_ratio: f64,
158    /// Memory efficiency (useful operations / memory usage).
159    pub memory_efficiency: f64,
160    /// Performance efficiency score.
161    pub performance_efficiency: f64,
162    /// Resource waste assessment.
163    pub resource_waste: ResourceWasteAssessment,
164}
165
166impl Default for LifecycleEfficiencyMetrics {
167    fn default() -> Self {
168        Self {
169            utilization_ratio: 0.0,
170            memory_efficiency: 0.0,
171            performance_efficiency: 0.0,
172            resource_waste: ResourceWasteAssessment {
173                wasted_memory_percent: 0.0,
174                wasted_cpu_percent: 0.0,
175                premature_destructions: 0,
176                unused_instances: 0,
177                optimization_opportunities: Vec::new(),
178            },
179        }
180    }
181}
182
183/// Resource waste assessment.
184#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
185pub struct ResourceWasteAssessment {
186    /// Wasted memory percentage.
187    pub wasted_memory_percent: f64,
188    /// Wasted CPU cycles percentage.
189    pub wasted_cpu_percent: f64,
190    /// Premature destruction events.
191    pub premature_destructions: u32,
192    /// Unused object instances.
193    pub unused_instances: u32,
194    /// Optimization opportunities.
195    pub optimization_opportunities: Vec<String>,
196}
197
198/// Lifecycle pattern information.
199#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
200pub struct LifecyclePattern {
201    /// Pattern type.
202    pub pattern_type: LifecyclePatternType,
203    /// Pattern frequency.
204    pub frequency: u32,
205    /// Pattern efficiency.
206    pub efficiency_score: f64,
207    /// Associated performance impact.
208    pub performance_impact: f64,
209    /// Optimization suggestions.
210    pub optimization_suggestions: Vec<String>,
211}
212
213/// Types of lifecycle patterns.
214#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
215pub enum LifecyclePatternType {
216    /// Short-lived objects.
217    ShortLived,
218    /// Long-lived objects.
219    LongLived,
220    /// Cyclical objects.
221    Cyclical,
222    /// On-demand objects.
223    OnDemand,
224    /// Cached objects.
225    Cached,
226    /// Pooled objects.
227    Pooled,
228    /// Singleton objects.
229    Singleton,
230    /// Factory objects.
231    Factory,
232    /// RAII objects.
233    RAII,
234}
235
236/// Simple lifecycle pattern classification.
237#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub enum SimpleLifecyclePattern {
239    /// Very short-lived (0-1ms).
240    Instant,
241    /// Short-lived (2-100ms).
242    ShortLived,
243    /// Medium-lived (101ms-10s).
244    MediumLived,
245    /// Long-lived (10s-5min).
246    LongLived,
247    /// Persistent (>5min).
248    Persistent,
249}
250
251impl From<crate::core::types::ObjectLifecycleInfo> for ObjectLifecycleInfo {
252    fn from(old: crate::core::types::ObjectLifecycleInfo) -> Self {
253        Self {
254            object_id: old.object_id,
255            type_name: old.type_name,
256            lifecycle_events: old
257                .lifecycle_events
258                .into_iter()
259                .map(|e| LifecycleEvent {
260                    event_type: match e.event_type {
261                        crate::core::types::LifecycleEventType::Creation => {
262                            LifecycleEventType::Creation
263                        }
264                        crate::core::types::LifecycleEventType::Initialization => {
265                            LifecycleEventType::Initialization
266                        }
267                        crate::core::types::LifecycleEventType::FirstUse => {
268                            LifecycleEventType::FirstUse
269                        }
270                        crate::core::types::LifecycleEventType::Move => LifecycleEventType::Move,
271                        crate::core::types::LifecycleEventType::Copy => LifecycleEventType::Copy,
272                        crate::core::types::LifecycleEventType::Clone => LifecycleEventType::Clone,
273                        crate::core::types::LifecycleEventType::Borrow => {
274                            LifecycleEventType::Borrow
275                        }
276                        crate::core::types::LifecycleEventType::MutableBorrow => {
277                            LifecycleEventType::MutableBorrow
278                        }
279                        crate::core::types::LifecycleEventType::BorrowRelease => {
280                            LifecycleEventType::BorrowRelease
281                        }
282                        crate::core::types::LifecycleEventType::Modification => {
283                            LifecycleEventType::Modification
284                        }
285                        crate::core::types::LifecycleEventType::LastUse => {
286                            LifecycleEventType::LastUse
287                        }
288                        crate::core::types::LifecycleEventType::Drop => LifecycleEventType::Drop,
289                        crate::core::types::LifecycleEventType::Destruction => {
290                            LifecycleEventType::Destruction
291                        }
292                        crate::core::types::LifecycleEventType::MemoryReclaim => {
293                            LifecycleEventType::MemoryReclaim
294                        }
295                    },
296                    timestamp: e.timestamp,
297                    location: SourceLocation {
298                        file: e.location.file,
299                        line: e.location.line,
300                        column: e.location.column,
301                    },
302                    memory_state: MemoryState {
303                        memory_location: match e.memory_state.memory_location {
304                            crate::core::types::MemoryLocationType::Stack => {
305                                MemoryLocationType::Stack
306                            }
307                            crate::core::types::MemoryLocationType::Heap => {
308                                MemoryLocationType::Heap
309                            }
310                            crate::core::types::MemoryLocationType::Register => {
311                                MemoryLocationType::Register
312                            }
313                            crate::core::types::MemoryLocationType::Static => {
314                                MemoryLocationType::Static
315                            }
316                            crate::core::types::MemoryLocationType::ThreadLocal => {
317                                MemoryLocationType::ThreadLocal
318                            }
319                        },
320                        memory_address: e.memory_state.memory_address,
321                        object_size: e.memory_state.object_size,
322                        reference_count: e.memory_state.reference_count,
323                        borrow_state: match e.memory_state.borrow_state {
324                            crate::core::types::BorrowState::NotBorrowed => {
325                                BorrowState::NotBorrowed
326                            }
327                            crate::core::types::BorrowState::SharedBorrow { count } => {
328                                BorrowState::SharedBorrow { count }
329                            }
330                            crate::core::types::BorrowState::MutableBorrow => {
331                                BorrowState::MutableBorrow
332                            }
333                            crate::core::types::BorrowState::MovedOut => BorrowState::MovedOut,
334                        },
335                    },
336                    performance_metrics: EventPerformanceMetrics {
337                        cpu_cycles: e.performance_metrics.cpu_cycles,
338                        memory_bandwidth_bytes: e.performance_metrics.memory_bandwidth_bytes,
339                        cache_misses: e.performance_metrics.cache_misses,
340                        processing_time_ns: e.performance_metrics.processing_time_ns,
341                    },
342                    call_stack: e.call_stack,
343                })
344                .collect(),
345            total_lifetime_ns: old.total_lifetime_ns,
346            stage_durations: LifecycleStageDurations {
347                creation_to_first_use_ns: old.stage_durations.creation_to_first_use_ns,
348                active_use_duration_ns: old.stage_durations.active_use_duration_ns,
349                last_use_to_destruction_ns: old.stage_durations.last_use_to_destruction_ns,
350                borrowed_duration_ns: old.stage_durations.borrowed_duration_ns,
351                idle_duration_ns: old.stage_durations.idle_duration_ns,
352            },
353            efficiency_metrics: LifecycleEfficiencyMetrics {
354                utilization_ratio: old.efficiency_metrics.utilization_ratio,
355                memory_efficiency: old.efficiency_metrics.memory_efficiency,
356                performance_efficiency: old.efficiency_metrics.performance_efficiency,
357                resource_waste: ResourceWasteAssessment {
358                    wasted_memory_percent: old
359                        .efficiency_metrics
360                        .resource_waste
361                        .wasted_memory_percent,
362                    wasted_cpu_percent: old.efficiency_metrics.resource_waste.wasted_cpu_percent,
363                    premature_destructions: old
364                        .efficiency_metrics
365                        .resource_waste
366                        .premature_destructions,
367                    unused_instances: old.efficiency_metrics.resource_waste.unused_instances,
368                    optimization_opportunities: old
369                        .efficiency_metrics
370                        .resource_waste
371                        .optimization_opportunities,
372                },
373            },
374            lifecycle_patterns: old
375                .lifecycle_patterns
376                .into_iter()
377                .map(|p| LifecyclePattern {
378                    pattern_type: match p.pattern_type {
379                        crate::core::types::LifecyclePatternType::ShortLived => {
380                            LifecyclePatternType::ShortLived
381                        }
382                        crate::core::types::LifecyclePatternType::LongLived => {
383                            LifecyclePatternType::LongLived
384                        }
385                        crate::core::types::LifecyclePatternType::Cyclical => {
386                            LifecyclePatternType::Cyclical
387                        }
388                        crate::core::types::LifecyclePatternType::OnDemand => {
389                            LifecyclePatternType::OnDemand
390                        }
391                        crate::core::types::LifecyclePatternType::Cached => {
392                            LifecyclePatternType::Cached
393                        }
394                        crate::core::types::LifecyclePatternType::Pooled => {
395                            LifecyclePatternType::Pooled
396                        }
397                        crate::core::types::LifecyclePatternType::Singleton => {
398                            LifecyclePatternType::Singleton
399                        }
400                        crate::core::types::LifecyclePatternType::Factory => {
401                            LifecyclePatternType::Factory
402                        }
403                        crate::core::types::LifecyclePatternType::RAII => {
404                            LifecyclePatternType::RAII
405                        }
406                    },
407                    frequency: p.frequency,
408                    efficiency_score: p.efficiency_score,
409                    performance_impact: p.performance_impact,
410                    optimization_suggestions: p.optimization_suggestions,
411                })
412                .collect(),
413        }
414    }
415}
416
417#[cfg(test)]
418mod tests {
419    use super::*;
420
421    /// Objective: Verify ObjectLifecycleInfo creation with all fields
422    /// Invariants: All fields should be properly initialized
423    #[test]
424    fn test_object_lifecycle_info() {
425        let info = ObjectLifecycleInfo {
426            object_id: 1,
427            type_name: "String".to_string(),
428            lifecycle_events: vec![],
429            total_lifetime_ns: Some(1000000),
430            stage_durations: LifecycleStageDurations {
431                creation_to_first_use_ns: Some(100),
432                active_use_duration_ns: Some(900000),
433                last_use_to_destruction_ns: Some(99900),
434                borrowed_duration_ns: 100000,
435                idle_duration_ns: 50000,
436            },
437            efficiency_metrics: LifecycleEfficiencyMetrics::default(),
438            lifecycle_patterns: vec![],
439        };
440
441        assert_eq!(info.object_id, 1, "Object ID should match");
442        assert_eq!(info.type_name, "String", "Type name should match");
443        assert_eq!(
444            info.total_lifetime_ns,
445            Some(1000000),
446            "Total lifetime should match"
447        );
448    }
449
450    /// Objective: Verify LifecycleEventType variants
451    /// Invariants: All variants should have debug representation
452    #[test]
453    fn test_lifecycle_event_type() {
454        let events = vec![
455            LifecycleEventType::Creation,
456            LifecycleEventType::Initialization,
457            LifecycleEventType::FirstUse,
458            LifecycleEventType::Move,
459            LifecycleEventType::Copy,
460            LifecycleEventType::Clone,
461            LifecycleEventType::Borrow,
462            LifecycleEventType::MutableBorrow,
463            LifecycleEventType::BorrowRelease,
464            LifecycleEventType::Modification,
465            LifecycleEventType::LastUse,
466            LifecycleEventType::Drop,
467            LifecycleEventType::Destruction,
468            LifecycleEventType::MemoryReclaim,
469        ];
470
471        for event in events {
472            let debug_str = format!("{event:?}");
473            assert!(
474                !debug_str.is_empty(),
475                "LifecycleEventType should have debug representation"
476            );
477        }
478    }
479
480    /// Objective: Verify LifecycleEvent creation
481    /// Invariants: All fields should be accessible
482    #[test]
483    fn test_lifecycle_event() {
484        let event = LifecycleEvent {
485            event_type: LifecycleEventType::Creation,
486            timestamp: 1000,
487            location: SourceLocation {
488                file: "test.rs".to_string(),
489                line: 10,
490                column: 5,
491            },
492            memory_state: MemoryState {
493                memory_location: MemoryLocationType::Heap,
494                memory_address: 0x1000,
495                object_size: 64,
496                reference_count: Some(1),
497                borrow_state: BorrowState::NotBorrowed,
498            },
499            performance_metrics: EventPerformanceMetrics {
500                cpu_cycles: 1000,
501                memory_bandwidth_bytes: 64,
502                cache_misses: 2,
503                processing_time_ns: 500,
504            },
505            call_stack: vec!["main".to_string(), "test".to_string()],
506        };
507
508        assert_eq!(
509            event.event_type,
510            LifecycleEventType::Creation,
511            "Event type should be Creation"
512        );
513        assert_eq!(event.timestamp, 1000, "Timestamp should match");
514        assert_eq!(event.call_stack.len(), 2, "Call stack should have 2 frames");
515    }
516
517    /// Objective: Verify MemoryState creation
518    /// Invariants: All fields should be accessible
519    #[test]
520    fn test_memory_state() {
521        let state = MemoryState {
522            memory_location: MemoryLocationType::Stack,
523            memory_address: 0x7fff0000,
524            object_size: 32,
525            reference_count: None,
526            borrow_state: BorrowState::SharedBorrow { count: 3 },
527        };
528
529        assert_eq!(
530            state.memory_location,
531            MemoryLocationType::Stack,
532            "Memory location should be Stack"
533        );
534        assert_eq!(
535            state.borrow_state,
536            BorrowState::SharedBorrow { count: 3 },
537            "Borrow state should be SharedBorrow with count 3"
538        );
539    }
540
541    /// Objective: Verify BorrowState variants
542    /// Invariants: All variants should be distinct
543    #[test]
544    fn test_borrow_state_variants() {
545        let states = vec![
546            BorrowState::NotBorrowed,
547            BorrowState::SharedBorrow { count: 1 },
548            BorrowState::MutableBorrow,
549            BorrowState::MovedOut,
550        ];
551
552        for state in &states {
553            let debug_str = format!("{state:?}");
554            assert!(
555                !debug_str.is_empty(),
556                "BorrowState should have debug representation"
557            );
558        }
559
560        assert_eq!(BorrowState::NotBorrowed, BorrowState::NotBorrowed);
561        assert_ne!(BorrowState::NotBorrowed, BorrowState::MutableBorrow);
562    }
563
564    /// Objective: Verify MemoryLocationType variants
565    /// Invariants: All variants should be distinct
566    #[test]
567    fn test_memory_location_type_variants() {
568        let locations = vec![
569            MemoryLocationType::Stack,
570            MemoryLocationType::Heap,
571            MemoryLocationType::Register,
572            MemoryLocationType::Static,
573            MemoryLocationType::ThreadLocal,
574        ];
575
576        for location in &locations {
577            let debug_str = format!("{location:?}");
578            assert!(
579                !debug_str.is_empty(),
580                "MemoryLocationType should have debug representation"
581            );
582        }
583    }
584
585    /// Objective: Verify EventPerformanceMetrics creation
586    /// Invariants: All fields should be accessible
587    #[test]
588    fn test_event_performance_metrics() {
589        let metrics = EventPerformanceMetrics {
590            cpu_cycles: 5000,
591            memory_bandwidth_bytes: 1024,
592            cache_misses: 10,
593            processing_time_ns: 2000,
594        };
595
596        assert_eq!(metrics.cpu_cycles, 5000, "CPU cycles should match");
597        assert_eq!(
598            metrics.memory_bandwidth_bytes, 1024,
599            "Memory bandwidth should match"
600        );
601        assert_eq!(metrics.cache_misses, 10, "Cache misses should match");
602    }
603
604    /// Objective: Verify LifecycleStageDurations creation
605    /// Invariants: All fields should be accessible
606    #[test]
607    fn test_lifecycle_stage_durations() {
608        let durations = LifecycleStageDurations {
609            creation_to_first_use_ns: Some(100),
610            active_use_duration_ns: Some(1000),
611            last_use_to_destruction_ns: Some(50),
612            borrowed_duration_ns: 200,
613            idle_duration_ns: 100,
614        };
615
616        assert_eq!(
617            durations.creation_to_first_use_ns,
618            Some(100),
619            "Creation to first use should match"
620        );
621        assert_eq!(
622            durations.active_use_duration_ns,
623            Some(1000),
624            "Active use duration should match"
625        );
626    }
627
628    /// Objective: Verify LifecycleEfficiencyMetrics default
629    /// Invariants: Default should have zero values
630    #[test]
631    fn test_lifecycle_efficiency_metrics_default() {
632        let metrics = LifecycleEfficiencyMetrics::default();
633
634        assert_eq!(
635            metrics.utilization_ratio, 0.0,
636            "Utilization ratio should be 0"
637        );
638        assert_eq!(
639            metrics.memory_efficiency, 0.0,
640            "Memory efficiency should be 0"
641        );
642        assert_eq!(
643            metrics.performance_efficiency, 0.0,
644            "Performance efficiency should be 0"
645        );
646        assert_eq!(
647            metrics.resource_waste.wasted_memory_percent, 0.0,
648            "Wasted memory should be 0"
649        );
650    }
651
652    /// Objective: Verify LifecycleEfficiencyMetrics with values
653    /// Invariants: Should handle populated metrics
654    #[test]
655    fn test_lifecycle_efficiency_metrics_with_values() {
656        let metrics = LifecycleEfficiencyMetrics {
657            utilization_ratio: 0.85,
658            memory_efficiency: 0.9,
659            performance_efficiency: 0.95,
660            resource_waste: ResourceWasteAssessment {
661                wasted_memory_percent: 5.0,
662                wasted_cpu_percent: 3.0,
663                premature_destructions: 2,
664                unused_instances: 5,
665                optimization_opportunities: vec!["Use pool".to_string()],
666            },
667        };
668
669        assert_eq!(
670            metrics.utilization_ratio, 0.85,
671            "Utilization ratio should match"
672        );
673        assert_eq!(
674            metrics.resource_waste.premature_destructions, 2,
675            "Premature destructions should match"
676        );
677        assert_eq!(
678            metrics.resource_waste.optimization_opportunities.len(),
679            1,
680            "Should have one optimization opportunity"
681        );
682    }
683
684    /// Objective: Verify ResourceWasteAssessment creation
685    /// Invariants: All fields should be accessible
686    #[test]
687    fn test_resource_waste_assessment() {
688        let assessment = ResourceWasteAssessment {
689            wasted_memory_percent: 10.0,
690            wasted_cpu_percent: 5.0,
691            premature_destructions: 3,
692            unused_instances: 10,
693            optimization_opportunities: vec!["Optimize A".to_string(), "Optimize B".to_string()],
694        };
695
696        assert_eq!(
697            assessment.wasted_memory_percent, 10.0,
698            "Wasted memory percent should match"
699        );
700        assert_eq!(
701            assessment.unused_instances, 10,
702            "Unused instances should match"
703        );
704    }
705
706    /// Objective: Verify LifecyclePattern creation
707    /// Invariants: All fields should be accessible
708    #[test]
709    fn test_lifecycle_pattern() {
710        let pattern = LifecyclePattern {
711            pattern_type: LifecyclePatternType::ShortLived,
712            frequency: 100,
713            efficiency_score: 0.8,
714            performance_impact: 0.2,
715            optimization_suggestions: vec!["Consider pooling".to_string()],
716        };
717
718        assert_eq!(
719            pattern.pattern_type,
720            LifecyclePatternType::ShortLived,
721            "Pattern type should match"
722        );
723        assert_eq!(pattern.frequency, 100, "Frequency should match");
724    }
725
726    /// Objective: Verify LifecyclePatternType variants
727    /// Invariants: All variants should be distinct
728    #[test]
729    fn test_lifecycle_pattern_type_variants() {
730        let patterns = vec![
731            LifecyclePatternType::ShortLived,
732            LifecyclePatternType::LongLived,
733            LifecyclePatternType::Cyclical,
734            LifecyclePatternType::OnDemand,
735            LifecyclePatternType::Cached,
736            LifecyclePatternType::Pooled,
737            LifecyclePatternType::Singleton,
738            LifecyclePatternType::Factory,
739            LifecyclePatternType::RAII,
740        ];
741
742        for pattern in &patterns {
743            let debug_str = format!("{pattern:?}");
744            assert!(
745                !debug_str.is_empty(),
746                "LifecyclePatternType should have debug representation"
747            );
748        }
749    }
750
751    /// Objective: Verify SimpleLifecyclePattern variants
752    /// Invariants: All variants should be distinct
753    #[test]
754    fn test_simple_lifecycle_pattern_variants() {
755        let patterns = vec![
756            SimpleLifecyclePattern::Instant,
757            SimpleLifecyclePattern::ShortLived,
758            SimpleLifecyclePattern::MediumLived,
759            SimpleLifecyclePattern::LongLived,
760            SimpleLifecyclePattern::Persistent,
761        ];
762
763        for pattern in &patterns {
764            let debug_str = format!("{pattern:?}");
765            assert!(
766                !debug_str.is_empty(),
767                "SimpleLifecyclePattern should have debug representation"
768            );
769        }
770    }
771
772    /// Objective: Verify serialization of LifecycleEventType
773    /// Invariants: Should serialize and deserialize correctly
774    #[test]
775    fn test_lifecycle_event_type_serialization() {
776        let event_type = LifecycleEventType::Clone;
777        let json = serde_json::to_string(&event_type);
778        assert!(json.is_ok(), "Should serialize to JSON");
779
780        let deserialized: Result<LifecycleEventType, _> = serde_json::from_str(&json.unwrap());
781        assert!(deserialized.is_ok(), "Should deserialize from JSON");
782        assert_eq!(
783            deserialized.unwrap(),
784            LifecycleEventType::Clone,
785            "Should preserve value"
786        );
787    }
788
789    /// Objective: Verify serialization of BorrowState
790    /// Invariants: Should serialize and deserialize correctly
791    #[test]
792    fn test_borrow_state_serialization() {
793        let state = BorrowState::SharedBorrow { count: 5 };
794        let json = serde_json::to_string(&state);
795        assert!(json.is_ok(), "Should serialize to JSON");
796
797        let deserialized: Result<BorrowState, _> = serde_json::from_str(&json.unwrap());
798        assert!(deserialized.is_ok(), "Should deserialize from JSON");
799        assert_eq!(
800            deserialized.unwrap(),
801            BorrowState::SharedBorrow { count: 5 },
802            "Should preserve value"
803        );
804    }
805
806    /// Objective: Verify serialization of MemoryLocationType
807    /// Invariants: Should serialize and deserialize correctly
808    #[test]
809    fn test_memory_location_type_serialization() {
810        let location = MemoryLocationType::Heap;
811        let json = serde_json::to_string(&location);
812        assert!(json.is_ok(), "Should serialize to JSON");
813
814        let deserialized: Result<MemoryLocationType, _> = serde_json::from_str(&json.unwrap());
815        assert!(deserialized.is_ok(), "Should deserialize from JSON");
816        assert_eq!(
817            deserialized.unwrap(),
818            MemoryLocationType::Heap,
819            "Should preserve value"
820        );
821    }
822
823    /// Objective: Verify ObjectLifecycleInfo with events
824    /// Invariants: Should handle multiple lifecycle events
825    #[test]
826    fn test_object_lifecycle_info_with_events() {
827        let events = vec![
828            LifecycleEvent {
829                event_type: LifecycleEventType::Creation,
830                timestamp: 0,
831                location: SourceLocation {
832                    file: "test.rs".to_string(),
833                    line: 1,
834                    column: 1,
835                },
836                memory_state: MemoryState {
837                    memory_location: MemoryLocationType::Heap,
838                    memory_address: 0x1000,
839                    object_size: 64,
840                    reference_count: None,
841                    borrow_state: BorrowState::NotBorrowed,
842                },
843                performance_metrics: EventPerformanceMetrics {
844                    cpu_cycles: 100,
845                    memory_bandwidth_bytes: 64,
846                    cache_misses: 0,
847                    processing_time_ns: 50,
848                },
849                call_stack: vec![],
850            },
851            LifecycleEvent {
852                event_type: LifecycleEventType::Drop,
853                timestamp: 1000000,
854                location: SourceLocation {
855                    file: "test.rs".to_string(),
856                    line: 10,
857                    column: 1,
858                },
859                memory_state: MemoryState {
860                    memory_location: MemoryLocationType::Heap,
861                    memory_address: 0x1000,
862                    object_size: 64,
863                    reference_count: None,
864                    borrow_state: BorrowState::NotBorrowed,
865                },
866                performance_metrics: EventPerformanceMetrics {
867                    cpu_cycles: 50,
868                    memory_bandwidth_bytes: 0,
869                    cache_misses: 0,
870                    processing_time_ns: 25,
871                },
872                call_stack: vec![],
873            },
874        ];
875
876        let info = ObjectLifecycleInfo {
877            object_id: 1,
878            type_name: "String".to_string(),
879            lifecycle_events: events,
880            total_lifetime_ns: Some(1000000),
881            stage_durations: LifecycleStageDurations {
882                creation_to_first_use_ns: None,
883                active_use_duration_ns: None,
884                last_use_to_destruction_ns: None,
885                borrowed_duration_ns: 0,
886                idle_duration_ns: 0,
887            },
888            efficiency_metrics: LifecycleEfficiencyMetrics::default(),
889            lifecycle_patterns: vec![],
890        };
891
892        assert_eq!(info.lifecycle_events.len(), 2, "Should have 2 events");
893        assert_eq!(
894            info.lifecycle_events[0].event_type,
895            LifecycleEventType::Creation,
896            "First event should be Creation"
897        );
898        assert_eq!(
899            info.lifecycle_events[1].event_type,
900            LifecycleEventType::Drop,
901            "Second event should be Drop"
902        );
903    }
904
905    /// Objective: Verify Clone implementation for ObjectLifecycleInfo
906    /// Invariants: Cloned object should have same values
907    #[test]
908    fn test_object_lifecycle_info_clone() {
909        let original = ObjectLifecycleInfo {
910            object_id: 42,
911            type_name: "Vec<u8>".to_string(),
912            lifecycle_events: vec![],
913            total_lifetime_ns: Some(5000),
914            stage_durations: LifecycleStageDurations {
915                creation_to_first_use_ns: Some(100),
916                active_use_duration_ns: Some(4000),
917                last_use_to_destruction_ns: Some(900),
918                borrowed_duration_ns: 500,
919                idle_duration_ns: 200,
920            },
921            efficiency_metrics: LifecycleEfficiencyMetrics::default(),
922            lifecycle_patterns: vec![],
923        };
924
925        let cloned = original.clone();
926
927        assert_eq!(
928            original.object_id, cloned.object_id,
929            "Object ID should match"
930        );
931        assert_eq!(
932            original.type_name, cloned.type_name,
933            "Type name should match"
934        );
935    }
936}