memscope_rs/analysis_engine/
engine.rs1use crate::analysis_engine::analyzer::{AnalysisResult, Analyzer};
7use crate::snapshot::{MemorySnapshot, SharedSnapshotEngine};
8
9pub struct AnalysisEngine {
20 snapshot_engine: SharedSnapshotEngine,
22 analyzers: Vec<Box<dyn Analyzer>>,
24}
25
26impl AnalysisEngine {
27 pub fn new(snapshot_engine: SharedSnapshotEngine) -> Self {
29 Self {
30 snapshot_engine,
31 analyzers: Vec::new(),
32 }
33 }
34
35 pub fn register_analyzer(&mut self, analyzer: Box<dyn Analyzer>) {
40 self.analyzers.push(analyzer);
41 }
42
43 pub fn analyze(&self) -> Vec<AnalysisResult> {
48 let snapshot = self.snapshot_engine.build_snapshot();
49 self.analyze_snapshot(&snapshot)
50 }
51
52 pub fn analyze_snapshot(&self, snapshot: &MemorySnapshot) -> Vec<AnalysisResult> {
60 self.analyzers
61 .iter()
62 .map(|analyzer| analyzer.analyze(snapshot))
63 .collect()
64 }
65
66 pub fn analyzer_count(&self) -> usize {
68 self.analyzers.len()
69 }
70
71 pub fn has_analyzers(&self) -> bool {
73 !self.analyzers.is_empty()
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::analysis_engine::analyzer::{AnalysisResult, Analyzer, Severity};
81 use crate::event_store::EventStore;
82 use crate::snapshot::SnapshotEngine;
83
84 use std::sync::Arc;
85
86 struct TestAnalyzer {
87 name: String,
88 }
89
90 impl Analyzer for TestAnalyzer {
91 fn name(&self) -> &str {
92 &self.name
93 }
94
95 fn analyze(&self, snapshot: &MemorySnapshot) -> AnalysisResult {
96 AnalysisResult {
97 analyzer_name: self.name.clone(),
98 issue_count: snapshot.active_count(),
99 severity: Severity::Warning,
100 description: format!("Analysis by {}", self.name),
101 findings: vec![],
102 }
103 }
104 }
105
106 #[test]
107 fn test_analysis_engine_creation() {
108 let event_store = Arc::new(EventStore::new());
109 let snapshot_engine = Arc::new(SnapshotEngine::new(event_store));
110 let engine = AnalysisEngine::new(snapshot_engine);
111
112 assert_eq!(engine.analyzer_count(), 0);
113 assert!(!engine.has_analyzers());
114 }
115
116 #[test]
117 fn test_register_analyzer() {
118 let event_store = Arc::new(EventStore::new());
119 let snapshot_engine = Arc::new(SnapshotEngine::new(event_store));
120 let mut engine = AnalysisEngine::new(snapshot_engine);
121
122 engine.register_analyzer(Box::new(TestAnalyzer {
123 name: "test".to_string(),
124 }));
125
126 assert_eq!(engine.analyzer_count(), 1);
127 assert!(engine.has_analyzers());
128 }
129
130 #[test]
131 fn test_analyze() {
132 let event_store = Arc::new(EventStore::new());
133 let snapshot_engine = Arc::new(SnapshotEngine::new(event_store));
134 let mut engine = AnalysisEngine::new(snapshot_engine);
135
136 engine.register_analyzer(Box::new(TestAnalyzer {
137 name: "test".to_string(),
138 }));
139
140 let results = engine.analyze();
141 assert_eq!(results.len(), 1);
142 assert_eq!(results[0].analyzer_name, "test");
143 }
144
145 #[test]
146 fn test_multiple_analyzers() {
147 let event_store = Arc::new(EventStore::new());
148 let snapshot_engine = Arc::new(SnapshotEngine::new(event_store));
149 let mut engine = AnalysisEngine::new(snapshot_engine);
150
151 engine.register_analyzer(Box::new(TestAnalyzer {
152 name: "analyzer1".to_string(),
153 }));
154 engine.register_analyzer(Box::new(TestAnalyzer {
155 name: "analyzer2".to_string(),
156 }));
157
158 assert_eq!(engine.analyzer_count(), 2);
159
160 let results = engine.analyze();
161 assert_eq!(results.len(), 2);
162 }
163}